HBASE-16157 The incorrect block cache count and size are caused by removing duplicate block key in the LruBlockCache (ChiaPing Tsai)

This commit is contained in:
tedyu 2016-07-01 09:43:39 -07:00
parent bc70dc00bb
commit 5a7c9939cb
2 changed files with 46 additions and 1 deletions

View File

@ -511,7 +511,10 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
* @return the heap size of evicted block * @return the heap size of evicted block
*/ */
protected long evictBlock(LruCachedBlock block, boolean evictedByEvictionProcess) { protected long evictBlock(LruCachedBlock block, boolean evictedByEvictionProcess) {
map.remove(block.getCacheKey()); boolean found = map.remove(block.getCacheKey()) != null;
if (!found) {
return 0;
}
updateSizeMetrics(block, true); updateSizeMetrics(block, true);
long val = elements.decrementAndGet(); long val = elements.decrementAndGet();
if (LOG.isTraceEnabled()) { if (LOG.isTraceEnabled()) {
@ -543,6 +546,16 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
} }
} }
@VisibleForTesting
boolean isEvictionInProgress() {
return evictionInProgress;
}
@VisibleForTesting
long getOverhead() {
return overhead;
}
/** /**
* Eviction method. * Eviction method.
*/ */

View File

@ -44,7 +44,34 @@ import org.junit.experimental.categories.Category;
@Category({IOTests.class, SmallTests.class}) @Category({IOTests.class, SmallTests.class})
public class TestLruBlockCache { public class TestLruBlockCache {
@Test
public void testCurrentSize() throws Exception {
long maxSize = 100000;
int numBlocks = 9;
int testRuns = 10;
long blockSize = calculateBlockSizeDefault(maxSize, numBlocks);
assertTrue("calculateBlockSize appears broken.", blockSize * numBlocks <= maxSize);
LruBlockCache cache = new LruBlockCache(maxSize, blockSize);
EvictionThread evictionThread = cache.getEvictionThread();
assertTrue(evictionThread != null);
while (!evictionThread.isEnteringRun()) {
Thread.sleep(1);
}
int blockCount = 0;
String hfileName = "hfile";
for (int run = 0; run != testRuns; ++run) {
while (!cache.isEvictionInProgress()) {
CachedItem block = new CachedItem(hfileName, (int) blockSize, blockCount++);
boolean inMemory = Math.random() > 0.5;
cache.cacheBlock(block.cacheKey, block, inMemory, false);
}
assertEquals(true, cache.isEvictionInProgress());
cache.evictBlocksByHfileName(hfileName);
assertEquals(0, cache.getBlockCount());
assertEquals(cache.getOverhead(), cache.getCurrentSize());
}
}
@Test @Test
public void testBackgroundEvictionThread() throws Exception { public void testBackgroundEvictionThread() throws Exception {
long maxSize = 100000; long maxSize = 100000;
@ -785,6 +812,11 @@ public class TestLruBlockCache {
BlockCacheKey cacheKey; BlockCacheKey cacheKey;
int size; int size;
CachedItem(String blockName, int size, int offset) {
this.cacheKey = new BlockCacheKey(blockName, offset);
this.size = size;
}
CachedItem(String blockName, int size) { CachedItem(String blockName, int size) {
this.cacheKey = new BlockCacheKey(blockName, 0); this.cacheKey = new BlockCacheKey(blockName, 0);
this.size = size; this.size = size;