This is an automated email from the ASF dual-hosted git repository.
zhangduo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/master by this push:
new 671129d HBASE-25252 Move HMaster inner classes out (#2628)
671129d is described below
commit 671129df5666d25c4012cde179c0bd1bae4b164f
Author: Duo Zhang <[email protected]>
AuthorDate: Sat Nov 7 20:05:04 2020 +0800
HBASE-25252 Move HMaster inner classes out (#2628)
Signed-off-by: Viraj Jasani <[email protected]>
Signed-off-by: Wellington Chevreuil <[email protected]>
Signed-off-by: Guanghao Zhang <[email protected]>
---
.../org/apache/hadoop/hbase/master/HMaster.java | 125 +++------------------
.../hbase/master/MasterInitializationMonitor.java | 80 +++++++++++++
.../hadoop/hbase/master/MasterRedirectServlet.java | 81 +++++++++++++
3 files changed, 174 insertions(+), 112 deletions(-)
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
index 8cb399a..573838f 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/HMaster.java
@@ -50,10 +50,7 @@ import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
-import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.hadoop.conf.Configuration;
@@ -95,7 +92,6 @@ import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
import org.apache.hadoop.hbase.exceptions.MasterStoppedException;
import org.apache.hadoop.hbase.executor.ExecutorType;
import org.apache.hadoop.hbase.favored.FavoredNodesManager;
-import org.apache.hadoop.hbase.http.InfoServer;
import org.apache.hadoop.hbase.ipc.CoprocessorRpcUtils;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.ipc.ServerNotRunningYetException;
@@ -238,76 +234,23 @@ import
org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.GetRegionIn
import
org.apache.hadoop.hbase.shaded.protobuf.generated.SnapshotProtos.SnapshotDescription;
/**
- * HMaster is the "master server" for HBase. An HBase cluster has one active
- * master. If many masters are started, all compete. Whichever wins goes on
to
- * run the cluster. All others park themselves in their constructor until
- * master or cluster shutdown or until the active master loses its lease in
- * zookeeper. Thereafter, all running master jostle to take over master role.
- *
- * <p>The Master can be asked shutdown the cluster. See {@link #shutdown()}.
In
- * this case it will tell all regionservers to go down and then wait on them
- * all reporting in that they are down. This master will then shut itself
down.
- *
- * <p>You can also shutdown just this master. Call {@link #stopMaster()}.
- *
+ * HMaster is the "master server" for HBase. An HBase cluster has one active
master. If many masters
+ * are started, all compete. Whichever wins goes on to run the cluster. All
others park themselves
+ * in their constructor until master or cluster shutdown or until the active
master loses its lease
+ * in zookeeper. Thereafter, all running master jostle to take over master
role.
+ * <p/>
+ * The Master can be asked shutdown the cluster. See {@link #shutdown()}. In
this case it will tell
+ * all regionservers to go down and then wait on them all reporting in that
they are down. This
+ * master will then shut itself down.
+ * <p/>
+ * You can also shutdown just this master. Call {@link #stopMaster()}.
* @see org.apache.zookeeper.Watcher
*/
@InterfaceAudience.LimitedPrivate(HBaseInterfaceAudience.TOOLS)
@SuppressWarnings("deprecation")
public class HMaster extends HRegionServer implements MasterServices {
- private static Logger LOG = LoggerFactory.getLogger(HMaster.class);
-
- /**
- * Protection against zombie master. Started once Master accepts active
responsibility and
- * starts taking over responsibilities. Allows a finite time window before
giving up ownership.
- */
- private static class InitializationMonitor extends Thread {
- /** The amount of time in milliseconds to sleep before checking
initialization status. */
- public static final String TIMEOUT_KEY =
"hbase.master.initializationmonitor.timeout";
- public static final long TIMEOUT_DEFAULT =
TimeUnit.MILLISECONDS.convert(15, TimeUnit.MINUTES);
-
- /**
- * When timeout expired and initialization has not complete, call {@link
System#exit(int)} when
- * true, do nothing otherwise.
- */
- public static final String HALT_KEY =
"hbase.master.initializationmonitor.haltontimeout";
- public static final boolean HALT_DEFAULT = false;
- private final HMaster master;
- private final long timeout;
- private final boolean haltOnTimeout;
-
- /** Creates a Thread that monitors the {@link #isInitialized()} state. */
- InitializationMonitor(HMaster master) {
- super("MasterInitializationMonitor");
- this.master = master;
- this.timeout = master.getConfiguration().getLong(TIMEOUT_KEY,
TIMEOUT_DEFAULT);
- this.haltOnTimeout = master.getConfiguration().getBoolean(HALT_KEY,
HALT_DEFAULT);
- this.setDaemon(true);
- }
-
- @Override
- public void run() {
- try {
- while (!master.isStopped() && master.isActiveMaster()) {
- Thread.sleep(timeout);
- if (master.isInitialized()) {
- LOG.debug("Initialization completed within allotted tolerance.
Monitor exiting.");
- } else {
- LOG.error("Master failed to complete initialization after " +
timeout + "ms. Please"
- + " consider submitting a bug report including a thread dump
of this process.");
- if (haltOnTimeout) {
- LOG.error("Zombie Master exiting. Thread dump to stdout");
- Threads.printThreadInfo(System.out, "Zombie HMaster");
- System.exit(-1);
- }
- }
- }
- } catch (InterruptedException ie) {
- LOG.trace("InitMonitor thread interrupted. Existing.");
- }
- }
- }
+ private static final Logger LOG = LoggerFactory.getLogger(HMaster.class);
// MASTER is name of the webapp and the attribute name used stuffing this
//instance into web context.
@@ -464,48 +407,6 @@ public class HMaster extends HRegionServer implements
MasterServices {
// Cached clusterId on stand by masters to serve clusterID requests from
clients.
private final CachedClusterId cachedClusterId;
- public static class RedirectServlet extends HttpServlet {
- private static final long serialVersionUID = 2894774810058302473L;
- private final int regionServerInfoPort;
- private final String regionServerHostname;
-
- /**
- * @param infoServer that we're trying to send all requests to
- * @param hostname may be null. if given, will be used for redirects
instead of host from client.
- */
- public RedirectServlet(InfoServer infoServer, String hostname) {
- regionServerInfoPort = infoServer.getPort();
- regionServerHostname = hostname;
- }
-
- @Override
- public void doGet(HttpServletRequest request,
- HttpServletResponse response) throws ServletException, IOException {
- String redirectHost = regionServerHostname;
- if(redirectHost == null) {
- redirectHost = request.getServerName();
- if(!Addressing.isLocalAddress(InetAddress.getByName(redirectHost))) {
- LOG.warn("Couldn't resolve '" + redirectHost + "' as an address
local to this node and '" +
- MASTER_HOSTNAME_KEY + "' is not set; client will get an HTTP 400
response. If " +
- "your HBase deployment relies on client accessible names that
the region server process " +
- "can't resolve locally, then you should set the previously
mentioned configuration variable " +
- "to an appropriate hostname.");
- // no sending client provided input back to the client, so the goal
host is just in the logs.
- response.sendError(400, "Request was to a host that I can't resolve
for any of the network interfaces on " +
- "this node. If this is due to an intermediary such as an HTTP
load balancer or other proxy, your HBase " +
- "administrator can set '" + MASTER_HOSTNAME_KEY + "' to point to
the correct hostname.");
- return;
- }
- }
- // TODO this scheme should come from looking at the scheme registered in
the infoserver's http server for the
- // host and port we're using, but it's buried way too deep to do that
ATM.
- String redirectUrl = request.getScheme() + "://"
- + redirectHost + ":" + regionServerInfoPort
- + request.getRequestURI();
- response.sendRedirect(redirectUrl);
- }
- }
-
/**
* Initializes the HMaster. The steps are as follows:
* <p>
@@ -678,7 +579,7 @@ public class HMaster extends HRegionServer implements
MasterServices {
final String redirectHostname =
StringUtils.isBlank(useThisHostnameInstead) ? null :
useThisHostnameInstead;
- final RedirectServlet redirect = new RedirectServlet(infoServer,
redirectHostname);
+ final MasterRedirectServlet redirect = new
MasterRedirectServlet(infoServer, redirectHostname);
final WebAppContext context = new WebAppContext(null, "/", null, null,
null, null, WebAppContext.NO_SESSIONS);
context.addServlet(new ServletHolder(redirect), "/*");
context.setServer(masterJettyServer);
@@ -998,7 +899,7 @@ public class HMaster extends HRegionServer implements
MasterServices {
this.activeMaster = true;
// Start the Zombie master detector after setting master as active, see
HBASE-21535
- Thread zombieDetector = new Thread(new InitializationMonitor(this),
+ Thread zombieDetector = new Thread(new MasterInitializationMonitor(this),
"ActiveMasterInitializationMonitor-" + System.currentTimeMillis());
zombieDetector.setDaemon(true);
zombieDetector.start();
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterInitializationMonitor.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterInitializationMonitor.java
new file mode 100644
index 0000000..dcfeeab
--- /dev/null
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterInitializationMonitor.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master;
+
+import java.util.concurrent.TimeUnit;
+import org.apache.hadoop.hbase.util.Threads;
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Protection against zombie master. Started once Master accepts active
responsibility and starts
+ * taking over responsibilities. Allows a finite time window before giving up
ownership.
+ */
[email protected]
+class MasterInitializationMonitor extends Thread {
+
+ private static final Logger LOG =
LoggerFactory.getLogger(MasterInitializationMonitor.class);
+
+ /** The amount of time in milliseconds to sleep before checking
initialization status. */
+ public static final String TIMEOUT_KEY =
"hbase.master.initializationmonitor.timeout";
+ public static final long TIMEOUT_DEFAULT = TimeUnit.MILLISECONDS.convert(15,
TimeUnit.MINUTES);
+
+ /**
+ * When timeout expired and initialization has not complete, call {@link
System#exit(int)} when
+ * true, do nothing otherwise.
+ */
+ public static final String HALT_KEY =
"hbase.master.initializationmonitor.haltontimeout";
+ public static final boolean HALT_DEFAULT = false;
+
+ private final HMaster master;
+ private final long timeout;
+ private final boolean haltOnTimeout;
+
+ /** Creates a Thread that monitors the {@link #isInitialized()} state. */
+ MasterInitializationMonitor(HMaster master) {
+ super("MasterInitializationMonitor");
+ this.master = master;
+ this.timeout = master.getConfiguration().getLong(TIMEOUT_KEY,
TIMEOUT_DEFAULT);
+ this.haltOnTimeout = master.getConfiguration().getBoolean(HALT_KEY,
HALT_DEFAULT);
+ this.setDaemon(true);
+ }
+
+ @Override
+ public void run() {
+ try {
+ while (!master.isStopped() && master.isActiveMaster()) {
+ Thread.sleep(timeout);
+ if (master.isInitialized()) {
+ LOG.debug("Initialization completed within allotted tolerance.
Monitor exiting.");
+ } else {
+ LOG.error("Master failed to complete initialization after " +
timeout + "ms. Please" +
+ " consider submitting a bug report including a thread dump of this
process.");
+ if (haltOnTimeout) {
+ LOG.error("Zombie Master exiting. Thread dump to stdout");
+ Threads.printThreadInfo(System.out, "Zombie HMaster");
+ System.exit(-1);
+ }
+ }
+ }
+ } catch (InterruptedException ie) {
+ LOG.trace("InitMonitor thread interrupted. Existing.");
+ }
+ }
+}
\ No newline at end of file
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRedirectServlet.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRedirectServlet.java
new file mode 100644
index 0000000..bda2934
--- /dev/null
+++
b/hbase-server/src/main/java/org/apache/hadoop/hbase/master/MasterRedirectServlet.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.master;
+
+import static org.apache.hadoop.hbase.util.DNS.MASTER_HOSTNAME_KEY;
+
+import java.io.IOException;
+import java.net.InetAddress;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import org.apache.hadoop.hbase.http.InfoServer;
+import org.apache.hadoop.hbase.util.Addressing;
+import org.apache.yetus.audience.InterfaceAudience;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
[email protected]
+class MasterRedirectServlet extends HttpServlet {
+
+ private static final long serialVersionUID = 2894774810058302473L;
+
+ private static final Logger LOG =
LoggerFactory.getLogger(MasterRedirectServlet.class);
+
+ private final int regionServerInfoPort;
+ private final String regionServerHostname;
+
+ /**
+ * @param infoServer that we're trying to send all requests to
+ * @param hostname may be null. if given, will be used for redirects instead
of host from client.
+ */
+ public MasterRedirectServlet(InfoServer infoServer, String hostname) {
+ regionServerInfoPort = infoServer.getPort();
+ regionServerHostname = hostname;
+ }
+
+ @Override
+ public void doGet(HttpServletRequest request, HttpServletResponse response)
+ throws ServletException, IOException {
+ String redirectHost = regionServerHostname;
+ if (redirectHost == null) {
+ redirectHost = request.getServerName();
+ if (!Addressing.isLocalAddress(InetAddress.getByName(redirectHost))) {
+ LOG.warn("Couldn't resolve '" + redirectHost + "' as an address local
to this node and '" +
+ MASTER_HOSTNAME_KEY + "' is not set; client will get an HTTP 400
response. If " +
+ "your HBase deployment relies on client accessible names that the
region server " +
+ "process can't resolve locally, then you should set the previously
mentioned " +
+ "configuration variable to an appropriate hostname.");
+ // no sending client provided input back to the client, so the goal
host is just in the
+ // logs.
+ response.sendError(400,
+ "Request was to a host that I can't resolve for any of the network
interfaces on " +
+ "this node. If this is due to an intermediary such as an HTTP load
balancer or " +
+ "other proxy, your HBase administrator can set '" +
MASTER_HOSTNAME_KEY +
+ "' to point to the correct hostname.");
+ return;
+ }
+ }
+ // TODO: this scheme should come from looking at the scheme registered in
the infoserver's http
+ // server for the host and port we're using, but it's buried way too deep
to do that ATM.
+ String redirectUrl = request.getScheme() + "://" + redirectHost + ":" +
regionServerInfoPort +
+ request.getRequestURI();
+ response.sendRedirect(redirectUrl);
+ }
+}
\ No newline at end of file