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