From b955fa6c3263e1d5678b2668048f8c5dde083b45 Mon Sep 17 00:00:00 2001 From: Nicolas Spiegelberg Date: Mon, 5 Dec 2011 21:17:47 +0000 Subject: [PATCH] Ability to calculate the blockcache hit ratio for the last few minutes Summary: The metric blockcacheHitRatio is since the beginning of time. It would be nice to calculate the block cache hit ratio for the past few minutes. This patch remembers the blockcacheHitRatio for the last 5 periods by default. Test Plan: unit test attached. Reviewers: jgray, khemani, nspiegelberg, JIRA Reviewed By: nspiegelberg CC: nspiegelberg, dhruba Differential Revision: 585 git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1210640 13f79535-47bb-0310-9956-ffa450edef68 --- .../hadoop/hbase/io/hfile/CacheStats.java | 80 ++++++++++++++++- .../hbase/regionserver/HRegionServer.java | 8 ++ .../metrics/RegionServerMetrics.java | 8 ++ .../hbase/io/hfile/TestLruBlockCache.java | 90 +++++++++++++++++++ 4 files changed, 185 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java b/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java index 538081070ab..439d431d308 100644 --- a/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java +++ b/src/main/java/org/apache/hadoop/hbase/io/hfile/CacheStats.java @@ -25,6 +25,12 @@ import java.util.concurrent.atomic.AtomicLong; * Class that implements cache metrics. */ public class CacheStats { + + /** Sliding window statistics. The number of metric periods to include in + * sliding window hit ratio calculations. + */ + static final int DEFAULT_WINDOW_PERIODS = 5; + /** The number of getBlock requests that were cache hits */ private final AtomicLong hitCount = new AtomicLong(0); /** @@ -46,6 +52,39 @@ public class CacheStats { /** The total number of blocks that have been evicted */ private final AtomicLong evictedBlockCount = new AtomicLong(0); + /** The number of metrics periods to include in window */ + private final int numPeriodsInWindow; + /** Hit counts for each period in window */ + private final long [] hitCounts; + /** Caching hit counts for each period in window */ + private final long [] hitCachingCounts; + /** Access counts for each period in window */ + private final long [] requestCounts; + /** Caching access counts for each period in window */ + private final long [] requestCachingCounts; + /** Last hit count read */ + private long lastHitCount = 0; + /** Last hit caching count read */ + private long lastHitCachingCount = 0; + /** Last request count read */ + private long lastRequestCount = 0; + /** Last request caching count read */ + private long lastRequestCachingCount = 0; + /** Current window index (next to be updated) */ + private int windowIndex = 0; + + public CacheStats() { + this(DEFAULT_WINDOW_PERIODS); + } + + public CacheStats(int numPeriodsInWindow) { + this.numPeriodsInWindow = numPeriodsInWindow; + this.hitCounts = initializeZeros(numPeriodsInWindow); + this.hitCachingCounts = initializeZeros(numPeriodsInWindow); + this.requestCounts = initializeZeros(numPeriodsInWindow); + this.requestCachingCounts = initializeZeros(numPeriodsInWindow); + } + public void miss(boolean caching) { missCount.incrementAndGet(); if (caching) missCachingCount.incrementAndGet(); @@ -115,4 +154,43 @@ public class CacheStats { public double evictedPerEviction() { return ((float)getEvictedCount()/(float)getEvictionCount()); } -} \ No newline at end of file + + public void rollMetricsPeriod() { + hitCounts[windowIndex] = getHitCount() - lastHitCount; + lastHitCount = getHitCount(); + hitCachingCounts[windowIndex] = + getHitCachingCount() - lastHitCachingCount; + lastHitCachingCount = getHitCachingCount(); + requestCounts[windowIndex] = getRequestCount() - lastRequestCount; + lastRequestCount = getRequestCount(); + requestCachingCounts[windowIndex] = + getRequestCachingCount() - lastRequestCachingCount; + lastRequestCachingCount = getRequestCachingCount(); + windowIndex = (windowIndex + 1) % numPeriodsInWindow; + } + + public double getHitRatioPastNPeriods() { + double ratio = ((double)sum(hitCounts)/(double)sum(requestCounts)); + return Double.isNaN(ratio) ? 0 : ratio; + } + + public double getHitCachingRatioPastNPeriods() { + double ratio = + ((double)sum(hitCachingCounts)/(double)sum(requestCachingCounts)); + return Double.isNaN(ratio) ? 0 : ratio; + } + + private static long sum(long [] counts) { + long sum = 0; + for (long count : counts) sum += count; + return sum; + } + + private static long [] initializeZeros(int n) { + long [] zeros = new long [n]; + for (int i=0; i