1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.IOException;
26 import java.util.Arrays;
27 import java.util.List;
28 import java.util.Random;
29
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.fs.Path;
34 import org.apache.hadoop.hbase.HBaseConfiguration;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.HColumnDescriptor;
37 import org.apache.hadoop.hbase.HConstants;
38 import org.apache.hadoop.hbase.HRegionInfo;
39 import org.apache.hadoop.hbase.HTableDescriptor;
40 import org.apache.hadoop.hbase.MiniHBaseCluster;
41 import org.apache.hadoop.hbase.NamespaceDescriptor;
42 import org.apache.hadoop.hbase.TableName;
43 import org.apache.hadoop.hbase.Waiter;
44 import org.apache.hadoop.hbase.client.Admin;
45 import org.apache.hadoop.hbase.client.Connection;
46 import org.apache.hadoop.hbase.client.ConnectionFactory;
47 import org.apache.hadoop.hbase.client.Get;
48 import org.apache.hadoop.hbase.client.HTable;
49 import org.apache.hadoop.hbase.client.Put;
50 import org.apache.hadoop.hbase.client.Result;
51 import org.apache.hadoop.hbase.client.Table;
52 import org.apache.hadoop.hbase.regionserver.wal.FSHLog;
53 import org.apache.hadoop.hbase.testclassification.LargeTests;
54 import org.apache.hadoop.hbase.util.Bytes;
55 import org.apache.hadoop.hbase.util.JVMClusterUtil;
56 import org.apache.hadoop.hbase.util.Pair;
57 import org.apache.hadoop.hbase.wal.WAL;
58 import org.junit.Test;
59 import org.junit.experimental.categories.Category;
60
61 import com.google.common.hash.Hashing;
62
63
64
65
66 @Category(LargeTests.class)
67 public class TestPerColumnFamilyFlush {
68 private static final Log LOG = LogFactory.getLog(TestPerColumnFamilyFlush.class);
69
70 Region region = null;
71
72 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
73
74 private static final Path DIR = TEST_UTIL.getDataTestDir("TestHRegion");
75
76 public static final TableName TABLENAME = TableName.valueOf("TestPerColumnFamilyFlush", "t1");
77
78 public static final byte[][] FAMILIES = { Bytes.toBytes("f1"), Bytes.toBytes("f2"),
79 Bytes.toBytes("f3"), Bytes.toBytes("f4"), Bytes.toBytes("f5") };
80
81 public static final byte[] FAMILY1 = FAMILIES[0];
82
83 public static final byte[] FAMILY2 = FAMILIES[1];
84
85 public static final byte[] FAMILY3 = FAMILIES[2];
86
87 private void initHRegion(String callingMethod, Configuration conf) throws IOException {
88 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
89 for (byte[] family : FAMILIES) {
90 htd.addFamily(new HColumnDescriptor(family));
91 }
92 HRegionInfo info = new HRegionInfo(TABLENAME, null, null, false);
93 Path path = new Path(DIR, callingMethod);
94 region = HRegion.createHRegion(info, path, conf, htd);
95 }
96
97
98 private Put createPut(int familyNum, int putNum) {
99 byte[] qf = Bytes.toBytes("q" + familyNum);
100 byte[] row = Bytes.toBytes("row" + familyNum + "-" + putNum);
101 byte[] val = Bytes.toBytes("val" + familyNum + "-" + putNum);
102 Put p = new Put(row);
103 p.addColumn(FAMILIES[familyNum - 1], qf, val);
104 return p;
105 }
106
107
108 private Get createGet(int familyNum, int putNum) {
109 byte[] row = Bytes.toBytes("row" + familyNum + "-" + putNum);
110 return new Get(row);
111 }
112
113
114 void verifyEdit(int familyNum, int putNum, HTable table) throws IOException {
115 Result r = table.get(createGet(familyNum, putNum));
116 byte[] family = FAMILIES[familyNum - 1];
117 byte[] qf = Bytes.toBytes("q" + familyNum);
118 byte[] val = Bytes.toBytes("val" + familyNum + "-" + putNum);
119 assertNotNull(("Missing Put#" + putNum + " for CF# " + familyNum), r.getFamilyMap(family));
120 assertNotNull(("Missing Put#" + putNum + " for CF# " + familyNum),
121 r.getFamilyMap(family).get(qf));
122 assertTrue(("Incorrect value for Put#" + putNum + " for CF# " + familyNum),
123 Arrays.equals(r.getFamilyMap(family).get(qf), val));
124 }
125
126 @Test(timeout = 180000)
127 public void testSelectiveFlushWhenEnabled() throws IOException {
128
129 Configuration conf = HBaseConfiguration.create();
130 conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, 200 * 1024);
131 conf.set(FlushPolicyFactory.HBASE_FLUSH_POLICY_KEY, FlushLargeStoresPolicy.class.getName());
132 conf.setLong(FlushLargeStoresPolicy.HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND, 100 * 1024);
133
134 initHRegion("testSelectiveFlushWhenEnabled", conf);
135
136 for (int i = 1; i <= 1200; i++) {
137 region.put(createPut(1, i));
138
139 if (i <= 100) {
140 region.put(createPut(2, i));
141 if (i <= 50) {
142 region.put(createPut(3, i));
143 }
144 }
145 }
146
147 long totalMemstoreSize = region.getMemstoreSize();
148
149
150 long smallestSeqCF1 = region.getOldestSeqIdOfStore(FAMILY1);
151 long smallestSeqCF2 = region.getOldestSeqIdOfStore(FAMILY2);
152 long smallestSeqCF3 = region.getOldestSeqIdOfStore(FAMILY3);
153
154
155 long cf1MemstoreSize = region.getStore(FAMILY1).getMemStoreSize();
156 long cf2MemstoreSize = region.getStore(FAMILY2).getMemStoreSize();
157 long cf3MemstoreSize = region.getStore(FAMILY3).getMemStoreSize();
158
159
160 long smallestSeqInRegionCurrentMemstore = getWAL(region)
161 .getEarliestMemstoreSeqNum(region.getRegionInfo().getEncodedNameAsBytes());
162
163
164
165 assertEquals(smallestSeqCF1, smallestSeqInRegionCurrentMemstore);
166
167
168 assertTrue(smallestSeqCF1 < smallestSeqCF2);
169 assertTrue(smallestSeqCF2 < smallestSeqCF3);
170 assertTrue(cf1MemstoreSize > 0);
171 assertTrue(cf2MemstoreSize > 0);
172 assertTrue(cf3MemstoreSize > 0);
173
174
175
176 assertEquals(totalMemstoreSize + 3 * DefaultMemStore.DEEP_OVERHEAD, cf1MemstoreSize
177 + cf2MemstoreSize + cf3MemstoreSize);
178
179
180 region.flush(false);
181
182
183 long oldCF2MemstoreSize = cf2MemstoreSize;
184 long oldCF3MemstoreSize = cf3MemstoreSize;
185
186
187 cf1MemstoreSize = region.getStore(FAMILY1).getMemStoreSize();
188 cf2MemstoreSize = region.getStore(FAMILY2).getMemStoreSize();
189 cf3MemstoreSize = region.getStore(FAMILY3).getMemStoreSize();
190 totalMemstoreSize = region.getMemstoreSize();
191 smallestSeqInRegionCurrentMemstore = getWAL(region)
192 .getEarliestMemstoreSeqNum(region.getRegionInfo().getEncodedNameAsBytes());
193
194
195
196 assertEquals(DefaultMemStore.DEEP_OVERHEAD, cf1MemstoreSize);
197
198 assertEquals(cf2MemstoreSize, oldCF2MemstoreSize);
199
200 assertEquals(cf3MemstoreSize, oldCF3MemstoreSize);
201
202
203 assertEquals(smallestSeqInRegionCurrentMemstore, smallestSeqCF2);
204
205 assertEquals(totalMemstoreSize + 2 * DefaultMemStore.DEEP_OVERHEAD, cf2MemstoreSize
206 + cf3MemstoreSize);
207
208
209 for (int i = 1200; i < 2400; i++) {
210 region.put(createPut(2, i));
211
212
213 if (i - 1200 < 100) {
214 region.put(createPut(3, i));
215 }
216 }
217
218
219 oldCF3MemstoreSize = region.getStore(FAMILY3).getMemStoreSize();
220
221
222 region.flush(false);
223
224
225 cf1MemstoreSize = region.getStore(FAMILY1).getMemStoreSize();
226 cf2MemstoreSize = region.getStore(FAMILY2).getMemStoreSize();
227 cf3MemstoreSize = region.getStore(FAMILY3).getMemStoreSize();
228 totalMemstoreSize = region.getMemstoreSize();
229 smallestSeqInRegionCurrentMemstore = getWAL(region)
230 .getEarliestMemstoreSeqNum(region.getRegionInfo().getEncodedNameAsBytes());
231
232
233 assertEquals(DefaultMemStore.DEEP_OVERHEAD, cf1MemstoreSize);
234 assertEquals(DefaultMemStore.DEEP_OVERHEAD, cf2MemstoreSize);
235
236 assertEquals(cf3MemstoreSize, oldCF3MemstoreSize);
237 assertEquals(totalMemstoreSize + DefaultMemStore.DEEP_OVERHEAD, cf3MemstoreSize);
238 assertEquals(smallestSeqInRegionCurrentMemstore, smallestSeqCF3);
239
240
241
242
243
244
245 region.flush(true);
246
247
248
249
250 for (int i = 1; i <= 300; i++) {
251 region.put(createPut(1, i));
252 region.put(createPut(2, i));
253 region.put(createPut(3, i));
254 region.put(createPut(4, i));
255 region.put(createPut(5, i));
256 }
257
258 region.flush(false);
259
260
261
262 assertEquals(0, region.getMemstoreSize());
263 }
264
265 @Test(timeout = 180000)
266 public void testSelectiveFlushWhenNotEnabled() throws IOException {
267
268 Configuration conf = HBaseConfiguration.create();
269 conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, 200 * 1024);
270 conf.set(FlushPolicyFactory.HBASE_FLUSH_POLICY_KEY, FlushAllStoresPolicy.class.getName());
271
272
273 initHRegion("testSelectiveFlushWhenNotEnabled", conf);
274
275 for (int i = 1; i <= 1200; i++) {
276 region.put(createPut(1, i));
277 if (i <= 100) {
278 region.put(createPut(2, i));
279 if (i <= 50) {
280 region.put(createPut(3, i));
281 }
282 }
283 }
284
285 long totalMemstoreSize = region.getMemstoreSize();
286
287
288 long cf1MemstoreSize = region.getStore(FAMILY1).getMemStoreSize();
289 long cf2MemstoreSize = region.getStore(FAMILY2).getMemStoreSize();
290 long cf3MemstoreSize = region.getStore(FAMILY3).getMemStoreSize();
291
292
293 assertTrue(cf1MemstoreSize > 0);
294 assertTrue(cf2MemstoreSize > 0);
295 assertTrue(cf3MemstoreSize > 0);
296
297
298
299 assertEquals(totalMemstoreSize + 3 * DefaultMemStore.DEEP_OVERHEAD, cf1MemstoreSize
300 + cf2MemstoreSize + cf3MemstoreSize);
301
302
303 region.flush(false);
304
305 cf1MemstoreSize = region.getStore(FAMILY1).getMemStoreSize();
306 cf2MemstoreSize = region.getStore(FAMILY2).getMemStoreSize();
307 cf3MemstoreSize = region.getStore(FAMILY3).getMemStoreSize();
308 totalMemstoreSize = region.getMemstoreSize();
309 long smallestSeqInRegionCurrentMemstore = ((HRegion)region).getWAL()
310 .getEarliestMemstoreSeqNum(region.getRegionInfo().getEncodedNameAsBytes());
311
312
313 assertEquals(DefaultMemStore.DEEP_OVERHEAD, cf1MemstoreSize);
314 assertEquals(DefaultMemStore.DEEP_OVERHEAD, cf2MemstoreSize);
315 assertEquals(DefaultMemStore.DEEP_OVERHEAD, cf3MemstoreSize);
316 assertEquals(0, totalMemstoreSize);
317 assertEquals(HConstants.NO_SEQNUM, smallestSeqInRegionCurrentMemstore);
318 }
319
320
321 private static Pair<Region, HRegionServer> getRegionWithName(TableName tableName) {
322 MiniHBaseCluster cluster = TEST_UTIL.getMiniHBaseCluster();
323 List<JVMClusterUtil.RegionServerThread> rsts = cluster.getRegionServerThreads();
324 for (int i = 0; i < cluster.getRegionServerThreads().size(); i++) {
325 HRegionServer hrs = rsts.get(i).getRegionServer();
326 for (Region region : hrs.getOnlineRegions(tableName)) {
327 return Pair.newPair(region, hrs);
328 }
329 }
330 return null;
331 }
332
333 private void doTestLogReplay() throws Exception {
334 Configuration conf = TEST_UTIL.getConfiguration();
335 conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, 20000);
336
337 conf.set(FlushPolicyFactory.HBASE_FLUSH_POLICY_KEY, FlushLargeStoresPolicy.class.getName());
338 conf.setLong(FlushLargeStoresPolicy.HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND, 10000);
339 final int numRegionServers = 4;
340 try {
341 TEST_UTIL.startMiniCluster(numRegionServers);
342 TEST_UTIL.getHBaseAdmin().createNamespace(
343 NamespaceDescriptor.create(TABLENAME.getNamespaceAsString()).build());
344 HTable table = TEST_UTIL.createTable(TABLENAME, FAMILIES);
345 HTableDescriptor htd = table.getTableDescriptor();
346
347 for (byte[] family : FAMILIES) {
348 if (!htd.hasFamily(family)) {
349 htd.addFamily(new HColumnDescriptor(family));
350 }
351 }
352
353
354
355 for (int i = 1; i <= 80; i++) {
356 table.put(createPut(1, i));
357 if (i <= 10) {
358 table.put(createPut(2, i));
359 table.put(createPut(3, i));
360 }
361 }
362 table.flushCommits();
363 Thread.sleep(1000);
364
365 Pair<Region, HRegionServer> desiredRegionAndServer = getRegionWithName(TABLENAME);
366 Region desiredRegion = desiredRegionAndServer.getFirst();
367 assertTrue("Could not find a region which hosts the new region.", desiredRegion != null);
368
369
370 desiredRegion.flush(false);
371
372 long totalMemstoreSize;
373 long cf1MemstoreSize, cf2MemstoreSize, cf3MemstoreSize;
374 totalMemstoreSize = desiredRegion.getMemstoreSize();
375
376
377 cf1MemstoreSize = desiredRegion.getStore(FAMILY1).getMemStoreSize();
378 cf2MemstoreSize = desiredRegion.getStore(FAMILY2).getMemStoreSize();
379 cf3MemstoreSize = desiredRegion.getStore(FAMILY3).getMemStoreSize();
380
381
382 assertEquals(DefaultMemStore.DEEP_OVERHEAD, cf1MemstoreSize);
383
384 assertTrue(cf2MemstoreSize > 0);
385 assertTrue(cf3MemstoreSize > 0);
386 assertEquals(totalMemstoreSize + 2 * DefaultMemStore.DEEP_OVERHEAD, cf2MemstoreSize
387 + cf3MemstoreSize);
388
389
390
391
392
393 Thread.sleep(2000);
394
395
396 HRegionServer rs = desiredRegionAndServer.getSecond();
397 rs.abort("testing");
398
399
400
401
402
403
404 for (int i = 1; i <= 80; i++) {
405 verifyEdit(1, i, table);
406 if (i <= 10) {
407 verifyEdit(2, i, table);
408 verifyEdit(3, i, table);
409 }
410 }
411 } finally {
412 TEST_UTIL.shutdownMiniCluster();
413 }
414 }
415
416
417
418
419
420 @Test(timeout = 180000)
421 public void testLogReplayWithDistributedReplay() throws Exception {
422 TEST_UTIL.getConfiguration().setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, true);
423 doTestLogReplay();
424 }
425
426
427 @Test(timeout = 180000)
428 public void testLogReplayWithDistributedLogSplit() throws Exception {
429 TEST_UTIL.getConfiguration().setBoolean(HConstants.DISTRIBUTED_LOG_REPLAY_KEY, false);
430 doTestLogReplay();
431 }
432
433 private WAL getWAL(Region region) {
434 return ((HRegion)region).getWAL();
435 }
436
437 private int getNumRolledLogFiles(Region region) {
438 return ((FSHLog)getWAL(region)).getNumRolledLogFiles();
439 }
440
441
442
443
444
445
446
447 @Test(timeout = 180000)
448 public void testFlushingWhenLogRolling() throws Exception {
449 TableName tableName = TableName.valueOf("testFlushingWhenLogRolling");
450 Configuration conf = TEST_UTIL.getConfiguration();
451 conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, 128 * 1024 * 1024);
452 conf.set(FlushPolicyFactory.HBASE_FLUSH_POLICY_KEY, FlushLargeStoresPolicy.class.getName());
453 long cfFlushSizeLowerBound = 2048;
454 conf.setLong(FlushLargeStoresPolicy.HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND,
455 cfFlushSizeLowerBound);
456
457
458 conf.setLong("hbase.regionserver.logroll.period", 60L * 60 * 1000);
459
460 conf.setLong("hbase.regionserver.hlog.blocksize", 128L * 1024 * 1024);
461
462 final int maxLogs = 10;
463 conf.setInt("hbase.regionserver.maxlogs", maxLogs);
464
465 final int numRegionServers = 1;
466 TEST_UTIL.startMiniCluster(numRegionServers);
467 try {
468 HTable table = null;
469 table = TEST_UTIL.createTable(tableName, FAMILIES);
470
471
472
473 try (Admin admin = TEST_UTIL.getConnection().getAdmin()) {
474 admin.flush(TableName.NAMESPACE_TABLE_NAME);
475 }
476 Pair<Region, HRegionServer> desiredRegionAndServer = getRegionWithName(tableName);
477 final Region desiredRegion = desiredRegionAndServer.getFirst();
478 assertTrue("Could not find a region which hosts the new region.", desiredRegion != null);
479 LOG.info("Writing to region=" + desiredRegion);
480
481
482 for (int i = 1; i <= 3; i++) {
483 table.put(createPut(i, 0));
484 }
485
486
487 for (int i = 0; i < maxLogs; i++) {
488 for (int j = 0; j < 100; j++) {
489 table.put(createPut(1, i * 100 + j));
490 }
491 table.flushCommits();
492
493 int currentNumRolledLogFiles = getNumRolledLogFiles(desiredRegion);
494 assertNull(getWAL(desiredRegion).rollWriter());
495 while (getNumRolledLogFiles(desiredRegion) <= currentNumRolledLogFiles) {
496 Thread.sleep(100);
497 }
498 }
499 table.close();
500 assertEquals(maxLogs, getNumRolledLogFiles(desiredRegion));
501 assertTrue(desiredRegion.getStore(FAMILY1).getMemStoreSize() > cfFlushSizeLowerBound);
502 assertTrue(desiredRegion.getStore(FAMILY2).getMemStoreSize() < cfFlushSizeLowerBound);
503 assertTrue(desiredRegion.getStore(FAMILY3).getMemStoreSize() < cfFlushSizeLowerBound);
504 table.put(createPut(1, 12345678));
505 table.flushCommits();
506
507 desiredRegionAndServer.getSecond().walRoller.requestRollAll();
508
509 TEST_UTIL.waitFor(30000, new Waiter.ExplainingPredicate<Exception>() {
510
511 @Override
512 public boolean evaluate() throws Exception {
513 return desiredRegion.getMemstoreSize() == 0;
514 }
515
516 @Override
517 public String explainFailure() throws Exception {
518 long memstoreSize = desiredRegion.getMemstoreSize();
519 if (memstoreSize > 0) {
520 return "Still have unflushed entries in memstore, memstore size is " + memstoreSize;
521 }
522 return "Unknown";
523 }
524 });
525 LOG.info("Finished waiting on flush after too many WALs...");
526
527 assertEquals(DefaultMemStore.DEEP_OVERHEAD,
528 desiredRegion.getStore(FAMILY1).getMemStoreSize());
529 assertEquals(DefaultMemStore.DEEP_OVERHEAD,
530 desiredRegion.getStore(FAMILY2).getMemStoreSize());
531 assertEquals(DefaultMemStore.DEEP_OVERHEAD,
532 desiredRegion.getStore(FAMILY3).getMemStoreSize());
533
534 assertNull(getWAL(desiredRegion).rollWriter(true));
535 assertTrue(getNumRolledLogFiles(desiredRegion) < maxLogs);
536 } finally {
537 TEST_UTIL.shutdownMiniCluster();
538 }
539 }
540
541 private void doPut(Table table, long memstoreFlushSize) throws IOException, InterruptedException {
542 Region region = getRegionWithName(table.getName()).getFirst();
543
544 byte[] qf = Bytes.toBytes("qf");
545 Random rand = new Random();
546 byte[] value1 = new byte[100];
547 byte[] value2 = new byte[200];
548 byte[] value3 = new byte[400];
549 for (int i = 0; i < 10000; i++) {
550 Put put = new Put(Bytes.toBytes("row-" + i));
551 rand.setSeed(i);
552 rand.nextBytes(value1);
553 rand.nextBytes(value2);
554 rand.nextBytes(value3);
555 put.addColumn(FAMILY1, qf, value1);
556 put.addColumn(FAMILY2, qf, value2);
557 put.addColumn(FAMILY3, qf, value3);
558 table.put(put);
559
560 while (region.getMemstoreSize() > memstoreFlushSize) {
561 Thread.sleep(100);
562 }
563 }
564 }
565
566
567
568 @Test(timeout = 180000)
569 public void testCompareStoreFileCount() throws Exception {
570 long memstoreFlushSize = 1024L * 1024;
571 Configuration conf = TEST_UTIL.getConfiguration();
572 conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, memstoreFlushSize);
573 conf.set(FlushPolicyFactory.HBASE_FLUSH_POLICY_KEY, FlushAllStoresPolicy.class.getName());
574 conf.setLong(FlushLargeStoresPolicy.HREGION_COLUMNFAMILY_FLUSH_SIZE_LOWER_BOUND, 400 * 1024);
575 conf.setInt(HStore.BLOCKING_STOREFILES_KEY, 10000);
576 conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
577 ConstantSizeRegionSplitPolicy.class.getName());
578
579 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
580 htd.setCompactionEnabled(false);
581 htd.addFamily(new HColumnDescriptor(FAMILY1));
582 htd.addFamily(new HColumnDescriptor(FAMILY2));
583 htd.addFamily(new HColumnDescriptor(FAMILY3));
584
585 LOG.info("==============Test with selective flush disabled===============");
586 int cf1StoreFileCount = -1;
587 int cf2StoreFileCount = -1;
588 int cf3StoreFileCount = -1;
589 int cf1StoreFileCount1 = -1;
590 int cf2StoreFileCount1 = -1;
591 int cf3StoreFileCount1 = -1;
592 try {
593 TEST_UTIL.startMiniCluster(1);
594 TEST_UTIL.getHBaseAdmin().createNamespace(
595 NamespaceDescriptor.create(TABLENAME.getNamespaceAsString()).build());
596 TEST_UTIL.getHBaseAdmin().createTable(htd);
597 TEST_UTIL.waitTableAvailable(TABLENAME);
598 Connection conn = ConnectionFactory.createConnection(conf);
599 Table table = conn.getTable(TABLENAME);
600 doPut(table, memstoreFlushSize);
601 table.close();
602 conn.close();
603
604 Region region = getRegionWithName(TABLENAME).getFirst();
605 cf1StoreFileCount = region.getStore(FAMILY1).getStorefilesCount();
606 cf2StoreFileCount = region.getStore(FAMILY2).getStorefilesCount();
607 cf3StoreFileCount = region.getStore(FAMILY3).getStorefilesCount();
608 } finally {
609 TEST_UTIL.shutdownMiniCluster();
610 }
611
612 LOG.info("==============Test with selective flush enabled===============");
613 conf.set(FlushPolicyFactory.HBASE_FLUSH_POLICY_KEY, FlushLargeStoresPolicy.class.getName());
614 try {
615 TEST_UTIL.startMiniCluster(1);
616 TEST_UTIL.getHBaseAdmin().createNamespace(
617 NamespaceDescriptor.create(TABLENAME.getNamespaceAsString()).build());
618 TEST_UTIL.getHBaseAdmin().createTable(htd);
619 Connection conn = ConnectionFactory.createConnection(conf);
620 Table table = conn.getTable(TABLENAME);
621 doPut(table, memstoreFlushSize);
622 table.close();
623 conn.close();
624
625 region = getRegionWithName(TABLENAME).getFirst();
626 cf1StoreFileCount1 = region.getStore(FAMILY1).getStorefilesCount();
627 cf2StoreFileCount1 = region.getStore(FAMILY2).getStorefilesCount();
628 cf3StoreFileCount1 = region.getStore(FAMILY3).getStorefilesCount();
629 } finally {
630 TEST_UTIL.shutdownMiniCluster();
631 }
632
633 LOG.info("disable selective flush: " + Bytes.toString(FAMILY1) + "=>" + cf1StoreFileCount
634 + ", " + Bytes.toString(FAMILY2) + "=>" + cf2StoreFileCount + ", "
635 + Bytes.toString(FAMILY3) + "=>" + cf3StoreFileCount);
636 LOG.info("enable selective flush: " + Bytes.toString(FAMILY1) + "=>" + cf1StoreFileCount1
637 + ", " + Bytes.toString(FAMILY2) + "=>" + cf2StoreFileCount1 + ", "
638 + Bytes.toString(FAMILY3) + "=>" + cf3StoreFileCount1);
639
640 assertTrue(cf1StoreFileCount1 < cf1StoreFileCount);
641 assertTrue(cf2StoreFileCount1 < cf2StoreFileCount);
642 }
643
644 public static void main(String[] args) throws Exception {
645 int numRegions = Integer.parseInt(args[0]);
646 long numRows = Long.parseLong(args[1]);
647
648 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
649 htd.setMaxFileSize(10L * 1024 * 1024 * 1024);
650 htd.setValue(HTableDescriptor.SPLIT_POLICY, ConstantSizeRegionSplitPolicy.class.getName());
651 htd.addFamily(new HColumnDescriptor(FAMILY1));
652 htd.addFamily(new HColumnDescriptor(FAMILY2));
653 htd.addFamily(new HColumnDescriptor(FAMILY3));
654
655 Configuration conf = HBaseConfiguration.create();
656 Connection conn = ConnectionFactory.createConnection(conf);
657 Admin admin = conn.getAdmin();
658 if (admin.tableExists(TABLENAME)) {
659 admin.disableTable(TABLENAME);
660 admin.deleteTable(TABLENAME);
661 }
662 if (numRegions >= 3) {
663 byte[] startKey = new byte[16];
664 byte[] endKey = new byte[16];
665 Arrays.fill(endKey, (byte) 0xFF);
666 admin.createTable(htd, startKey, endKey, numRegions);
667 } else {
668 admin.createTable(htd);
669 }
670 admin.close();
671
672 Table table = conn.getTable(TABLENAME);
673 byte[] qf = Bytes.toBytes("qf");
674 Random rand = new Random();
675 byte[] value1 = new byte[16];
676 byte[] value2 = new byte[256];
677 byte[] value3 = new byte[4096];
678 for (long i = 0; i < numRows; i++) {
679 Put put = new Put(Hashing.md5().hashLong(i).asBytes());
680 rand.setSeed(i);
681 rand.nextBytes(value1);
682 rand.nextBytes(value2);
683 rand.nextBytes(value3);
684 put.addColumn(FAMILY1, qf, value1);
685 put.addColumn(FAMILY2, qf, value2);
686 put.addColumn(FAMILY3, qf, value3);
687 table.put(put);
688 if (i % 10000 == 0) {
689 LOG.info(i + " rows put");
690 }
691 }
692 table.close();
693 conn.close();
694 }
695 }