1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master;
20
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.List;
24
25 import org.apache.commons.cli.CommandLine;
26 import org.apache.commons.cli.GnuParser;
27 import org.apache.commons.cli.Options;
28 import org.apache.commons.cli.ParseException;
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.hadoop.classification.InterfaceAudience;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.MasterNotRunningException;
34 import org.apache.hadoop.hbase.ZNodeClearer;
35 import org.apache.hadoop.hbase.HConstants;
36 import org.apache.hadoop.hbase.LocalHBaseCluster;
37 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
38 import org.apache.hadoop.hbase.client.HBaseAdmin;
39 import org.apache.hadoop.hbase.regionserver.HRegionServer;
40 import org.apache.hadoop.hbase.util.JVMClusterUtil;
41 import org.apache.hadoop.hbase.util.ServerCommandLine;
42 import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
43 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
44 import org.apache.zookeeper.KeeperException;
45
46 @InterfaceAudience.Private
47 public class HMasterCommandLine extends ServerCommandLine {
48 private static final Log LOG = LogFactory.getLog(HMasterCommandLine.class);
49
50 private static final String USAGE =
51 "Usage: Master [opts] start|stop|clear\n" +
52 " start Start Master. If local mode, start Master and RegionServer in same JVM\n" +
53 " stop Start cluster shutdown; Master signals RegionServer shutdown\n" +
54 " clear Delete the master znode in ZooKeeper after a master crashes\n "+
55 " where [opts] are:\n" +
56 " --minRegionServers=<servers> Minimum RegionServers needed to host user tables.\n" +
57 " --localRegionServers=<servers> " +
58 "RegionServers to start in master process when in standalone mode.\n" +
59 " --masters=<servers> Masters to start in this process.\n" +
60 " --backup Master should start in backup mode";
61
62 private final Class<? extends HMaster> masterClass;
63
64 public HMasterCommandLine(Class<? extends HMaster> masterClass) {
65 this.masterClass = masterClass;
66 }
67
68 protected String getUsage() {
69 return USAGE;
70 }
71
72
73 public int run(String args[]) throws Exception {
74 Options opt = new Options();
75 opt.addOption("localRegionServers", true,
76 "RegionServers to start in master process when running standalone");
77 opt.addOption("masters", true, "Masters to start in this process");
78 opt.addOption("minRegionServers", true, "Minimum RegionServers needed to host user tables");
79 opt.addOption("backup", false, "Do not try to become HMaster until the primary fails");
80
81 CommandLine cmd;
82 try {
83 cmd = new GnuParser().parse(opt, args);
84 } catch (ParseException e) {
85 LOG.error("Could not parse: ", e);
86 usage(null);
87 return 1;
88 }
89
90
91 if (cmd.hasOption("minRegionServers")) {
92 String val = cmd.getOptionValue("minRegionServers");
93 getConf().setInt("hbase.regions.server.count.min",
94 Integer.valueOf(val));
95 LOG.debug("minRegionServers set to " + val);
96 }
97
98
99 if (cmd.hasOption("minServers")) {
100 String val = cmd.getOptionValue("minServers");
101 getConf().setInt("hbase.regions.server.count.min",
102 Integer.valueOf(val));
103 LOG.debug("minServers set to " + val);
104 }
105
106
107 if (cmd.hasOption("backup")) {
108 getConf().setBoolean(HConstants.MASTER_TYPE_BACKUP, true);
109 }
110
111
112
113 if (cmd.hasOption("localRegionServers")) {
114 String val = cmd.getOptionValue("localRegionServers");
115 getConf().setInt("hbase.regionservers", Integer.valueOf(val));
116 LOG.debug("localRegionServers set to " + val);
117 }
118
119 if (cmd.hasOption("masters")) {
120 String val = cmd.getOptionValue("masters");
121 getConf().setInt("hbase.masters", Integer.valueOf(val));
122 LOG.debug("masters set to " + val);
123 }
124
125 List<String> remainingArgs = cmd.getArgList();
126 if (remainingArgs.size() != 1) {
127 usage(null);
128 return 1;
129 }
130
131 String command = remainingArgs.get(0);
132
133 if ("start".equals(command)) {
134 return startMaster();
135 } else if ("stop".equals(command)) {
136 return stopMaster();
137 } else if ("clear".equals(command)) {
138 return (ZNodeClearer.clear(getConf()) ? 0 : 1);
139 } else {
140 usage("Invalid command: " + command);
141 return 1;
142 }
143 }
144
145 private int startMaster() {
146 Configuration conf = getConf();
147 try {
148
149
150 if (LocalHBaseCluster.isLocal(conf)) {
151 final MiniZooKeeperCluster zooKeeperCluster = new MiniZooKeeperCluster(conf);
152 File zkDataPath = new File(conf.get(HConstants.ZOOKEEPER_DATA_DIR));
153 int zkClientPort = conf.getInt(HConstants.ZOOKEEPER_CLIENT_PORT, 0);
154 if (zkClientPort == 0) {
155 throw new IOException("No config value for "
156 + HConstants.ZOOKEEPER_CLIENT_PORT);
157 }
158 zooKeeperCluster.setDefaultClientPort(zkClientPort);
159
160
161 ZKUtil.loginServer(conf, "hbase.zookeeper.server.keytab.file",
162 "hbase.zookeeper.server.kerberos.principal", null);
163
164 int clientPort = zooKeeperCluster.startup(zkDataPath);
165 if (clientPort != zkClientPort) {
166 String errorMsg = "Could not start ZK at requested port of " +
167 zkClientPort + ". ZK was started at port: " + clientPort +
168 ". Aborting as clients (e.g. shell) will not be able to find " +
169 "this ZK quorum.";
170 System.err.println(errorMsg);
171 throw new IOException(errorMsg);
172 }
173 conf.set(HConstants.ZOOKEEPER_CLIENT_PORT,
174 Integer.toString(clientPort));
175
176
177 LocalHBaseCluster cluster = new LocalHBaseCluster(conf, conf.getInt("hbase.masters", 1),
178 conf.getInt("hbase.regionservers", 1), LocalHMaster.class, HRegionServer.class);
179 ((LocalHMaster)cluster.getMaster(0)).setZKCluster(zooKeeperCluster);
180 cluster.startup();
181 waitOnMasterThreads(cluster);
182 } else {
183 logProcessInfo(getConf());
184 HMaster master = HMaster.constructMaster(masterClass, conf);
185 if (master.isStopped()) {
186 LOG.info("Won't bring the Master up as a shutdown is requested");
187 return 1;
188 }
189 master.start();
190 master.join();
191 if(master.isAborted())
192 throw new RuntimeException("HMaster Aborted");
193 }
194 } catch (Throwable t) {
195 LOG.error("Master exiting", t);
196 return 1;
197 }
198 return 0;
199 }
200
201 private int stopMaster() {
202 HBaseAdmin adm = null;
203 try {
204 Configuration conf = getConf();
205
206 conf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 1);
207 adm = new HBaseAdmin(getConf());
208 } catch (MasterNotRunningException e) {
209 LOG.error("Master not running");
210 return 1;
211 } catch (ZooKeeperConnectionException e) {
212 LOG.error("ZooKeeper not available");
213 return 1;
214 } catch (IOException e) {
215 LOG.error("Got IOException: " +e.getMessage(), e);
216 return 1;
217 }
218 try {
219 adm.shutdown();
220 } catch (Throwable t) {
221 LOG.error("Failed to stop master", t);
222 return 1;
223 }
224 return 0;
225 }
226
227 private void waitOnMasterThreads(LocalHBaseCluster cluster) throws InterruptedException{
228 List<JVMClusterUtil.MasterThread> masters = cluster.getMasters();
229 List<JVMClusterUtil.RegionServerThread> regionservers = cluster.getRegionServers();
230
231 if (masters != null) {
232 for (JVMClusterUtil.MasterThread t : masters) {
233 t.join();
234 if(t.getMaster().isAborted()) {
235 closeAllRegionServerThreads(regionservers);
236 throw new RuntimeException("HMaster Aborted");
237 }
238 }
239 }
240 }
241
242 private static void closeAllRegionServerThreads(List<JVMClusterUtil.RegionServerThread> regionservers) {
243 for(JVMClusterUtil.RegionServerThread t : regionservers){
244 t.getRegionServer().stop("HMaster Aborted; Bringing down regions servers");
245 }
246 }
247
248
249
250
251 public static class LocalHMaster extends HMaster {
252 private MiniZooKeeperCluster zkcluster = null;
253
254 public LocalHMaster(Configuration conf)
255 throws IOException, KeeperException, InterruptedException {
256 super(conf);
257 }
258
259 @Override
260 public void run() {
261 super.run();
262 if (this.zkcluster != null) {
263 try {
264 this.zkcluster.shutdown();
265 } catch (IOException e) {
266 e.printStackTrace();
267 }
268 }
269 }
270
271 void setZKCluster(final MiniZooKeeperCluster zkcluster) {
272 this.zkcluster = zkcluster;
273 }
274 }
275 }