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.IOException;
23 import java.io.File;
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.HBaseConfiguration;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.LocalHBaseCluster;
36 import org.apache.hadoop.hbase.MasterNotRunningException;
37 import org.apache.hadoop.hbase.client.HBaseAdmin;
38 import org.apache.hadoop.hbase.regionserver.HRegionServer;
39 import org.apache.hadoop.hbase.util.ServerCommandLine;
40 import org.apache.hadoop.hbase.MiniZooKeeperCluster;
41 import org.apache.zookeeper.KeeperException;
42
43 public class HMasterCommandLine extends ServerCommandLine {
44 private static final Log LOG = LogFactory.getLog(HMasterCommandLine.class);
45
46 private static final String USAGE =
47 "Usage: Master [opts] start|stop\n" +
48 " start Start Master. If local mode, start Master and RegionServer in same JVM\n" +
49 " stop Start cluster shutdown; Master signals RegionServer shutdown\n" +
50 " where [opts] are:\n" +
51 " --minServers=<servers> Minimum RegionServers needed to host user tables.\n" +
52 " --backup Master should start in backup mode";
53
54 private final Class<? extends HMaster> masterClass;
55
56 public HMasterCommandLine(Class<? extends HMaster> masterClass) {
57 this.masterClass = masterClass;
58 }
59
60 protected String getUsage() {
61 return USAGE;
62 }
63
64
65 public int run(String args[]) throws Exception {
66 Options opt = new Options();
67 opt.addOption("minServers", true, "Minimum RegionServers needed to host user tables");
68 opt.addOption("backup", false, "Do not try to become HMaster until the primary fails");
69
70
71 CommandLine cmd;
72 try {
73 cmd = new GnuParser().parse(opt, args);
74 } catch (ParseException e) {
75 LOG.error("Could not parse: ", e);
76 usage(null);
77 return -1;
78 }
79
80
81 if (cmd.hasOption("minServers")) {
82 String val = cmd.getOptionValue("minServers");
83 getConf().setInt("hbase.regions.server.count.min",
84 Integer.valueOf(val));
85 LOG.debug("minServers set to " + val);
86 }
87
88
89 if (cmd.hasOption("backup")) {
90 getConf().setBoolean(HConstants.MASTER_TYPE_BACKUP, true);
91 }
92
93 List<String> remainingArgs = cmd.getArgList();
94 if (remainingArgs.size() != 1) {
95 usage(null);
96 return -1;
97 }
98
99 String command = remainingArgs.get(0);
100
101 if ("start".equals(command)) {
102 return startMaster();
103 } else if ("stop".equals(command)) {
104 return stopMaster();
105 } else {
106 usage("Invalid command: " + command);
107 return -1;
108 }
109 }
110
111 private int startMaster() {
112 Configuration conf = getConf();
113 try {
114
115
116 if (LocalHBaseCluster.isLocal(conf)) {
117 final MiniZooKeeperCluster zooKeeperCluster =
118 new MiniZooKeeperCluster();
119 File zkDataPath = new File(conf.get("hbase.zookeeper.property.dataDir"));
120 int zkClientPort = conf.getInt("hbase.zookeeper.property.clientPort", 0);
121 if (zkClientPort == 0) {
122 throw new IOException("No config value for hbase.zookeeper.property.clientPort");
123 }
124 zooKeeperCluster.setTickTime(conf.getInt("hbase.zookeeper.property.tickTime", 3000));
125 zooKeeperCluster.setClientPort(zkClientPort);
126 int clientPort = zooKeeperCluster.startup(zkDataPath);
127 if (clientPort != zkClientPort) {
128 String errorMsg = "Couldnt start ZK at requested address of " +
129 zkClientPort + ", instead got: " + clientPort + ". Aborting. Why? " +
130 "Because clients (eg shell) wont be able to find this ZK quorum";
131 System.err.println(errorMsg);
132 throw new IOException(errorMsg);
133 }
134 conf.set("hbase.zookeeper.property.clientPort",
135 Integer.toString(clientPort));
136
137
138 LocalHBaseCluster cluster = new LocalHBaseCluster(conf, 1,
139 LocalHMaster.class, HRegionServer.class);
140 ((LocalHMaster)cluster.getMaster()).setZKCluster(zooKeeperCluster);
141 cluster.startup();
142 } else {
143 HMaster master = HMaster.constructMaster(masterClass, conf);
144 if (master.getShutdownRequested().get()) {
145 LOG.info("Won't bring the Master up as a shutdown is requested");
146 return -1;
147 }
148 master.start();
149 master.join();
150 }
151 } catch (Throwable t) {
152 LOG.error("Failed to start master", t);
153 return -1;
154 }
155 return 0;
156 }
157
158 private int stopMaster() {
159 HBaseAdmin adm = null;
160 try {
161 adm = new HBaseAdmin(getConf());
162 } catch (MasterNotRunningException e) {
163 LOG.error("Master not running");
164 return -1;
165 }
166 try {
167 adm.shutdown();
168 } catch (Throwable t) {
169 LOG.error("Failed to stop master", t);
170 return -1;
171 }
172 return 0;
173 }
174
175
176
177
178 static class LocalHMaster extends HMaster {
179 private MiniZooKeeperCluster zkcluster = null;
180
181 public LocalHMaster(Configuration conf)
182 throws IOException, KeeperException, InterruptedException {
183 super(conf);
184 }
185
186 @Override
187 public void run() {
188 super.run();
189 if (this.zkcluster != null) {
190 try {
191 this.zkcluster.shutdown();
192 } catch (IOException e) {
193 e.printStackTrace();
194 }
195 }
196 }
197
198 void setZKCluster(final MiniZooKeeperCluster zkcluster) {
199 this.zkcluster = zkcluster;
200 }
201 }
202 }