commit 67484892827cef330aee089e660db7e4ce12e7c7 Author: Yu Li Date: Mon Jan 25 17:20:03 2016 +0800 HBASE-15162 Add separate metrics for meta/data block hit ratio in cache diff --git a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerSource.java b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerSource.java index 974918ba6f2b5165685ff4b2d6066897d5dc87fa..87c0a2c0a5173aa79493ae1952c420d139489ee9 100644 --- a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerSource.java +++ b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerSource.java @@ -334,4 +334,11 @@ public interface MetricsRegionServerSource extends BaseSource { String FS_PREAD_LATENCY_DESC = "Latency of HFile's positional reads on this region server."; String FS_WRITE_LATENCY = "fsWriteLatency"; String FS_WRITE_LATENCY_DESC = "Latency of HFile's writes on this region server."; + + String BLOCK_CACHE_EXPRESS_META_HIT_PERCENT = "blockCacheExpressMetaHitPercent"; + String BLOCK_CACHE_EXPRESS_META_HIT_PERCENT_DESC = + "The percent of the time that requests with the cache turned on hit the meta cache."; + String BLOCK_CACHE_EXPRESS_DATA_HIT_PERCENT = "blockCacheExpressDataHitPercent"; + String BLOCK_CACHE_EXPRESS_DATA_HIT_PERCENT_DESC = + "The percent of the time that requests with the cache turned on hit the data cache."; } diff --git a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapper.java b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapper.java index a2abf7360cda36cd8589fac63b745bef472f1f92..42249ec74744635329431ce5a8e95c5ebecbda25 100644 --- a/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapper.java +++ b/hbase-hadoop-compat/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapper.java @@ -382,4 +382,14 @@ public interface MetricsRegionServerWrapper { * Get the latency of HFile's writes. */ long getFSWriteLatency(); + + /** + * Get the percent of requests with the block cache turned on that hit the meta block cache. + */ + int getBlockCacheMetaHitCachingPercent(); + + /** + * Get the percent of requests with the block cache turned on that hit the data block cache. + */ + int getBlockCacheDataHitCachingPercent(); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/BlockCache.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/BlockCache.java index cef7e02d45a6e2a1349f4696a59953329fccbdbd..ec13702d9f11699e2abb5209710ddacfcaecb34c 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/BlockCache.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/BlockCache.java @@ -55,11 +55,27 @@ public interface BlockCache extends Iterable { * (used to avoid double counting cache misses when doing double-check locking) * @param updateCacheMetrics Whether to update cache metrics or not * @return Block or null if block is not in 2 cache. + * @deprecated reserved for unit test only, use + * {@link #getBlock(BlockCacheKey, boolean, boolean, boolean, BlockType)} instead */ + @Deprecated Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat, boolean updateCacheMetrics); /** + * Fetch block from cache + * @param cacheKey Block to fetch. + * @param caching Whether this request has caching enabled (used for stats) + * @param repeat Whether this is a repeat lookup for the same block + * (used to avoid double counting cache misses when doing double-check locking) + * @param updateCacheMetrics Whether to update cache metrics or not + * @param blockType block type of {@link HFileBlock} + * @return Block or null if block is not in 2 cache. + */ + Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat, + boolean updateCacheMetrics, BlockType blockType); + + /** * Evict block from cache. * @param cacheKey Block to evict * @return true if block existed and was evicted, false if not diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java index 50e8bbb8b5441b037abd6b8eb4179ae30e97d4b8..3d47a164d34cb7dcac56b17f3645aa8b0916d5aa 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java @@ -56,6 +56,11 @@ public class CacheStats { */ private final AtomicLong hitCachingCount = new AtomicLong(0); + /** meta block hit caching count */ + private final AtomicLong metaHitCachingCount = new AtomicLong(0); + /** data block hit caching count */ + private final AtomicLong dataHitCachingCount = new AtomicLong(0); + /** The number of getBlock requests that were cache misses */ private final AtomicLong missCount = new AtomicLong(0); @@ -67,6 +72,11 @@ public class CacheStats { */ private final AtomicLong missCachingCount = new AtomicLong(0); + /** meta block miss caching count */ + private final AtomicLong metaMissCachingCount = new AtomicLong(0); + /** data block miss caching count */ + private final AtomicLong dataMissCachingCount = new AtomicLong(0); + /** The number of times an eviction has occurred */ private final AtomicLong evictionCount = new AtomicLong(0); @@ -137,6 +147,14 @@ public class CacheStats { if (caching) missCachingCount.incrementAndGet(); } + public void missByBlockType(BlockType bt) { + if (bt.isData()) { + dataMissCachingCount.incrementAndGet(); + } else { + metaMissCachingCount.incrementAndGet(); + } + } + public void hit(boolean caching) { hit(caching, true); } @@ -147,6 +165,14 @@ public class CacheStats { if (caching) hitCachingCount.incrementAndGet(); } + public void hitByBlockType(BlockType bt) { + if (bt.isData()) { + dataHitCachingCount.incrementAndGet(); + } else { + metaHitCachingCount.incrementAndGet(); + } + } + public void evict() { evictionCount.incrementAndGet(); } @@ -290,4 +316,36 @@ public class CacheStats { } return zeros; } + + public long getMetaHitCachingCount() { + return metaHitCachingCount.get(); + } + + public long getDataHitCachingCount() { + return dataHitCachingCount.get(); + } + + public long getMetaMissCachingCount() { + return metaMissCachingCount.get(); + } + + public long getDataMissCachingCount() { + return dataMissCachingCount.get(); + } + + public long getMetaRequestCachingCount() { + return getMetaHitCachingCount() + getMetaMissCachingCount(); + } + + public long getDataRequestCachingCount() { + return getDataHitCachingCount() + getDataMissCachingCount(); + } + + public double getMetaHitCachingRatio() { + return ((float) getMetaHitCachingCount() / (float) getMetaRequestCachingCount()); + } + + public double getDataHitCachingRatio() { + return ((float) getDataHitCachingCount() / (float) getDataRequestCachingCount()); + } } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CombinedBlockCache.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CombinedBlockCache.java index 22bffee6bb8c62668985cd72aad8079c17a11da7..907cd9dd90725f0685ebccd6d1152dbf54332fb1 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CombinedBlockCache.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/CombinedBlockCache.java @@ -79,12 +79,18 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize { @Override public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat, boolean updateCacheMetrics) { + return getBlock(cacheKey, caching, repeat, updateCacheMetrics, null); + } + + @Override + public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, + boolean repeat, boolean updateCacheMetrics, BlockType blockType) { // TODO: is there a hole here, or just awkwardness since in the lruCache getBlock // we end up calling l2Cache.getBlock. if (lruCache.containsBlock(cacheKey)) { - return lruCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics); + return lruCache.getBlock(cacheKey, caching, repeat, updateCacheMetrics, blockType); } - Cacheable result = l2Cache.getBlock(cacheKey, caching, repeat, updateCacheMetrics); + Cacheable result = l2Cache.getBlock(cacheKey, caching, repeat, updateCacheMetrics, blockType); return result; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java index e2c52f597c89e07fd4e82fd6133edd5af37a7bf9..83836795ea46228b711c31448f9e699a0cfe3593 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/HFileReaderImpl.java @@ -1331,7 +1331,7 @@ public class HFileReaderImpl implements HFile.Reader, Configurable { if (cacheConf.isBlockCacheEnabled()) { BlockCache cache = cacheConf.getBlockCache(); HFileBlock cachedBlock = (HFileBlock) cache.getBlock(cacheKey, cacheBlock, useLock, - updateCacheMetrics); + updateCacheMetrics, expectedBlockType); if (cachedBlock != null) { if (cacheConf.shouldCacheCompressed(cachedBlock.getBlockType().getCategory())) { HFileBlock compressedBlock = cachedBlock; diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java index 68ce16c3064ef411b14d3e257784d07bef0553f2..463b57fb5ac5c1f37e5143d5d2fb918b21a04cc6 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/LruBlockCache.java @@ -436,14 +436,36 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize { @Override public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat, boolean updateCacheMetrics) { + return getBlock(cacheKey, caching, repeat, updateCacheMetrics, null); + } + + /** + * Get the buffer of the block with the specified name. + * @param cacheKey block's cache key + * @param caching true if the caller caches blocks on cache misses + * @param repeat Whether this is a repeat lookup for the same block + * (used to avoid double counting cache misses when doing double-check locking) + * @param updateCacheMetrics Whether to update cache metrics or not + * @param blockType block type of {@link HFileBlock} + * @return buffer of specified cache key, or null if not in cache + */ + @Override + public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat, + boolean updateCacheMetrics, BlockType blockType) { LruCachedBlock cb = map.get(cacheKey); if (cb == null) { - if (!repeat && updateCacheMetrics) stats.miss(caching, cacheKey.isPrimary()); + if (!repeat && updateCacheMetrics) { + stats.miss(caching, cacheKey.isPrimary()); + if (null != blockType && caching) { + stats.missByBlockType(blockType); + } + } // If there is another block cache then try and read there. // However if this is a retry ( second time in double checked locking ) // And it's already a miss then the l2 will also be a miss. if (victimHandler != null && !repeat) { - Cacheable result = victimHandler.getBlock(cacheKey, caching, repeat, updateCacheMetrics); + Cacheable result = + victimHandler.getBlock(cacheKey, caching, repeat, updateCacheMetrics, blockType); // Promote this to L1. if (result != null && caching) { @@ -453,7 +475,12 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize { } return null; } - if (updateCacheMetrics) stats.hit(caching, cacheKey.isPrimary()); + if (updateCacheMetrics) { + stats.hit(caching, cacheKey.isPrimary()); + if (null != blockType && caching) { + stats.hitByBlockType(blockType); + } + } cb.access(count.incrementAndGet()); return cb.getBuffer(); } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java index 60249587396ff2196b9993bb5e90baa758d4b48e..0564c606375e7e86be6c9ceba029aaf86cb745c2 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/bucket/BucketCache.java @@ -395,6 +395,21 @@ public class BucketCache implements BlockCache, HeapSize { @Override public Cacheable getBlock(BlockCacheKey key, boolean caching, boolean repeat, boolean updateCacheMetrics) { + return getBlock(key, caching, repeat, updateCacheMetrics, null); + } + + /** + * Get the buffer of the block with the specified key. + * @param key block's cache key + * @param caching true if the caller caches blocks on cache misses + * @param repeat Whether this is a repeat lookup for the same block + * @param updateCacheMetrics Whether we should update cache metrics or not + * @param blockType block type of {@link HFileBlock} + * @return buffer of specified cache key, or null if not in cache + */ + @Override + public Cacheable getBlock(BlockCacheKey key, boolean caching, boolean repeat, + boolean updateCacheMetrics, BlockType blockType) { if (!cacheEnabled) { return null; } @@ -402,6 +417,9 @@ public class BucketCache implements BlockCache, HeapSize { if (re != null) { if (updateCacheMetrics) { cacheStats.hit(caching, key.isPrimary()); + if (null != blockType && caching) { + cacheStats.hitByBlockType(blockType); + } } re.access(accessCount.incrementAndGet()); return re.getData(); @@ -425,6 +443,9 @@ public class BucketCache implements BlockCache, HeapSize { if (updateCacheMetrics) { cacheStats.hit(caching, key.isPrimary()); cacheStats.ioHit(timeTaken); + if (null != blockType && caching) { + cacheStats.hitByBlockType(blockType); + } } if (cachedBlock.getMemoryType() == MemoryType.SHARED) { bucketEntry.refCount.incrementAndGet(); @@ -444,6 +465,9 @@ public class BucketCache implements BlockCache, HeapSize { } if (!repeat && updateCacheMetrics) { cacheStats.miss(caching, key.isPrimary()); + if (null != blockType && caching) { + cacheStats.missByBlockType(blockType); + } } return null; } diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperImpl.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperImpl.java index d39f80ac1b8013a7700850a03a5ac8fe134fda49..f9f939d6c29328992c99cabbfc4105fe9c2bc063 100644 --- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperImpl.java +++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperImpl.java @@ -779,4 +779,20 @@ class MetricsRegionServerWrapperImpl public long getFSWriteLatency() { return fsWriteLatency; } + + @Override + public int getBlockCacheMetaHitCachingPercent() { + if (null == this.cacheStats) { + return 0; + } + return (int) (this.cacheStats.getMetaHitCachingRatio() * 100); + } + + @Override + public int getBlockCacheDataHitCachingPercent() { + if (null == this.cacheStats) { + return 0; + } + return (int) (this.cacheStats.getDataHitCachingRatio() * 100); + } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperStub.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperStub.java index e4c98d1a7870a2a6d7f7024cd54f67eaa0042b96..8992705419bf8435d92def77ff8b781dbbca34c3 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperStub.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/MetricsRegionServerWrapperStub.java @@ -374,4 +374,14 @@ public class MetricsRegionServerWrapperStub implements MetricsRegionServerWrappe public long getFSWriteLatency() { return 410; } + + @Override + public int getBlockCacheMetaHitCachingPercent() { + return 96; + } + + @Override + public int getBlockCacheDataHitCachingPercent() { + return 80; + } } diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHeapMemoryManager.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHeapMemoryManager.java index 5f42a034aaa6eb831f0d7993a4f757d8ab61a7e8..b84c179b0512dae6f988c472f8fa4ce51589d5b0 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHeapMemoryManager.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHeapMemoryManager.java @@ -38,6 +38,7 @@ import org.apache.hadoop.hbase.Waiter; import org.apache.hadoop.hbase.client.ClusterConnection; import org.apache.hadoop.hbase.io.hfile.BlockCache; import org.apache.hadoop.hbase.io.hfile.BlockCacheKey; +import org.apache.hadoop.hbase.io.hfile.BlockType; import org.apache.hadoop.hbase.io.hfile.CacheStats; import org.apache.hadoop.hbase.io.hfile.Cacheable; import org.apache.hadoop.hbase.io.hfile.CachedBlock; @@ -560,6 +561,12 @@ public class TestHeapMemoryManager { } @Override + public Cacheable getBlock(BlockCacheKey cacheKey, boolean caching, boolean repeat, + boolean updateCacheMetrics, BlockType blockType) { + return null; + } + + @Override public boolean evictBlock(BlockCacheKey cacheKey) { stats.evicted(0, cacheKey != null ? cacheKey.isPrimary() : true); return false;