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.ServerCommandLine;
40 import org.apache.hadoop.hbase.zookeeper.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.setClientPort(zkClientPort);
125 int clientPort = zooKeeperCluster.startup(zkDataPath);
126 if (clientPort != zkClientPort) {
127 String errorMsg = "Couldnt start ZK at requested address of " +
128 zkClientPort + ", instead got: " + clientPort + ". Aborting. Why? " +
129 "Because clients (eg shell) wont be able to find this ZK quorum";
130 System.err.println(errorMsg);
131 throw new IOException(errorMsg);
132 }
133 conf.set("hbase.zookeeper.property.clientPort",
134 Integer.toString(clientPort));
135
136
137 LocalHBaseCluster cluster = new LocalHBaseCluster(conf, 1, 1,
138 LocalHMaster.class, HRegionServer.class);
139 ((LocalHMaster)cluster.getMaster(0)).setZKCluster(zooKeeperCluster);
140 cluster.startup();
141 } else {
142 HMaster master = HMaster.constructMaster(masterClass, conf);
143 if (master.isStopped()) {
144 LOG.info("Won't bring the Master up as a shutdown is requested");
145 return -1;
146 }
147 master.start();
148 master.join();
149 }
150 } catch (Throwable t) {
151 LOG.error("Failed to start master", t);
152 return -1;
153 }
154 return 0;
155 }
156
157 private int stopMaster() {
158 HBaseAdmin adm = null;
159 try {
160 Configuration conf = getConf();
161
162 conf.setInt("hbase.client.retries.number", 1);
163 adm = new HBaseAdmin(getConf());
164 } catch (MasterNotRunningException e) {
165 LOG.error("Master not running");
166 return -1;
167 } catch (ZooKeeperConnectionException e) {
168 LOG.error("ZooKeeper not available");
169 return -1;
170 }
171 try {
172 adm.shutdown();
173 } catch (Throwable t) {
174 LOG.error("Failed to stop master", t);
175 return -1;
176 }
177 return 0;
178 }
179
180
181
182
183 public static class LocalHMaster extends HMaster {
184 private MiniZooKeeperCluster zkcluster = null;
185
186 public LocalHMaster(Configuration conf)
187 throws IOException, KeeperException, InterruptedException {
188 super(conf);
189 }
190
191 @Override
192 public void run() {
193 super.run();
194 if (this.zkcluster != null) {
195 try {
196 this.zkcluster.shutdown();
197 } catch (IOException e) {
198 e.printStackTrace();
199 }
200 }
201 }
202
203 void setZKCluster(final MiniZooKeeperCluster zkcluster) {
204 this.zkcluster = zkcluster;
205 }
206 }
207 }