1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import static org.junit.Assert.assertTrue;
21 import static org.junit.Assert.fail;
22
23 import java.io.IOException;
24 import java.net.SocketTimeoutException;
25 import java.util.Comparator;
26 import java.util.HashMap;
27 import java.util.Map;
28 import java.util.Random;
29 import java.util.SortedMap;
30 import java.util.concurrent.ConcurrentSkipListMap;
31 import java.util.concurrent.ExecutorService;
32 import java.util.concurrent.Executors;
33 import java.util.concurrent.atomic.AtomicInteger;
34 import java.util.concurrent.atomic.AtomicLong;
35
36 import org.apache.hadoop.hbase.util.ByteStringer;
37 import org.apache.commons.lang.NotImplementedException;
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.apache.hadoop.conf.Configuration;
41 import org.apache.hadoop.conf.Configured;
42 import org.apache.hadoop.hbase.DoNotRetryIOException;
43 import org.apache.hadoop.hbase.HBaseConfiguration;
44 import org.apache.hadoop.hbase.HConstants;
45 import org.apache.hadoop.hbase.HRegionInfo;
46 import org.apache.hadoop.hbase.HRegionLocation;
47 import org.apache.hadoop.hbase.RegionLocations;
48 import org.apache.hadoop.hbase.KeyValue;
49 import org.apache.hadoop.hbase.RegionTooBusyException;
50 import org.apache.hadoop.hbase.ServerName;
51 import org.apache.hadoop.hbase.testclassification.SmallTests;
52 import org.apache.hadoop.hbase.TableName;
53 import org.apache.hadoop.hbase.protobuf.generated.CellProtos;
54 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos;
55 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileRequest;
56 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.BulkLoadHFileResponse;
57 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ClientService;
58 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ClientService.BlockingInterface;
59 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceRequest;
60 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.CoprocessorServiceResponse;
61 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetRequest;
62 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.GetResponse;
63 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiRequest;
64 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MultiResponse;
65 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateRequest;
66 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.MutateResponse;
67 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionAction;
68 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.RegionActionResult;
69 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ResultOrException;
70 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanRequest;
71 import org.apache.hadoop.hbase.protobuf.generated.ClientProtos.ScanResponse;
72 import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.RegionSpecifier.RegionSpecifierType;
73 import org.apache.hadoop.hbase.regionserver.RegionServerStoppedException;
74 import org.apache.hadoop.hbase.security.User;
75 import org.apache.hadoop.hbase.util.Bytes;
76 import org.apache.hadoop.hbase.util.Pair;
77 import org.apache.hadoop.hbase.util.Threads;
78 import org.apache.hadoop.util.Tool;
79 import org.apache.hadoop.util.ToolRunner;
80 import org.junit.Before;
81 import org.junit.Ignore;
82 import org.junit.Test;
83 import org.junit.experimental.categories.Category;
84 import org.mockito.Mockito;
85
86 import com.google.common.base.Stopwatch;
87 import com.google.protobuf.ByteString;
88 import com.google.protobuf.RpcController;
89 import com.google.protobuf.ServiceException;
90
91
92
93
94
95 @Category(SmallTests.class)
96 public class TestClientNoCluster extends Configured implements Tool {
97 private static final Log LOG = LogFactory.getLog(TestClientNoCluster.class);
98 private Configuration conf;
99 public static final ServerName META_SERVERNAME =
100 ServerName.valueOf("meta.example.org", 16010, 12345);
101
102 @Before
103 public void setUp() throws Exception {
104 this.conf = HBaseConfiguration.create();
105
106
107
108 this.conf.set("hbase.client.registry.impl", SimpleConnectionRegistry.class.getName());
109 }
110
111
112
113
114 static class SimpleConnectionRegistry implements ConnectionRegistry {
115 final ServerName META_HOST = META_SERVERNAME;
116
117 @Override
118 public void init(Connection connection) {
119 }
120
121 @Override
122 public ServerName getActiveMaster() {
123 return null;
124 }
125
126 @Override
127 public RegionLocations getMetaRegionLocations() throws IOException {
128 return new RegionLocations(
129 new HRegionLocation(HRegionInfo.FIRST_META_REGIONINFO, META_HOST));
130 }
131
132 @Override
133 public String getClusterId() {
134 return HConstants.CLUSTER_ID_DEFAULT;
135 }
136
137 @Override
138 public boolean isTableOnlineState(TableName tableName, boolean enabled)
139 throws IOException {
140 return enabled;
141 }
142
143 @Override
144 public int getCurrentNrHRS() throws IOException {
145 return 1;
146 }
147
148 @Override
149 public void close() {
150 }
151 }
152
153
154
155
156
157 @Ignore
158 @Test
159 public void testTimeoutAndRetries() throws IOException {
160 Configuration localConfig = HBaseConfiguration.create(this.conf);
161
162 localConfig.set("hbase.client.connection.impl", RpcTimeoutConnection.class.getName());
163 Table table = new HTable(localConfig, TableName.META_TABLE_NAME);
164 Throwable t = null;
165 LOG.info("Start");
166 try {
167
168 table.exists(new Get(Bytes.toBytes("abc")));
169 } catch (SocketTimeoutException e) {
170
171 LOG.info("Got expected exception", e);
172 t = e;
173 } catch (RetriesExhaustedException e) {
174
175 fail();
176 } finally {
177 table.close();
178 }
179 LOG.info("Stop");
180 assertTrue(t != null);
181 }
182
183
184
185
186
187 @Test
188 public void testRpcTimeout() throws IOException {
189 Configuration localConfig = HBaseConfiguration.create(this.conf);
190
191 localConfig.set("hbase.client.connection.impl", RpcTimeoutConnection.class.getName());
192 int pause = 10;
193 localConfig.setInt("hbase.client.pause", pause);
194 localConfig.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 10);
195
196
197
198
199 localConfig.setInt(HConstants.HBASE_CLIENT_META_OPERATION_TIMEOUT, pause - 1);
200 Table table = new HTable(localConfig, TableName.META_TABLE_NAME);
201 Throwable t = null;
202 try {
203
204 table.exists(new Get(Bytes.toBytes("abc")));
205 } catch (SocketTimeoutException e) {
206
207 LOG.info("Got expected exception", e);
208 t = e;
209 } catch (RetriesExhaustedException e) {
210
211 fail();
212 } finally {
213 table.close();
214 }
215 assertTrue(t != null);
216 }
217
218 @Test
219 public void testDoNotRetryMetaScanner() throws IOException {
220 this.conf.set("hbase.client.connection.impl",
221 RegionServerStoppedOnScannerOpenConnection.class.getName());
222 try (Connection connection = ConnectionFactory.createConnection(conf)) {
223 MetaScanner.metaScan(connection, null);
224 }
225 }
226
227 @Test
228 public void testDoNotRetryOnScanNext() throws IOException {
229 this.conf.set("hbase.client.connection.impl",
230 RegionServerStoppedOnScannerOpenConnection.class.getName());
231
232
233
234 Table table = new HTable(this.conf, TableName.META_TABLE_NAME);
235 ResultScanner scanner = table.getScanner(HConstants.CATALOG_FAMILY);
236 try {
237 Result result = null;
238 while ((result = scanner.next()) != null) {
239 LOG.info(result);
240 }
241 } finally {
242 scanner.close();
243 table.close();
244 }
245 }
246
247 @Test
248 public void testRegionServerStoppedOnScannerOpen() throws IOException {
249 this.conf.set("hbase.client.connection.impl",
250 RegionServerStoppedOnScannerOpenConnection.class.getName());
251
252
253
254 Table table = new HTable(this.conf, TableName.META_TABLE_NAME);
255 ResultScanner scanner = table.getScanner(HConstants.CATALOG_FAMILY);
256 try {
257 Result result = null;
258 while ((result = scanner.next()) != null) {
259 LOG.info(result);
260 }
261 } finally {
262 scanner.close();
263 table.close();
264 }
265 }
266
267
268
269
270 static class ScanOpenNextThenExceptionThenRecoverConnection
271 extends ConnectionManager.HConnectionImplementation {
272 final ClientService.BlockingInterface stub;
273
274 ScanOpenNextThenExceptionThenRecoverConnection(Configuration conf,
275 boolean managed, ExecutorService pool) throws IOException {
276 super(conf, managed);
277
278
279 this.stub = Mockito.mock(ClientService.BlockingInterface.class);
280 long sid = 12345L;
281 try {
282 Mockito.when(stub.scan((RpcController)Mockito.any(),
283 (ClientProtos.ScanRequest)Mockito.any())).
284 thenReturn(ClientProtos.ScanResponse.newBuilder().setScannerId(sid).build()).
285 thenThrow(new ServiceException(new RegionServerStoppedException("From Mockito"))).
286 thenReturn(ClientProtos.ScanResponse.newBuilder().setScannerId(sid).
287 setMoreResults(false).build());
288 } catch (ServiceException e) {
289 throw new IOException(e);
290 }
291 }
292
293 @Override
294 public BlockingInterface getClient(ServerName sn) throws IOException {
295 return this.stub;
296 }
297 }
298
299 @Test
300 public void testConnectionClosedOnRegionLocate() throws IOException {
301 Configuration testConf = new Configuration(this.conf);
302 testConf.setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 2);
303
304
305
306 Connection connection = ConnectionFactory.createConnection(testConf);
307 Table table = connection.getTable(TableName.META_TABLE_NAME);
308 connection.close();
309 try {
310 Get get = new Get(Bytes.toBytes("dummyRow"));
311 table.get(get);
312 fail("Should have thrown DoNotRetryException but no exception thrown");
313 } catch (Exception e) {
314 if (!(e instanceof DoNotRetryIOException)) {
315 String errMsg =
316 "Should have thrown DoNotRetryException but actually " + e.getClass().getSimpleName();
317 LOG.error(errMsg, e);
318 fail(errMsg);
319 }
320 } finally {
321 table.close();
322 }
323 }
324
325
326
327
328 static class RegionServerStoppedOnScannerOpenConnection
329 extends ConnectionManager.HConnectionImplementation {
330 final ClientService.BlockingInterface stub;
331
332 RegionServerStoppedOnScannerOpenConnection(Configuration conf, boolean managed,
333 ExecutorService pool, User user) throws IOException {
334 super(conf, managed);
335
336
337 this.stub = Mockito.mock(ClientService.BlockingInterface.class);
338 long sid = 12345L;
339 try {
340 Mockito.when(stub.scan((RpcController)Mockito.any(),
341 (ClientProtos.ScanRequest)Mockito.any())).
342 thenReturn(ClientProtos.ScanResponse.newBuilder().setScannerId(sid).build()).
343 thenThrow(new ServiceException(new RegionServerStoppedException("From Mockito"))).
344 thenReturn(ClientProtos.ScanResponse.newBuilder().setScannerId(sid).
345 setMoreResults(false).build());
346 } catch (ServiceException e) {
347 throw new IOException(e);
348 }
349 }
350
351 @Override
352 public BlockingInterface getClient(ServerName sn) throws IOException {
353 return this.stub;
354 }
355 }
356
357
358
359
360 static class RpcTimeoutConnection
361 extends ConnectionManager.HConnectionImplementation {
362 final ClientService.BlockingInterface stub;
363
364 RpcTimeoutConnection(Configuration conf, boolean managed, ExecutorService pool, User user)
365 throws IOException {
366 super(conf, managed);
367
368 this.stub = Mockito.mock(ClientService.BlockingInterface.class);
369 try {
370 Mockito.when(stub.get((RpcController)Mockito.any(),
371 (ClientProtos.GetRequest)Mockito.any())).
372 thenThrow(new ServiceException(new RegionServerStoppedException("From Mockito")));
373 } catch (ServiceException e) {
374 throw new IOException(e);
375 }
376 }
377
378 @Override
379 public BlockingInterface getClient(ServerName sn) throws IOException {
380 return this.stub;
381 }
382 }
383
384
385
386
387 static class ManyServersManyRegionsConnection
388 extends ConnectionManager.HConnectionImplementation {
389
390 final Map<ServerName, ClientService.BlockingInterface> serversByClient;
391
392
393
394
395 final SortedMap<byte [], Pair<HRegionInfo, ServerName>> meta;
396 final AtomicLong sequenceids = new AtomicLong(0);
397 private final Configuration conf;
398
399 ManyServersManyRegionsConnection(Configuration conf, boolean managed,
400 ExecutorService pool, User user)
401 throws IOException {
402 super(conf, managed, pool, user);
403 int serverCount = conf.getInt("hbase.test.servers", 10);
404 this.serversByClient =
405 new HashMap<ServerName, ClientService.BlockingInterface>(serverCount);
406 this.meta = makeMeta(Bytes.toBytes(
407 conf.get("hbase.test.tablename", Bytes.toString(BIG_USER_TABLE))),
408 conf.getInt("hbase.test.regions", 100),
409 conf.getLong("hbase.test.namespace.span", 1000),
410 serverCount);
411 this.conf = conf;
412 }
413
414 @Override
415 public ClientService.BlockingInterface getClient(ServerName sn) throws IOException {
416
417 ClientService.BlockingInterface stub = null;
418 synchronized (this.serversByClient) {
419 stub = this.serversByClient.get(sn);
420 if (stub == null) {
421 stub = new FakeServer(this.conf, meta, sequenceids);
422 this.serversByClient.put(sn, stub);
423 }
424 }
425 return stub;
426 }
427 }
428
429 static MultiResponse doMultiResponse(final SortedMap<byte [], Pair<HRegionInfo, ServerName>> meta,
430 final AtomicLong sequenceids, final MultiRequest request) {
431
432 ClientProtos.MultiResponse.Builder builder = ClientProtos.MultiResponse.newBuilder();
433
434 RegionActionResult.Builder regionActionResultBuilder =
435 RegionActionResult.newBuilder();
436 ResultOrException.Builder roeBuilder = ResultOrException.newBuilder();
437 for (RegionAction regionAction: request.getRegionActionList()) {
438 regionActionResultBuilder.clear();
439
440 for (ClientProtos.Action action: regionAction.getActionList()) {
441 roeBuilder.clear();
442
443 roeBuilder.setResult(ClientProtos.Result.getDefaultInstance());
444 roeBuilder.setIndex(action.getIndex());
445 regionActionResultBuilder.addResultOrException(roeBuilder.build());
446 }
447 builder.addRegionActionResult(regionActionResultBuilder.build());
448 }
449 return builder.build();
450 }
451
452
453
454
455
456
457 static class FakeServer implements ClientService.BlockingInterface {
458 private AtomicInteger multiInvocationsCount = new AtomicInteger(0);
459 private final SortedMap<byte [], Pair<HRegionInfo, ServerName>> meta;
460 private final AtomicLong sequenceids;
461 private final long multiPause;
462 private final int tooManyMultiRequests;
463
464 FakeServer(final Configuration c, final SortedMap<byte [], Pair<HRegionInfo, ServerName>> meta,
465 final AtomicLong sequenceids) {
466 this.meta = meta;
467 this.sequenceids = sequenceids;
468
469
470
471 this.multiPause = c.getLong("hbase.test.multi.pause.when.done", 0);
472 this.tooManyMultiRequests = c.getInt("hbase.test.multi.too.many", 3);
473 }
474
475 @Override
476 public GetResponse get(RpcController controller, GetRequest request)
477 throws ServiceException {
478 boolean metaRegion = isMetaRegion(request.getRegion().getValue().toByteArray(),
479 request.getRegion().getType());
480 if (!metaRegion) {
481 return doGetResponse(request);
482 }
483 return doMetaGetResponse(meta, request);
484 }
485
486 private GetResponse doGetResponse(GetRequest request) {
487 ClientProtos.Result.Builder resultBuilder = ClientProtos.Result.newBuilder();
488 ByteString row = request.getGet().getRow();
489 resultBuilder.addCell(getStartCode(row));
490 GetResponse.Builder builder = GetResponse.newBuilder();
491 builder.setResult(resultBuilder.build());
492 return builder.build();
493 }
494
495 @Override
496 public MutateResponse mutate(RpcController controller,
497 MutateRequest request) throws ServiceException {
498 throw new NotImplementedException();
499 }
500
501 @Override
502 public ScanResponse scan(RpcController controller,
503 ScanRequest request) throws ServiceException {
504
505
506 return doMetaScanResponse(meta, sequenceids, request);
507 }
508
509 @Override
510 public BulkLoadHFileResponse bulkLoadHFile(
511 RpcController controller, BulkLoadHFileRequest request)
512 throws ServiceException {
513 throw new NotImplementedException();
514 }
515
516 @Override
517 public CoprocessorServiceResponse execService(
518 RpcController controller, CoprocessorServiceRequest request)
519 throws ServiceException {
520 throw new NotImplementedException();
521 }
522
523 @Override
524 public MultiResponse multi(RpcController controller, MultiRequest request)
525 throws ServiceException {
526 int concurrentInvocations = this.multiInvocationsCount.incrementAndGet();
527 try {
528 if (concurrentInvocations >= tooManyMultiRequests) {
529 throw new ServiceException(new RegionTooBusyException("concurrentInvocations=" +
530 concurrentInvocations));
531 }
532 Threads.sleep(multiPause);
533 return doMultiResponse(meta, sequenceids, request);
534 } finally {
535 this.multiInvocationsCount.decrementAndGet();
536 }
537 }
538
539 @Override
540 public CoprocessorServiceResponse execRegionServerService(RpcController controller,
541 CoprocessorServiceRequest request) throws ServiceException {
542 throw new NotImplementedException();
543 }
544 }
545
546 static ScanResponse doMetaScanResponse(final SortedMap<byte [], Pair<HRegionInfo, ServerName>> meta,
547 final AtomicLong sequenceids, final ScanRequest request) {
548 ScanResponse.Builder builder = ScanResponse.newBuilder();
549 int max = request.getNumberOfRows();
550 int count = 0;
551 Map<byte [], Pair<HRegionInfo, ServerName>> tail =
552 request.hasScan()? meta.tailMap(request.getScan().getStartRow().toByteArray()): meta;
553 ClientProtos.Result.Builder resultBuilder = ClientProtos.Result.newBuilder();
554 for (Map.Entry<byte [], Pair<HRegionInfo, ServerName>> e: tail.entrySet()) {
555
556 if (max <= 0) break;
557 if (++count > max) break;
558 HRegionInfo hri = e.getValue().getFirst();
559 ByteString row = ByteStringer.wrap(hri.getRegionName());
560 resultBuilder.clear();
561 resultBuilder.addCell(getRegionInfo(row, hri));
562 resultBuilder.addCell(getServer(row, e.getValue().getSecond()));
563 resultBuilder.addCell(getStartCode(row));
564 builder.addResults(resultBuilder.build());
565
566 if (hri.getEndKey().length <= 0) builder.setMoreResults(false);
567 else builder.setMoreResults(true);
568 }
569
570 builder.setScannerId(request.hasScannerId()?
571 request.getScannerId(): sequenceids.incrementAndGet());
572 return builder.build();
573 }
574
575 static GetResponse doMetaGetResponse(final SortedMap<byte [], Pair<HRegionInfo, ServerName>> meta,
576 final GetRequest request) {
577 ClientProtos.Result.Builder resultBuilder = ClientProtos.Result.newBuilder();
578 ByteString row = request.getGet().getRow();
579 Pair<HRegionInfo, ServerName> p = meta.get(row.toByteArray());
580 if (p == null) {
581 if (request.getGet().getClosestRowBefore()) {
582 byte [] bytes = row.toByteArray();
583 SortedMap<byte [], Pair<HRegionInfo, ServerName>> head =
584 bytes != null? meta.headMap(bytes): meta;
585 p = head == null? null: head.get(head.lastKey());
586 }
587 }
588 if (p != null) {
589 resultBuilder.addCell(getRegionInfo(row, p.getFirst()));
590 resultBuilder.addCell(getServer(row, p.getSecond()));
591 }
592 resultBuilder.addCell(getStartCode(row));
593 GetResponse.Builder builder = GetResponse.newBuilder();
594 builder.setResult(resultBuilder.build());
595 return builder.build();
596 }
597
598
599
600
601
602
603 static boolean isMetaRegion(final byte [] name, final RegionSpecifierType type) {
604 switch (type) {
605 case REGION_NAME:
606 return Bytes.equals(HRegionInfo.FIRST_META_REGIONINFO.getRegionName(), name);
607 case ENCODED_REGION_NAME:
608 return Bytes.equals(HRegionInfo.FIRST_META_REGIONINFO.getEncodedNameAsBytes(), name);
609 default: throw new UnsupportedOperationException();
610 }
611 }
612
613 private final static ByteString CATALOG_FAMILY_BYTESTRING =
614 ByteStringer.wrap(HConstants.CATALOG_FAMILY);
615 private final static ByteString REGIONINFO_QUALIFIER_BYTESTRING =
616 ByteStringer.wrap(HConstants.REGIONINFO_QUALIFIER);
617 private final static ByteString SERVER_QUALIFIER_BYTESTRING =
618 ByteStringer.wrap(HConstants.SERVER_QUALIFIER);
619
620 static CellProtos.Cell.Builder getBaseCellBuilder(final ByteString row) {
621 CellProtos.Cell.Builder cellBuilder = CellProtos.Cell.newBuilder();
622 cellBuilder.setRow(row);
623 cellBuilder.setFamily(CATALOG_FAMILY_BYTESTRING);
624 cellBuilder.setTimestamp(System.currentTimeMillis());
625 return cellBuilder;
626 }
627
628 static CellProtos.Cell getRegionInfo(final ByteString row, final HRegionInfo hri) {
629 CellProtos.Cell.Builder cellBuilder = getBaseCellBuilder(row);
630 cellBuilder.setQualifier(REGIONINFO_QUALIFIER_BYTESTRING);
631 cellBuilder.setValue(ByteStringer.wrap(hri.toByteArray()));
632 return cellBuilder.build();
633 }
634
635 static CellProtos.Cell getServer(final ByteString row, final ServerName sn) {
636 CellProtos.Cell.Builder cellBuilder = getBaseCellBuilder(row);
637 cellBuilder.setQualifier(SERVER_QUALIFIER_BYTESTRING);
638 cellBuilder.setValue(ByteString.copyFromUtf8(sn.getHostAndPort()));
639 return cellBuilder.build();
640 }
641
642 static CellProtos.Cell getStartCode(final ByteString row) {
643 CellProtos.Cell.Builder cellBuilder = getBaseCellBuilder(row);
644 cellBuilder.setQualifier(ByteStringer.wrap(HConstants.STARTCODE_QUALIFIER));
645
646 cellBuilder.setValue(ByteStringer.wrap(Bytes.toBytes(META_SERVERNAME.getStartcode())));
647 return cellBuilder.build();
648 }
649
650 private static final byte [] BIG_USER_TABLE = Bytes.toBytes("t");
651
652
653
654
655
656
657
658
659 private static byte [] format(final long number) {
660 byte [] b = new byte[10];
661 long d = number;
662 for (int i = b.length - 1; i >= 0; i--) {
663 b[i] = (byte)((d % 10) + '0');
664 d /= 10;
665 }
666 return b;
667 }
668
669
670
671
672
673
674 private static HRegionInfo [] makeHRegionInfos(final byte [] tableName, final int count,
675 final long namespaceSpan) {
676 byte [] startKey = HConstants.EMPTY_BYTE_ARRAY;
677 byte [] endKey = HConstants.EMPTY_BYTE_ARRAY;
678 long interval = namespaceSpan / count;
679 HRegionInfo [] hris = new HRegionInfo[count];
680 for (int i = 0; i < count; i++) {
681 if (i == 0) {
682 endKey = format(interval);
683 } else {
684 startKey = endKey;
685 if (i == count - 1) endKey = HConstants.EMPTY_BYTE_ARRAY;
686 else endKey = format((i + 1) * interval);
687 }
688 hris[i] = new HRegionInfo(TableName.valueOf(tableName), startKey, endKey);
689 }
690 return hris;
691 }
692
693
694
695
696
697 private static ServerName [] makeServerNames(final int count) {
698 ServerName [] sns = new ServerName[count];
699 for (int i = 0; i < count; i++) {
700 sns[i] = ServerName.valueOf("" + i + ".example.org", 16010, i);
701 }
702 return sns;
703 }
704
705
706
707
708 private static class MetaRowsComparator implements Comparator<byte []> {
709 private final KeyValue.KVComparator delegate = new KeyValue.MetaComparator();
710 @Override
711 public int compare(byte[] left, byte[] right) {
712 return delegate.compareRows(left, 0, left.length, right, 0, right.length);
713 }
714 }
715
716
717
718
719
720
721 static SortedMap<byte [], Pair<HRegionInfo, ServerName>> makeMeta(final byte [] tableName,
722 final int regionCount, final long namespaceSpan, final int serverCount) {
723
724 SortedMap<byte [], Pair<HRegionInfo, ServerName>> meta =
725 new ConcurrentSkipListMap<byte[], Pair<HRegionInfo,ServerName>>(new MetaRowsComparator());
726 HRegionInfo [] hris = makeHRegionInfos(tableName, regionCount, namespaceSpan);
727 ServerName [] serverNames = makeServerNames(serverCount);
728 int per = regionCount / serverCount;
729 int count = 0;
730 for (HRegionInfo hri: hris) {
731 Pair<HRegionInfo, ServerName> p =
732 new Pair<HRegionInfo, ServerName>(hri, serverNames[count++ / per]);
733 meta.put(hri.getRegionName(), p);
734 }
735 return meta;
736 }
737
738
739
740
741
742
743
744
745
746 static void cycle(int id, final Configuration c, final Connection sharedConnection) throws IOException {
747 long namespaceSpan = c.getLong("hbase.test.namespace.span", 1000000);
748 long startTime = System.currentTimeMillis();
749 final int printInterval = 100000;
750 Random rd = new Random(id);
751 boolean get = c.getBoolean("hbase.test.do.gets", false);
752 TableName tableName = TableName.valueOf(BIG_USER_TABLE);
753 if (get) {
754 try (Table table = sharedConnection.getTable(tableName)){
755 Stopwatch stopWatch = new Stopwatch();
756 stopWatch.start();
757 for (int i = 0; i < namespaceSpan; i++) {
758 byte [] b = format(rd.nextLong());
759 Get g = new Get(b);
760 table.get(g);
761 if (i % printInterval == 0) {
762 LOG.info("Get " + printInterval + "/" + stopWatch.elapsedMillis());
763 stopWatch.reset();
764 stopWatch.start();
765 }
766 }
767 LOG.info("Finished a cycle putting " + namespaceSpan + " in " +
768 (System.currentTimeMillis() - startTime) + "ms");
769 }
770 } else {
771 try (BufferedMutator mutator = sharedConnection.getBufferedMutator(tableName)) {
772 Stopwatch stopWatch = new Stopwatch();
773 stopWatch.start();
774 for (int i = 0; i < namespaceSpan; i++) {
775 byte [] b = format(rd.nextLong());
776 Put p = new Put(b);
777 p.add(HConstants.CATALOG_FAMILY, b, b);
778 mutator.mutate(p);
779 if (i % printInterval == 0) {
780 LOG.info("Put " + printInterval + "/" + stopWatch.elapsedMillis());
781 stopWatch.reset();
782 stopWatch.start();
783 }
784 }
785 LOG.info("Finished a cycle putting " + namespaceSpan + " in " +
786 (System.currentTimeMillis() - startTime) + "ms");
787 }
788 }
789 }
790
791 @Override
792 public int run(String[] arg0) throws Exception {
793 int errCode = 0;
794
795
796 final int servers = 1;
797
798 final int regions = 100000;
799
800 final long namespaceSpan = 50000000;
801
802
803 final long multiPause = 0;
804
805 if ((namespaceSpan < regions) || (regions < servers)) {
806 throw new IllegalArgumentException("namespaceSpan=" + namespaceSpan + " must be > regions=" +
807 regions + " which must be > servers=" + servers);
808 }
809
810
811 getConf().set("hbase.client.connection.impl",
812 ManyServersManyRegionsConnection.class.getName());
813
814 getConf().set("hbase.client.registry.impl", SimpleConnectionRegistry.class.getName());
815
816
817
818 getConf().setInt("hbase.client.start.log.errors.counter", 0);
819
820
821 getConf().setInt("hbase.test.regions", regions);
822 getConf().setLong("hbase.test.namespace.span", namespaceSpan);
823 getConf().setLong("hbase.test.servers", servers);
824 getConf().set("hbase.test.tablename", Bytes.toString(BIG_USER_TABLE));
825 getConf().setLong("hbase.test.multi.pause.when.done", multiPause);
826
827 getConf().setInt("hbase.test.multi.too.many", 10);
828 final int clients = 2;
829
830
831
832 final ExecutorService pool = Executors.newCachedThreadPool(Threads.getNamedThreadFactory("p"));
833
834
835 final Connection sharedConnection = ConnectionFactory.createConnection(getConf()
836 try {
837 Thread [] ts = new Thread[clients];
838 for (int j = 0; j < ts.length; j++) {
839 final int id = j;
840 ts[j] = new Thread("" + j) {
841 final Configuration c = getConf();
842
843 @Override
844 public void run() {
845 try {
846 cycle(id, c, sharedConnection);
847 } catch (IOException e) {
848 e.printStackTrace();
849 }
850 }
851 };
852 ts[j].start();
853 }
854 for (int j = 0; j < ts.length; j++) {
855 ts[j].join();
856 }
857 } finally {
858 sharedConnection.close();
859 }
860 return errCode;
861 }
862
863
864
865
866
867
868 public static void main(String[] args) throws Exception {
869 System.exit(ToolRunner.run(HBaseConfiguration.create(), new TestClientNoCluster(), args));
870 }
871 }