HBASE-21843 RegionGroupingProvider breaks the meta wal file name pattern which may...
[hbase.git] / hbase-server / src / main / java / org / apache / hadoop / hbase / master / HMasterCommandLine.java
blob489894e8c6668727239271e7965d18223a90468b
1 /**
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 package org.apache.hadoop.hbase.master;
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.List;
25 import org.apache.hadoop.conf.Configuration;
26 import org.apache.hadoop.hbase.HConstants;
27 import org.apache.hadoop.hbase.LocalHBaseCluster;
28 import org.apache.hadoop.hbase.MasterNotRunningException;
29 import org.apache.hadoop.hbase.ZNodeClearer;
30 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
31 import org.apache.hadoop.hbase.trace.TraceUtil;
32 import org.apache.yetus.audience.InterfaceAudience;
33 import org.apache.hadoop.hbase.client.Admin;
34 import org.apache.hadoop.hbase.client.Connection;
35 import org.apache.hadoop.hbase.client.ConnectionFactory;
36 import org.apache.hadoop.hbase.regionserver.HRegionServer;
37 import org.apache.hadoop.hbase.util.JVMClusterUtil;
38 import org.apache.hadoop.hbase.util.ServerCommandLine;
39 import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
40 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
41 import org.apache.hadoop.metrics2.lib.DefaultMetricsSystem;
42 import org.apache.zookeeper.KeeperException;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 import org.apache.hbase.thirdparty.org.apache.commons.cli.CommandLine;
47 import org.apache.hbase.thirdparty.org.apache.commons.cli.GnuParser;
48 import org.apache.hbase.thirdparty.org.apache.commons.cli.Options;
49 import org.apache.hbase.thirdparty.org.apache.commons.cli.ParseException;
51 @InterfaceAudience.Private
52 public class HMasterCommandLine extends ServerCommandLine {
53 private static final Logger LOG = LoggerFactory.getLogger(HMasterCommandLine.class);
55 private static final String USAGE =
56 "Usage: Master [opts] start|stop|clear\n" +
57 " start Start Master. If local mode, start Master and RegionServer in same JVM\n" +
58 " stop Start cluster shutdown; Master signals RegionServer shutdown\n" +
59 " clear Delete the master znode in ZooKeeper after a master crashes\n "+
60 " where [opts] are:\n" +
61 " --minRegionServers=<servers> Minimum RegionServers needed to host user tables.\n" +
62 " --localRegionServers=<servers> " +
63 "RegionServers to start in master process when in standalone mode.\n" +
64 " --masters=<servers> Masters to start in this process.\n" +
65 " --backup Master should start in backup mode";
67 private final Class<? extends HMaster> masterClass;
69 public HMasterCommandLine(Class<? extends HMaster> masterClass) {
70 this.masterClass = masterClass;
73 @Override
74 protected String getUsage() {
75 return USAGE;
78 @Override
79 public int run(String args[]) throws Exception {
80 Options opt = new Options();
81 opt.addOption("localRegionServers", true,
82 "RegionServers to start in master process when running standalone");
83 opt.addOption("masters", true, "Masters to start in this process");
84 opt.addOption("minRegionServers", true, "Minimum RegionServers needed to host user tables");
85 opt.addOption("backup", false, "Do not try to become HMaster until the primary fails");
87 CommandLine cmd;
88 try {
89 cmd = new GnuParser().parse(opt, args);
90 } catch (ParseException e) {
91 LOG.error("Could not parse: ", e);
92 usage(null);
93 return 1;
97 if (cmd.hasOption("minRegionServers")) {
98 String val = cmd.getOptionValue("minRegionServers");
99 getConf().setInt("hbase.regions.server.count.min",
100 Integer.parseInt(val));
101 LOG.debug("minRegionServers set to " + val);
104 // minRegionServers used to be minServers. Support it too.
105 if (cmd.hasOption("minServers")) {
106 String val = cmd.getOptionValue("minServers");
107 getConf().setInt("hbase.regions.server.count.min", Integer.parseInt(val));
108 LOG.debug("minServers set to " + val);
111 // check if we are the backup master - override the conf if so
112 if (cmd.hasOption("backup")) {
113 getConf().setBoolean(HConstants.MASTER_TYPE_BACKUP, true);
116 // How many regionservers to startup in this process (we run regionservers in same process as
117 // master when we are in local/standalone mode. Useful testing)
118 if (cmd.hasOption("localRegionServers")) {
119 String val = cmd.getOptionValue("localRegionServers");
120 getConf().setInt("hbase.regionservers", Integer.parseInt(val));
121 LOG.debug("localRegionServers set to " + val);
123 // How many masters to startup inside this process; useful testing
124 if (cmd.hasOption("masters")) {
125 String val = cmd.getOptionValue("masters");
126 getConf().setInt("hbase.masters", Integer.parseInt(val));
127 LOG.debug("masters set to " + val);
130 @SuppressWarnings("unchecked")
131 List<String> remainingArgs = cmd.getArgList();
132 if (remainingArgs.size() != 1) {
133 usage(null);
134 return 1;
137 String command = remainingArgs.get(0);
139 if ("start".equals(command)) {
140 return startMaster();
141 } else if ("stop".equals(command)) {
142 return stopMaster();
143 } else if ("clear".equals(command)) {
144 return (ZNodeClearer.clear(getConf()) ? 0 : 1);
145 } else {
146 usage("Invalid command: " + command);
147 return 1;
151 private int startMaster() {
152 Configuration conf = getConf();
153 TraceUtil.initTracer(conf);
155 try {
156 // If 'local', defer to LocalHBaseCluster instance. Starts master
157 // and regionserver both in the one JVM.
158 if (LocalHBaseCluster.isLocal(conf)) {
159 DefaultMetricsSystem.setMiniClusterMode(true);
160 final MiniZooKeeperCluster zooKeeperCluster = new MiniZooKeeperCluster(conf);
161 File zkDataPath = new File(conf.get(HConstants.ZOOKEEPER_DATA_DIR));
163 // find out the default client port
164 int zkClientPort = 0;
166 // If the zookeeper client port is specified in server quorum, use it.
167 String zkserver = conf.get(HConstants.ZOOKEEPER_QUORUM);
168 if (zkserver != null) {
169 String[] zkservers = zkserver.split(",");
171 if (zkservers.length > 1) {
172 // In local mode deployment, we have the master + a region server and zookeeper server
173 // started in the same process. Therefore, we only support one zookeeper server.
174 String errorMsg = "Could not start ZK with " + zkservers.length +
175 " ZK servers in local mode deployment. Aborting as clients (e.g. shell) will not "
176 + "be able to find this ZK quorum.";
177 System.err.println(errorMsg);
178 throw new IOException(errorMsg);
181 String[] parts = zkservers[0].split(":");
183 if (parts.length == 2) {
184 // the second part is the client port
185 zkClientPort = Integer.parseInt(parts [1]);
188 // If the client port could not be find in server quorum conf, try another conf
189 if (zkClientPort == 0) {
190 zkClientPort = conf.getInt(HConstants.ZOOKEEPER_CLIENT_PORT, 0);
191 // The client port has to be set by now; if not, throw exception.
192 if (zkClientPort == 0) {
193 throw new IOException("No config value for " + HConstants.ZOOKEEPER_CLIENT_PORT);
196 zooKeeperCluster.setDefaultClientPort(zkClientPort);
197 // set the ZK tick time if specified
198 int zkTickTime = conf.getInt(HConstants.ZOOKEEPER_TICK_TIME, 0);
199 if (zkTickTime > 0) {
200 zooKeeperCluster.setTickTime(zkTickTime);
203 // login the zookeeper server principal (if using security)
204 ZKUtil.loginServer(conf, HConstants.ZK_SERVER_KEYTAB_FILE,
205 HConstants.ZK_SERVER_KERBEROS_PRINCIPAL, null);
206 int localZKClusterSessionTimeout =
207 conf.getInt(HConstants.ZK_SESSION_TIMEOUT + ".localHBaseCluster", 10*1000);
208 conf.setInt(HConstants.ZK_SESSION_TIMEOUT, localZKClusterSessionTimeout);
209 LOG.info("Starting a zookeeper cluster");
210 int clientPort = zooKeeperCluster.startup(zkDataPath);
211 if (clientPort != zkClientPort) {
212 String errorMsg = "Could not start ZK at requested port of " +
213 zkClientPort + ". ZK was started at port: " + clientPort +
214 ". Aborting as clients (e.g. shell) will not be able to find " +
215 "this ZK quorum.";
216 System.err.println(errorMsg);
217 throw new IOException(errorMsg);
219 conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, Integer.toString(clientPort));
221 // Need to have the zk cluster shutdown when master is shutdown.
222 // Run a subclass that does the zk cluster shutdown on its way out.
223 int mastersCount = conf.getInt("hbase.masters", 1);
224 int regionServersCount = conf.getInt("hbase.regionservers", 1);
225 // Set start timeout to 5 minutes for cmd line start operations
226 conf.setIfUnset("hbase.master.start.timeout.localHBaseCluster", "300000");
227 LOG.info("Starting up instance of localHBaseCluster; master=" + mastersCount +
228 ", regionserversCount=" + regionServersCount);
229 LocalHBaseCluster cluster = new LocalHBaseCluster(conf, mastersCount, regionServersCount,
230 LocalHMaster.class, HRegionServer.class);
231 ((LocalHMaster)cluster.getMaster(0)).setZKCluster(zooKeeperCluster);
232 cluster.startup();
233 waitOnMasterThreads(cluster);
234 } else {
235 logProcessInfo(getConf());
236 HMaster master = HMaster.constructMaster(masterClass, conf);
237 if (master.isStopped()) {
238 LOG.info("Won't bring the Master up as a shutdown is requested");
239 return 1;
241 master.start();
242 master.join();
243 if(master.isAborted())
244 throw new RuntimeException("HMaster Aborted");
246 } catch (Throwable t) {
247 LOG.error("Master exiting", t);
248 return 1;
250 return 0;
253 @SuppressWarnings("resource")
254 private int stopMaster() {
255 Configuration conf = getConf();
256 // Don't try more than once
257 conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 0);
258 try (Connection connection = ConnectionFactory.createConnection(conf)) {
259 try (Admin admin = connection.getAdmin()) {
260 admin.shutdown();
261 } catch (Throwable t) {
262 LOG.error("Failed to stop master", t);
263 return 1;
265 } catch (MasterNotRunningException e) {
266 LOG.error("Master not running");
267 return 1;
268 } catch (ZooKeeperConnectionException e) {
269 LOG.error("ZooKeeper not available");
270 return 1;
271 } catch (IOException e) {
272 LOG.error("Got IOException: " +e.getMessage(), e);
273 return 1;
275 return 0;
278 private void waitOnMasterThreads(LocalHBaseCluster cluster) throws InterruptedException{
279 List<JVMClusterUtil.MasterThread> masters = cluster.getMasters();
280 List<JVMClusterUtil.RegionServerThread> regionservers = cluster.getRegionServers();
282 if (masters != null) {
283 for (JVMClusterUtil.MasterThread t : masters) {
284 t.join();
285 if(t.getMaster().isAborted()) {
286 closeAllRegionServerThreads(regionservers);
287 throw new RuntimeException("HMaster Aborted");
293 private static void closeAllRegionServerThreads(
294 List<JVMClusterUtil.RegionServerThread> regionservers) {
295 for(JVMClusterUtil.RegionServerThread t : regionservers){
296 t.getRegionServer().stop("HMaster Aborted; Bringing down regions servers");
301 * Version of master that will shutdown the passed zk cluster on its way out.
303 public static class LocalHMaster extends HMaster {
304 private MiniZooKeeperCluster zkcluster = null;
306 public LocalHMaster(Configuration conf)
307 throws IOException, KeeperException, InterruptedException {
308 super(conf);
311 @Override
312 public void run() {
313 super.run();
314 if (this.zkcluster != null) {
315 try {
316 this.zkcluster.shutdown();
317 } catch (IOException e) {
318 LOG.error("Failed to shutdown MiniZooKeeperCluster", e);
323 void setZKCluster(final MiniZooKeeperCluster zkcluster) {
324 this.zkcluster = zkcluster;