1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase;
20
21 import java.io.IOException;
22 import java.security.PrivilegedExceptionAction;
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.List;
26
27 import com.google.common.base.Joiner;
28 import org.apache.commons.logging.Log;
29 import org.apache.commons.logging.LogFactory;
30 import org.apache.hadoop.hbase.classification.InterfaceAudience;
31 import org.apache.hadoop.hbase.classification.InterfaceStability;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.client.Admin;
34 import org.apache.hadoop.hbase.client.HBaseAdmin;
35 import org.apache.hadoop.hbase.regionserver.HRegionServer;
36 import org.apache.hadoop.hbase.security.User;
37 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
38 import org.apache.hadoop.hbase.util.Threads;
39
40 import java.util.concurrent.CopyOnWriteArrayList;
41 import org.apache.hadoop.hbase.master.HMaster;
42 import org.apache.hadoop.hbase.util.JVMClusterUtil;
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 @InterfaceAudience.Public
61 @InterfaceStability.Evolving
62 public class LocalHBaseCluster {
63 private static final Log LOG = LogFactory.getLog(LocalHBaseCluster.class);
64 private final List<JVMClusterUtil.MasterThread> masterThreads =
65 new CopyOnWriteArrayList<JVMClusterUtil.MasterThread>();
66 private final List<JVMClusterUtil.RegionServerThread> regionThreads =
67 new CopyOnWriteArrayList<JVMClusterUtil.RegionServerThread>();
68 private final static int DEFAULT_NO = 1;
69
70 public static final String LOCAL = "local";
71
72 public static final String LOCAL_COLON = LOCAL + ":";
73 public static final String ASSIGN_RANDOM_PORTS = "hbase.localcluster.assign.random.ports";
74
75 private final Configuration conf;
76 private final Class<? extends HMaster> masterClass;
77 private final Class<? extends HRegionServer> regionServerClass;
78
79
80
81
82
83
84 public LocalHBaseCluster(final Configuration conf)
85 throws IOException {
86 this(conf, DEFAULT_NO);
87 }
88
89
90
91
92
93
94
95
96 public LocalHBaseCluster(final Configuration conf, final int noRegionServers)
97 throws IOException {
98 this(conf, 1, noRegionServers, getMasterImplementation(conf),
99 getRegionServerImplementation(conf));
100 }
101
102
103
104
105
106
107
108
109
110 public LocalHBaseCluster(final Configuration conf, final int noMasters,
111 final int noRegionServers)
112 throws IOException {
113 this(conf, noMasters, noRegionServers, getMasterImplementation(conf),
114 getRegionServerImplementation(conf));
115 }
116
117 @SuppressWarnings("unchecked")
118 private static Class<? extends HRegionServer> getRegionServerImplementation(final Configuration conf) {
119 return (Class<? extends HRegionServer>)conf.getClass(HConstants.REGION_SERVER_IMPL,
120 HRegionServer.class);
121 }
122
123 @SuppressWarnings("unchecked")
124 private static Class<? extends HMaster> getMasterImplementation(final Configuration conf) {
125 return (Class<? extends HMaster>)conf.getClass(HConstants.MASTER_IMPL,
126 HMaster.class);
127 }
128
129
130
131
132
133
134
135
136
137
138
139 @SuppressWarnings("unchecked")
140 public LocalHBaseCluster(final Configuration conf, final int noMasters,
141 final int noRegionServers, final Class<? extends HMaster> masterClass,
142 final Class<? extends HRegionServer> regionServerClass)
143 throws IOException {
144 this.conf = conf;
145
146
147
148 if (conf.getBoolean(ASSIGN_RANDOM_PORTS, true)) {
149 conf.set(HConstants.MASTER_PORT, "0");
150 conf.set(HConstants.REGIONSERVER_PORT, "0");
151 if (conf.getInt(HConstants.REGIONSERVER_INFO_PORT, 0) != -1) {
152 conf.set(HConstants.REGIONSERVER_INFO_PORT, "0");
153 }
154 if (conf.getInt(HConstants.MASTER_INFO_PORT, 0) != -1) {
155 conf.set(HConstants.MASTER_INFO_PORT, "0");
156 }
157 }
158
159 this.masterClass = (Class<? extends HMaster>)
160 conf.getClass(HConstants.MASTER_IMPL, masterClass);
161
162 for (int i = 0; i < noMasters; i++) {
163 addMaster(new Configuration(conf), i);
164 }
165
166
167
168 List<String> masterHostPorts = new ArrayList<>();
169 for (JVMClusterUtil.MasterThread masterThread: getMasters()) {
170 masterHostPorts.add(masterThread.getMaster().getServerName().getAddress().toString());
171 }
172 conf.set(HConstants.MASTER_ADDRS_KEY, Joiner.on(",").join(masterHostPorts));
173
174
175 this.regionServerClass =
176 (Class<? extends HRegionServer>)conf.getClass(HConstants.REGION_SERVER_IMPL,
177 regionServerClass);
178
179 for (int i = 0; i < noRegionServers; i++) {
180 addRegionServer(new Configuration(conf), i);
181 }
182 }
183
184 public JVMClusterUtil.RegionServerThread addRegionServer()
185 throws IOException {
186 return addRegionServer(new Configuration(conf), this.regionThreads.size());
187 }
188
189 @SuppressWarnings("unchecked")
190 public JVMClusterUtil.RegionServerThread addRegionServer(
191 Configuration config, final int index)
192 throws IOException {
193
194
195
196
197
198
199
200 CoordinatedStateManager cp = CoordinatedStateManagerFactory.getCoordinatedStateManager(conf);
201
202 JVMClusterUtil.RegionServerThread rst =
203 JVMClusterUtil.createRegionServerThread(config, cp, (Class<? extends HRegionServer>) conf
204 .getClass(HConstants.REGION_SERVER_IMPL, this.regionServerClass), index);
205
206 this.regionThreads.add(rst);
207 return rst;
208 }
209
210 public JVMClusterUtil.RegionServerThread addRegionServer(
211 final Configuration config, final int index, User user)
212 throws IOException, InterruptedException {
213 return user.runAs(
214 new PrivilegedExceptionAction<JVMClusterUtil.RegionServerThread>() {
215 @Override
216 public JVMClusterUtil.RegionServerThread run() throws Exception {
217 return addRegionServer(config, index);
218 }
219 });
220 }
221
222 public JVMClusterUtil.MasterThread addMaster() throws IOException {
223 return addMaster(new Configuration(conf), this.masterThreads.size());
224 }
225
226 public JVMClusterUtil.MasterThread addMaster(Configuration c, final int index)
227 throws IOException {
228
229
230
231
232
233
234
235 CoordinatedStateManager cp = CoordinatedStateManagerFactory.getCoordinatedStateManager(conf);
236
237 JVMClusterUtil.MasterThread mt = JVMClusterUtil.createMasterThread(c, cp,
238 (Class<? extends HMaster>) conf.getClass(HConstants.MASTER_IMPL, this.masterClass), index);
239 this.masterThreads.add(mt);
240 return mt;
241 }
242
243 public JVMClusterUtil.MasterThread addMaster(
244 final Configuration c, final int index, User user)
245 throws IOException, InterruptedException {
246 return user.runAs(
247 new PrivilegedExceptionAction<JVMClusterUtil.MasterThread>() {
248 @Override
249 public JVMClusterUtil.MasterThread run() throws Exception {
250 return addMaster(c, index);
251 }
252 });
253 }
254
255
256
257
258
259 public HRegionServer getRegionServer(int serverNumber) {
260 return regionThreads.get(serverNumber).getRegionServer();
261 }
262
263
264
265
266 public List<JVMClusterUtil.RegionServerThread> getRegionServers() {
267 return Collections.unmodifiableList(this.regionThreads);
268 }
269
270
271
272
273
274
275 public List<JVMClusterUtil.RegionServerThread> getLiveRegionServers() {
276 List<JVMClusterUtil.RegionServerThread> liveServers =
277 new ArrayList<JVMClusterUtil.RegionServerThread>();
278 List<RegionServerThread> list = getRegionServers();
279 for (JVMClusterUtil.RegionServerThread rst: list) {
280 if (rst.isAlive()) liveServers.add(rst);
281 else LOG.info("Not alive " + rst.getName());
282 }
283 return liveServers;
284 }
285
286
287
288
289 public Configuration getConfiguration() {
290 return this.conf;
291 }
292
293
294
295
296
297 public String waitOnRegionServer(int serverNumber) {
298 JVMClusterUtil.RegionServerThread regionServerThread = this.regionThreads.get(serverNumber);
299 return waitOnRegionServer(regionServerThread);
300 }
301
302
303
304
305
306 public String waitOnRegionServer(JVMClusterUtil.RegionServerThread rst) {
307 while (rst.isAlive()) {
308 try {
309 LOG.info("Waiting on " + rst.getRegionServer().toString());
310 rst.join();
311 } catch (InterruptedException e) {
312 e.printStackTrace();
313 }
314 }
315 regionThreads.remove(rst);
316 return rst.getName();
317 }
318
319
320
321
322 public HMaster getMaster(int serverNumber) {
323 return masterThreads.get(serverNumber).getMaster();
324 }
325
326
327
328
329
330
331 public HMaster getActiveMaster() {
332 for (JVMClusterUtil.MasterThread mt : masterThreads) {
333
334
335 if (mt.getMaster().isActiveMaster() && !mt.getMaster().isStopped()) {
336 return mt.getMaster();
337 }
338 }
339 return null;
340 }
341
342
343
344
345 public List<JVMClusterUtil.MasterThread> getMasters() {
346 return Collections.unmodifiableList(this.masterThreads);
347 }
348
349
350
351
352
353
354 public List<JVMClusterUtil.MasterThread> getLiveMasters() {
355 List<JVMClusterUtil.MasterThread> liveServers = new ArrayList<>();
356 List<JVMClusterUtil.MasterThread> list = getMasters();
357 for (JVMClusterUtil.MasterThread mt: list) {
358 if (mt.isAlive()) {
359 liveServers.add(mt);
360 }
361 }
362 return liveServers;
363 }
364
365
366
367
368
369 public String waitOnMaster(int serverNumber) {
370 JVMClusterUtil.MasterThread masterThread = this.masterThreads.get(serverNumber);
371 return waitOnMaster(masterThread);
372 }
373
374
375
376
377
378 public String waitOnMaster(JVMClusterUtil.MasterThread masterThread) {
379 while (masterThread.isAlive()) {
380 try {
381 LOG.info("Waiting on " + masterThread.getMaster().getServerName().toString());
382 masterThread.join();
383 } catch (InterruptedException e) {
384 e.printStackTrace();
385 }
386 }
387 masterThreads.remove(masterThread);
388 return masterThread.getName();
389 }
390
391
392
393
394
395 public void join() {
396 if (this.regionThreads != null) {
397 for(Thread t: this.regionThreads) {
398 if (t.isAlive()) {
399 try {
400 Threads.threadDumpingIsAlive(t);
401 } catch (InterruptedException e) {
402 LOG.debug("Interrupted", e);
403 }
404 }
405 }
406 }
407 if (this.masterThreads != null) {
408 for (Thread t : this.masterThreads) {
409 if (t.isAlive()) {
410 try {
411 Threads.threadDumpingIsAlive(t);
412 } catch (InterruptedException e) {
413 LOG.debug("Interrupted", e);
414 }
415 }
416 }
417 }
418 }
419
420
421
422
423 public void startup() throws IOException {
424 JVMClusterUtil.startup(this.masterThreads, this.regionThreads);
425 }
426
427
428
429
430 public void shutdown() {
431 JVMClusterUtil.shutdown(this.masterThreads, this.regionThreads);
432 }
433
434
435
436
437
438 public static boolean isLocal(final Configuration c) {
439 boolean mode = c.getBoolean(HConstants.CLUSTER_DISTRIBUTED, HConstants.DEFAULT_CLUSTER_DISTRIBUTED);
440 return(mode == HConstants.CLUSTER_IS_LOCAL);
441 }
442
443
444
445
446
447
448 public static void main(String[] args) throws IOException {
449 Configuration conf = HBaseConfiguration.create();
450 LocalHBaseCluster cluster = new LocalHBaseCluster(conf);
451 cluster.startup();
452 Admin admin = new HBaseAdmin(conf);
453 try {
454 HTableDescriptor htd =
455 new HTableDescriptor(TableName.valueOf(cluster.getClass().getName()));
456 admin.createTable(htd);
457 } finally {
458 admin.close();
459 }
460 cluster.shutdown();
461 }
462 }