HBASE-26830 Rewrite TestLruBlockCache to make it more stable (#4212)
Signed-off-by: Xiaolin Ha <haxiaolin@apache.org>
(cherry picked from commit c3d0cc7040
)
This commit is contained in:
parent
0f93663db5
commit
05627b78ec
|
@ -66,6 +66,8 @@ public class TestLruBlockCache {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(TestLruBlockCache.class);
|
private static final Logger LOG = LoggerFactory.getLogger(TestLruBlockCache.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 TestLruBlockCache {
|
||||||
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 LruBlockCache cache = new LruBlockCache(maxSize, blockSize);
|
final LruBlockCache cache = new LruBlockCache(maxSize, blockSize);
|
||||||
EvictionThread evictionThread = cache.getEvictionThread();
|
EvictionThread evictionThread = cache.getEvictionThread();
|
||||||
assertTrue(evictionThread != null);
|
assertTrue(evictionThread != null);
|
||||||
while (!evictionThread.isEnteringRun()) {
|
Waiter.waitFor(CONF, 10000, 100, () -> evictionThread.isEnteringRun());
|
||||||
Thread.sleep(1);
|
|
||||||
}
|
|
||||||
final String hfileName = "hfile";
|
final String hfileName = "hfile";
|
||||||
int threads = 10;
|
int threads = 10;
|
||||||
final int blocksPerThread = 5 * numBlocks;
|
final int blocksPerThread = 5 * numBlocks;
|
||||||
|
@ -103,7 +102,7 @@ public class TestLruBlockCache {
|
||||||
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;
|
||||||
|
@ -132,9 +131,7 @@ public class TestLruBlockCache {
|
||||||
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(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add all the blocks
|
// Add all the blocks
|
||||||
for (CachedItem block : blocks) {
|
for (CachedItem block : blocks) {
|
||||||
|
@ -142,11 +139,18 @@ public class TestLruBlockCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -155,22 +159,20 @@ public class TestLruBlockCache {
|
||||||
// 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);
|
||||||
|
|
||||||
|
@ -229,7 +231,6 @@ public class TestLruBlockCache {
|
||||||
|
|
||||||
@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);
|
||||||
|
|
||||||
|
@ -269,14 +270,13 @@ public class TestLruBlockCache {
|
||||||
|
|
||||||
@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);
|
||||||
|
|
||||||
LruBlockCache cache = new LruBlockCache(maxSize,blockSize,false);
|
LruBlockCache cache = new LruBlockCache(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();
|
||||||
|
|
||||||
|
@ -328,7 +328,6 @@ public class TestLruBlockCache {
|
||||||
|
|
||||||
@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);
|
||||||
|
|
||||||
|
@ -345,9 +344,9 @@ public class TestLruBlockCache {
|
||||||
false,
|
false,
|
||||||
16 * 1024 * 1024);
|
16 * 1024 * 1024);
|
||||||
|
|
||||||
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();
|
||||||
|
|
||||||
|
@ -574,8 +573,8 @@ public class TestLruBlockCache {
|
||||||
false,
|
false,
|
||||||
16 * 1024 * 1024);
|
16 * 1024 * 1024);
|
||||||
|
|
||||||
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) {
|
||||||
|
@ -584,7 +583,7 @@ public class TestLruBlockCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -607,7 +606,7 @@ public class TestLruBlockCache {
|
||||||
// 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]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,8 +636,8 @@ public class TestLruBlockCache {
|
||||||
1.2f, // limit
|
1.2f, // limit
|
||||||
false,
|
false,
|
||||||
1024);
|
1024);
|
||||||
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) {
|
||||||
|
@ -661,7 +660,6 @@ public class TestLruBlockCache {
|
||||||
// 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);
|
||||||
|
|
||||||
|
@ -678,13 +676,12 @@ public class TestLruBlockCache {
|
||||||
false,
|
false,
|
||||||
16 * 1024 * 1024);
|
16 * 1024 * 1024);
|
||||||
|
|
||||||
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]);
|
||||||
|
|
||||||
|
@ -726,7 +723,7 @@ public class TestLruBlockCache {
|
||||||
// test metricsPastNPeriods
|
// test metricsPastNPeriods
|
||||||
@Test
|
@Test
|
||||||
public void testPastNPeriodsMetrics() throws Exception {
|
public void testPastNPeriodsMetrics() throws Exception {
|
||||||
double delta = 0.01;
|
double delta = 0.01;
|
||||||
|
|
||||||
// 3 total periods
|
// 3 total periods
|
||||||
CacheStats stats = new CacheStats("test", 3);
|
CacheStats stats = new CacheStats("test", 3);
|
||||||
|
@ -874,11 +871,11 @@ public class TestLruBlockCache {
|
||||||
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++) {
|
||||||
|
|
Loading…
Reference in New Issue