2020import static org .apache .hadoop .hbase .HConstants .BUCKET_CACHE_SIZE_KEY ;
2121import static org .apache .hadoop .hbase .io .hfile .bucket .BucketCache .DEFAULT_ERROR_TOLERATION_DURATION ;
2222import static org .junit .Assert .assertEquals ;
23+ import static org .junit .Assert .assertFalse ;
24+ import static org .junit .Assert .assertNull ;
2325import static org .junit .Assert .assertTrue ;
2426import static org .junit .Assert .fail ;
2527
6668import org .junit .ClassRule ;
6769import org .junit .Test ;
6870import org .junit .experimental .categories .Category ;
71+ import org .slf4j .Logger ;
72+ import org .slf4j .LoggerFactory ;
6973
7074/**
7175 * This class is used to test the functionality of the DataTieringManager.
@@ -93,6 +97,7 @@ public class TestDataTieringManager {
9397 public static final HBaseClassTestRule CLASS_RULE =
9498 HBaseClassTestRule .forClass (TestDataTieringManager .class );
9599
100+ private static final Logger LOG = LoggerFactory .getLogger (TestDataTieringManager .class );
96101 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil ();
97102 private static Configuration defaultConf ;
98103 private static FileSystem fs ;
@@ -111,10 +116,11 @@ public static void setupBeforeClass() throws Exception {
111116 defaultConf .setBoolean (CacheConfig .PREFETCH_BLOCKS_ON_OPEN_KEY , true );
112117 defaultConf .setStrings (HConstants .BUCKET_CACHE_IOENGINE_KEY , "offheap" );
113118 defaultConf .setLong (BUCKET_CACHE_SIZE_KEY , 32 );
119+ defaultConf .setBoolean (DataTieringManager .GLOBAL_DATA_TIERING_ENABLED_KEY , true );
114120 fs = HFileSystem .get (defaultConf );
115121 blockCache = BlockCacheFactory .createBlockCache (defaultConf );
116122 cacheConf = new CacheConfig (defaultConf , blockCache );
117- DataTieringManager .instantiate (testOnlineRegions );
123+ assertTrue ( DataTieringManager .instantiate (defaultConf , testOnlineRegions ) );
118124 setupOnlineRegions ();
119125 dataTieringManager = DataTieringManager .getInstance ();
120126 }
@@ -270,9 +276,9 @@ public void testBlockEvictions() throws Exception {
270276 int [] bucketSizes = new int [] { 8 * 1024 + 1024 };
271277
272278 // Setup: Create a bucket cache with lower capacity
273- BucketCache bucketCache = new BucketCache ( "file:" + testDir + "/bucket.cache" , capacitySize ,
274- 8192 , bucketSizes , writeThreads , writerQLen , testDir + "/bucket.persistence" ,
275- DEFAULT_ERROR_TOLERATION_DURATION , defaultConf );
279+ BucketCache bucketCache =
280+ new BucketCache ( "file:" + testDir + "/bucket.cache" , capacitySize , 8192 , bucketSizes ,
281+ writeThreads , writerQLen , null , DEFAULT_ERROR_TOLERATION_DURATION , defaultConf );
276282
277283 // Create three Cache keys with cold data files and a block with hot data.
278284 // hStoreFiles.get(3) is a cold data file, while hStoreFiles.get(0) is a hot file.
@@ -320,9 +326,9 @@ public void testBlockEvictionsAllColdBlocks() throws Exception {
320326 int [] bucketSizes = new int [] { 8 * 1024 + 1024 };
321327
322328 // Setup: Create a bucket cache with lower capacity
323- BucketCache bucketCache = new BucketCache ( "file:" + testDir + "/bucket.cache" , capacitySize ,
324- 8192 , bucketSizes , writeThreads , writerQLen , testDir + "/bucket.persistence" ,
325- DEFAULT_ERROR_TOLERATION_DURATION , defaultConf );
329+ BucketCache bucketCache =
330+ new BucketCache ( "file:" + testDir + "/bucket.cache" , capacitySize , 8192 , bucketSizes ,
331+ writeThreads , writerQLen , null , DEFAULT_ERROR_TOLERATION_DURATION , defaultConf );
326332
327333 // Create three Cache keys with three cold data blocks.
328334 // hStoreFiles.get(3) is a cold data file.
@@ -367,9 +373,9 @@ public void testBlockEvictionsHotBlocks() throws Exception {
367373 int [] bucketSizes = new int [] { 8 * 1024 + 1024 };
368374
369375 // Setup: Create a bucket cache with lower capacity
370- BucketCache bucketCache = new BucketCache ( "file:" + testDir + "/bucket.cache" , capacitySize ,
371- 8192 , bucketSizes , writeThreads , writerQLen , testDir + "/bucket.persistence" ,
372- DEFAULT_ERROR_TOLERATION_DURATION , defaultConf );
376+ BucketCache bucketCache =
377+ new BucketCache ( "file:" + testDir + "/bucket.cache" , capacitySize , 8192 , bucketSizes ,
378+ writeThreads , writerQLen , null , DEFAULT_ERROR_TOLERATION_DURATION , defaultConf );
373379
374380 // Create three Cache keys with two hot data blocks and one cold data block
375381 // hStoreFiles.get(0) is a hot data file and hStoreFiles.get(3) is a cold data file.
@@ -404,11 +410,74 @@ public void testBlockEvictionsHotBlocks() throws Exception {
404410 validateBlocks (bucketCache .getBackingMap ().keySet (), 2 , 2 , 0 );
405411 }
406412
413+ @ Test
414+ public void testFeatureKeyDisabled () throws Exception {
415+ DataTieringManager .resetForTestingOnly ();
416+ defaultConf .setBoolean (DataTieringManager .GLOBAL_DATA_TIERING_ENABLED_KEY , false );
417+ try {
418+ assertFalse (DataTieringManager .instantiate (defaultConf , testOnlineRegions ));
419+ // Verify that the DataaTieringManager instance is not instantiated in the
420+ // instantiate call above.
421+ assertNull (DataTieringManager .getInstance ());
422+
423+ // Also validate that data temperature is not honoured.
424+ long capacitySize = 40 * 1024 ;
425+ int writeThreads = 3 ;
426+ int writerQLen = 64 ;
427+ int [] bucketSizes = new int [] { 8 * 1024 + 1024 };
428+
429+ // Setup: Create a bucket cache with lower capacity
430+ BucketCache bucketCache =
431+ new BucketCache ("file:" + testDir + "/bucket.cache" , capacitySize , 8192 , bucketSizes ,
432+ writeThreads , writerQLen , null , DEFAULT_ERROR_TOLERATION_DURATION , defaultConf );
433+
434+ // Create three Cache keys with two hot data blocks and one cold data block
435+ // hStoreFiles.get(0) is a hot data file and hStoreFiles.get(3) is a cold data file.
436+ List <BlockCacheKey > cacheKeys = new ArrayList <>();
437+ cacheKeys .add (new BlockCacheKey (hStoreFiles .get (0 ).getPath (), 0 , true , BlockType .DATA ));
438+ cacheKeys .add (new BlockCacheKey (hStoreFiles .get (0 ).getPath (), 8192 , true , BlockType .DATA ));
439+ cacheKeys .add (new BlockCacheKey (hStoreFiles .get (3 ).getPath (), 0 , true , BlockType .DATA ));
440+
441+ // Create dummy data to be cached and fill the cache completely.
442+ CacheTestUtils .HFileBlockPair [] blocks = CacheTestUtils .generateHFileBlocks (8192 , 3 );
443+
444+ int blocksIter = 0 ;
445+ for (BlockCacheKey key : cacheKeys ) {
446+ LOG .info ("Adding {}" , key );
447+ bucketCache .cacheBlock (key , blocks [blocksIter ++].getBlock ());
448+ // Ensure that the block is persisted to the file.
449+ Waiter .waitFor (defaultConf , 10000 , 100 ,
450+ () -> (bucketCache .getBackingMap ().containsKey (key )));
451+ }
452+
453+ // Verify that the bucket cache contains 3 blocks.
454+ assertEquals (3 , bucketCache .getBackingMap ().keySet ().size ());
455+
456+ // Add an additional hot block, which triggers eviction.
457+ BlockCacheKey newKey =
458+ new BlockCacheKey (hStoreFiles .get (2 ).getPath (), 0 , true , BlockType .DATA );
459+ CacheTestUtils .HFileBlockPair [] newBlock = CacheTestUtils .generateHFileBlocks (8192 , 1 );
460+
461+ bucketCache .cacheBlock (newKey , newBlock [0 ].getBlock ());
462+ Waiter .waitFor (defaultConf , 10000 , 100 ,
463+ () -> (bucketCache .getBackingMap ().containsKey (newKey )));
464+
465+ // Verify that the bucket still contains the only cold block and one newly added hot block.
466+ // The older hot blocks are evicted and data-tiering mechanism does not kick in to evict
467+ // the cold block.
468+ validateBlocks (bucketCache .getBackingMap ().keySet (), 2 , 1 , 1 );
469+ } finally {
470+ DataTieringManager .resetForTestingOnly ();
471+ defaultConf .setBoolean (DataTieringManager .GLOBAL_DATA_TIERING_ENABLED_KEY , true );
472+ assertTrue (DataTieringManager .instantiate (defaultConf , testOnlineRegions ));
473+ }
474+ }
475+
407476 private void validateBlocks (Set <BlockCacheKey > keys , int expectedTotalKeys , int expectedHotBlocks ,
408477 int expectedColdBlocks ) {
409478 int numHotBlocks = 0 , numColdBlocks = 0 ;
410479
411- assertEquals ( expectedTotalKeys , keys .size ());
480+ Waiter . waitFor ( defaultConf , 10000 , 100 , () -> ( expectedTotalKeys == keys .size () ));
412481 int iter = 0 ;
413482 for (BlockCacheKey key : keys ) {
414483 try {
0 commit comments