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.zookeeper.KeeperException;
43
44 public class HMasterCommandLine extends ServerCommandLine {
45 private static final Log LOG = LogFactory.getLog(HMasterCommandLine.class);
46
47 private static final String USAGE =
48 "Usage: Master [opts] start|stop\n" +
49 " start Start Master. If local mode, start Master and RegionServer in same JVM\n" +
50 " stop Start cluster shutdown; Master signals RegionServer shutdown\n" +
51 " where [opts] are:\n" +
52 " --minServers=<servers> Minimum RegionServers needed to host user tables.\n" +
53 " --backup Master should start in backup mode";
54
55 private final Class<? extends HMaster> masterClass;
56
57 public HMasterCommandLine(Class<? extends HMaster> masterClass) {
58 this.masterClass = masterClass;
59 }
60
61 protected String getUsage() {
62 return USAGE;
63 }
64
65
66 public int run(String args[]) throws Exception {
67 Options opt = new Options();
68 opt.addOption("minServers", true, "Minimum RegionServers needed to host user tables");
69 opt.addOption("backup", false, "Do not try to become HMaster until the primary fails");
70
71
72 CommandLine cmd;
73 try {
74 cmd = new GnuParser().parse(opt, args);
75 } catch (ParseException e) {
76 LOG.error("Could not parse: ", e);
77 usage(null);
78 return -1;
79 }
80
81
82 if (cmd.hasOption("minServers")) {
83 String val = cmd.getOptionValue("minServers");
84 getConf().setInt("hbase.regions.server.count.min",
85 Integer.valueOf(val));
86 LOG.debug("minServers set to " + val);
87 }
88
89
90 if (cmd.hasOption("backup")) {
91 getConf().setBoolean(HConstants.MASTER_TYPE_BACKUP, true);
92 }
93
94 List<String> remainingArgs = cmd.getArgList();
95 if (remainingArgs.size() != 1) {
96 usage(null);
97 return -1;
98 }
99
100 String command = remainingArgs.get(0);
101
102 if ("start".equals(command)) {
103 return startMaster();
104 } else if ("stop".equals(command)) {
105 return stopMaster();
106 } else {
107 usage("Invalid command: " + command);
108 return -1;
109 }
110 }
111
112 private int startMaster() {
113 Configuration conf = getConf();
114 try {
115
116
117 if (LocalHBaseCluster.isLocal(conf)) {
118 final MiniZooKeeperCluster zooKeeperCluster =
119 new MiniZooKeeperCluster();
120 File zkDataPath = new File(conf.get("hbase.zookeeper.property.dataDir"));
121 int zkClientPort = conf.getInt("hbase.zookeeper.property.clientPort", 0);
122 if (zkClientPort == 0) {
123 throw new IOException("No config value for hbase.zookeeper.property.clientPort");
124 }
125 zooKeeperCluster.setDefaultClientPort(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, 1,
139 LocalHMaster.class, HRegionServer.class);
140 ((LocalHMaster)cluster.getMaster(0)).setZKCluster(zooKeeperCluster);
141 cluster.startup();
142 waitOnMasterThreads(cluster);
143 } else {
144 HMaster master = HMaster.constructMaster(masterClass, conf);
145 if (master.isStopped()) {
146 LOG.info("Won't bring the Master up as a shutdown is requested");
147 return -1;
148 }
149 master.start();
150 master.join();
151 if(master.isAborted())
152 throw new RuntimeException("HMaster Aborted");
153 }
154 } catch (Throwable t) {
155 LOG.error("Failed to start master", t);
156 return -1;
157 }
158 return 0;
159 }
160
161 private int stopMaster() {
162 HBaseAdmin adm = null;
163 try {
164 Configuration conf = getConf();
165
166 conf.setInt("hbase.client.retries.number", 1);
167 adm = new HBaseAdmin(getConf());
168 } catch (MasterNotRunningException e) {
169 LOG.error("Master not running");
170 return -1;
171 } catch (ZooKeeperConnectionException e) {
172 LOG.error("ZooKeeper not available");
173 return -1;
174 }
175 try {
176 adm.shutdown();
177 } catch (Throwable t) {
178 LOG.error("Failed to stop master", t);
179 return -1;
180 }
181 return 0;
182 }
183
184 private void waitOnMasterThreads(LocalHBaseCluster cluster) throws InterruptedException{
185 List<JVMClusterUtil.MasterThread> masters = cluster.getMasters();
186 List<JVMClusterUtil.RegionServerThread> regionservers = cluster.getRegionServers();
187
188 if (masters != null) {
189 for (JVMClusterUtil.MasterThread t : masters) {
190 t.join();
191 if(t.getMaster().isAborted()) {
192 closeAllRegionServerThreads(regionservers);
193 throw new RuntimeException("HMaster Aborted");
194 }
195 }
196 }
197 }
198
199 private static void closeAllRegionServerThreads(List<JVMClusterUtil.RegionServerThread> regionservers) {
200 for(JVMClusterUtil.RegionServerThread t : regionservers){
201 t.getRegionServer().stop("HMaster Aborted; Bringing down regions servers");
202 }
203 }
204
205
206
207
208 public static class LocalHMaster extends HMaster {
209 private MiniZooKeeperCluster zkcluster = null;
210
211 public LocalHMaster(Configuration conf)
212 throws IOException, KeeperException, InterruptedException {
213 super(conf);
214 }
215
216 @Override
217 public void run() {
218 super.run();
219 if (this.zkcluster != null) {
220 try {
221 this.zkcluster.shutdown();
222 } catch (IOException e) {
223 e.printStackTrace();
224 }
225 }
226 }
227
228 void setZKCluster(final MiniZooKeeperCluster zkcluster) {
229 this.zkcluster = zkcluster;
230 }
231 }
232 }