HBASE-26835 Rewrite TestLruAdaptiveBlockCache to make it more stable (#4219)

Signed-off-by: Xiaolin Ha <haxiaolin@apache.org>
(cherry picked from commit 5ad51e8b2b)
This commit is contained in:
Duo Zhang 2022-03-15 20:06:05 +08:00
parent e6879b8fd7
commit 350db514c7
1 changed files with 40 additions and 46 deletions

View File

@ -66,6 +66,8 @@ public class TestLruAdaptiveBlockCache {
private static final Logger LOG = LoggerFactory.getLogger(TestLruAdaptiveBlockCache.class); private static final Logger LOG = LoggerFactory.getLogger(TestLruAdaptiveBlockCache.class);
private static final Configuration CONF = HBaseConfiguration.create();
@Test @Test
public void testCacheEvictionThreadSafe() throws Exception { public void testCacheEvictionThreadSafe() throws Exception {
long maxSize = 100000; long maxSize = 100000;
@ -74,13 +76,10 @@ public class TestLruAdaptiveBlockCache {
final long blockSize = calculateBlockSizeDefault(maxSize, numBlocks); final long blockSize = calculateBlockSizeDefault(maxSize, numBlocks);
assertTrue("calculateBlockSize appears broken.", blockSize * numBlocks <= maxSize); assertTrue("calculateBlockSize appears broken.", blockSize * numBlocks <= maxSize);
final Configuration conf = HBaseConfiguration.create();
final LruAdaptiveBlockCache cache = new LruAdaptiveBlockCache(maxSize, blockSize); final LruAdaptiveBlockCache cache = new LruAdaptiveBlockCache(maxSize, blockSize);
EvictionThread evictionThread = cache.getEvictionThread(); EvictionThread evictionThread = cache.getEvictionThread();
assertNotNull(evictionThread); assertNotNull(evictionThread);
while (!evictionThread.isEnteringRun()) { Waiter.waitFor(CONF, 10000, 100, () -> evictionThread.isEnteringRun());
Thread.sleep(1000);
}
final String hfileName = "hfile"; final String hfileName = "hfile";
int threads = 10; int threads = 10;
final int blocksPerThread = 5 * numBlocks; final int blocksPerThread = 5 * numBlocks;
@ -102,7 +101,7 @@ public class TestLruAdaptiveBlockCache {
service.shutdown(); service.shutdown();
// The test may fail here if the evict thread frees the blocks too fast // The test may fail here if the evict thread frees the blocks too fast
service.awaitTermination(10, TimeUnit.MINUTES); service.awaitTermination(10, TimeUnit.MINUTES);
Waiter.waitFor(conf, 10000, 100, new ExplainingPredicate<Exception>() { Waiter.waitFor(CONF, 10000, 100, new ExplainingPredicate<Exception>() {
@Override @Override
public boolean evaluate() throws Exception { public boolean evaluate() throws Exception {
return cache.getBlockCount() == 0; return cache.getBlockCount() == 0;
@ -133,9 +132,7 @@ public class TestLruAdaptiveBlockCache {
CachedItem[] blocks = generateFixedBlocks(numBlocks + 1, blockSize, "block"); CachedItem[] blocks = generateFixedBlocks(numBlocks + 1, blockSize, "block");
// Make sure eviction thread has entered run method // Make sure eviction thread has entered run method
while (!evictionThread.isEnteringRun()) { Waiter.waitFor(CONF, 10000, 10, () -> evictionThread.isEnteringRun());
Thread.sleep(1);
}
// Add all the blocks // Add all the blocks
for (CachedItem block : blocks) { for (CachedItem block : blocks) {
@ -143,12 +140,19 @@ public class TestLruAdaptiveBlockCache {
} }
// wait until at least one eviction has run // wait until at least one eviction has run
int n = 0; Waiter.waitFor(CONF, 30000, 200, new ExplainingPredicate<Exception>() {
while(cache.getStats().getEvictionCount() == 0) {
Thread.sleep(200); @Override
assertTrue("Eviction never happened.", n++ < 20); public boolean evaluate() throws Exception {
return cache.getStats().getEvictionCount() > 0;
} }
@Override
public String explainFailure() throws Exception {
return "Eviction never happened.";
}
});
// let cache stabilize // let cache stabilize
// On some systems, the cache will run multiple evictions before it attains // On some systems, the cache will run multiple evictions before it attains
// steady-state. For instance, after populating the cache with 10 blocks, // steady-state. For instance, after populating the cache with 10 blocks,
@ -156,22 +160,20 @@ public class TestLruAdaptiveBlockCache {
// evicts another. I think this is due to the delta between minSize and // evicts another. I think this is due to the delta between minSize and
// acceptableSize, combined with variance between object overhead on // acceptableSize, combined with variance between object overhead on
// different environments. // different environments.
n = 0; int n = 0;
for (long prevCnt = 0 /* < number of blocks added */, for (long prevCnt = 0 /* < number of blocks added */, curCnt =
curCnt = cache.getBlockCount(); cache.getBlockCount(); prevCnt != curCnt; prevCnt = curCnt, curCnt = cache.getBlockCount()) {
prevCnt != curCnt; prevCnt = curCnt, curCnt = cache.getBlockCount()) {
Thread.sleep(200); Thread.sleep(200);
assertTrue("Cache never stabilized.", n++ < 20); assertTrue("Cache never stabilized.", n++ < 100);
} }
long evictionCount = cache.getStats().getEvictionCount(); long evictionCount = cache.getStats().getEvictionCount();
assertTrue(evictionCount >= 1); assertTrue(evictionCount >= 1);
System.out.println("Background Evictions run: " + evictionCount); LOG.info("Background Evictions run: {}", evictionCount);
} }
@Test @Test
public void testCacheSimple() throws Exception { public void testCacheSimple() throws Exception {
long maxSize = 1000000; long maxSize = 1000000;
long blockSize = calculateBlockSizeDefault(maxSize, 101); long blockSize = calculateBlockSizeDefault(maxSize, 101);
@ -233,7 +235,6 @@ public class TestLruAdaptiveBlockCache {
@Test @Test
public void testCacheEvictionSimple() throws Exception { public void testCacheEvictionSimple() throws Exception {
long maxSize = 100000; long maxSize = 100000;
long blockSize = calculateBlockSizeDefault(maxSize, 10); long blockSize = calculateBlockSizeDefault(maxSize, 10);
@ -275,14 +276,13 @@ public class TestLruAdaptiveBlockCache {
@Test @Test
public void testCacheEvictionTwoPriorities() throws Exception { public void testCacheEvictionTwoPriorities() throws Exception {
long maxSize = 100000; long maxSize = 100000;
long blockSize = calculateBlockSizeDefault(maxSize, 10); long blockSize = calculateBlockSizeDefault(maxSize, 10);
LruAdaptiveBlockCache cache = new LruAdaptiveBlockCache(maxSize,blockSize,false); LruAdaptiveBlockCache cache = new LruAdaptiveBlockCache(maxSize,blockSize,false);
CachedItem [] singleBlocks = generateFixedBlocks(5, 10000, "single"); CachedItem[] singleBlocks = generateFixedBlocks(5, 10000, "single");
CachedItem [] multiBlocks = generateFixedBlocks(5, 10000, "multi"); CachedItem[] multiBlocks = generateFixedBlocks(5, 10000, "multi");
long expectedCacheSize = cache.heapSize(); long expectedCacheSize = cache.heapSize();
@ -339,7 +339,6 @@ public class TestLruAdaptiveBlockCache {
@Test @Test
public void testCacheEvictionThreePriorities() throws Exception { public void testCacheEvictionThreePriorities() throws Exception {
long maxSize = 100000; long maxSize = 100000;
long blockSize = calculateBlockSize(maxSize, 10); long blockSize = calculateBlockSize(maxSize, 10);
@ -359,9 +358,9 @@ public class TestLruAdaptiveBlockCache {
500, 500,
0.01f); 0.01f);
CachedItem [] singleBlocks = generateFixedBlocks(5, blockSize, "single"); CachedItem[] singleBlocks = generateFixedBlocks(5, blockSize, "single");
CachedItem [] multiBlocks = generateFixedBlocks(5, blockSize, "multi"); CachedItem[] multiBlocks = generateFixedBlocks(5, blockSize, "multi");
CachedItem [] memoryBlocks = generateFixedBlocks(5, blockSize, "memory"); CachedItem[] memoryBlocks = generateFixedBlocks(5, blockSize, "memory");
long expectedCacheSize = cache.heapSize(); long expectedCacheSize = cache.heapSize();
@ -617,8 +616,8 @@ public class TestLruAdaptiveBlockCache {
500, 500,
0.01f); 0.01f);
CachedItem [] singleBlocks = generateFixedBlocks(20, blockSize, "single"); CachedItem[] singleBlocks = generateFixedBlocks(20, blockSize, "single");
CachedItem [] multiBlocks = generateFixedBlocks(5, blockSize, "multi"); CachedItem[] multiBlocks = generateFixedBlocks(5, blockSize, "multi");
// Add 5 multi blocks // Add 5 multi blocks
for (CachedItem block : multiBlocks) { for (CachedItem block : multiBlocks) {
@ -627,7 +626,7 @@ public class TestLruAdaptiveBlockCache {
} }
// Add 5 single blocks // Add 5 single blocks
for(int i=0;i<5;i++) { for (int i = 0; i < 5; i++) {
cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]); cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
} }
@ -654,7 +653,7 @@ public class TestLruAdaptiveBlockCache {
// blocks evicted. Inserting 13 blocks should yield 3 more evictions and // blocks evicted. Inserting 13 blocks should yield 3 more evictions and
// 12 more evicted. // 12 more evicted.
for(int i=5;i<18;i++) { for (int i = 5; i < 18; i++) {
cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]); cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
} }
@ -688,9 +687,8 @@ public class TestLruAdaptiveBlockCache {
500, 500,
0.01f); 0.01f);
CachedItem [] tooLong = generateFixedBlocks(10, 1024+5, "long"); CachedItem[] tooLong = generateFixedBlocks(10, 1024+5, "long");
CachedItem [] small = generateFixedBlocks(15, 600, "small"); CachedItem[] small = generateFixedBlocks(15, 600, "small");
for (CachedItem i:tooLong) { for (CachedItem i:tooLong) {
cache.cacheBlock(i.cacheKey, i); cache.cacheBlock(i.cacheKey, i);
@ -712,7 +710,6 @@ public class TestLruAdaptiveBlockCache {
// test setMaxSize // test setMaxSize
@Test @Test
public void testResizeBlockCache() throws Exception { public void testResizeBlockCache() throws Exception {
long maxSize = 300000; long maxSize = 300000;
long blockSize = calculateBlockSize(maxSize, 31); long blockSize = calculateBlockSize(maxSize, 31);
@ -732,13 +729,12 @@ public class TestLruAdaptiveBlockCache {
500, 500,
0.01f); 0.01f);
CachedItem [] singleBlocks = generateFixedBlocks(10, blockSize, "single"); CachedItem[] singleBlocks = generateFixedBlocks(10, blockSize, "single");
CachedItem [] multiBlocks = generateFixedBlocks(10, blockSize, "multi"); CachedItem[] multiBlocks = generateFixedBlocks(10, blockSize, "multi");
CachedItem [] memoryBlocks = generateFixedBlocks(10, blockSize, "memory"); CachedItem[] memoryBlocks = generateFixedBlocks(10, blockSize, "memory");
// Add all blocks from all priorities // Add all blocks from all priorities
for(int i=0;i<10;i++) { for (int i = 0; i < 10; i++) {
// Just add single blocks // Just add single blocks
cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]); cache.cacheBlock(singleBlocks[i].cacheKey, singleBlocks[i]);
@ -939,11 +935,11 @@ public class TestLruAdaptiveBlockCache {
return blocks; return blocks;
} }
private CachedItem [] generateFixedBlocks(int numBlocks, long size, String pfx) { private CachedItem[] generateFixedBlocks(int numBlocks, long size, String pfx) {
return generateFixedBlocks(numBlocks, (int)size, pfx); return generateFixedBlocks(numBlocks, (int)size, pfx);
} }
private CachedItem [] generateRandomBlocks(int numBlocks, long maxSize) { private CachedItem[] generateRandomBlocks(int numBlocks, long maxSize) {
CachedItem [] blocks = new CachedItem[numBlocks]; CachedItem [] blocks = new CachedItem[numBlocks];
Random rand = ThreadLocalRandom.current(); Random rand = ThreadLocalRandom.current();
for(int i=0;i<numBlocks;i++) { for(int i=0;i<numBlocks;i++) {
@ -1126,9 +1122,7 @@ public class TestLruAdaptiveBlockCache {
EvictionThread evictionThread = cache.getEvictionThread(); EvictionThread evictionThread = cache.getEvictionThread();
assertNotNull(evictionThread); assertNotNull(evictionThread);
while (!evictionThread.isEnteringRun()) { Waiter.waitFor(CONF, 10000, 10, () -> evictionThread.isEnteringRun());
Thread.sleep(1);
}
final String hfileName = "hfile"; final String hfileName = "hfile";
for (int blockIndex = 0; blockIndex <= numBlocks * 3000; ++blockIndex) { for (int blockIndex = 0; blockIndex <= numBlocks * 3000; ++blockIndex) {