org.apache.hadoop.hbase.io.hfile.CacheStats Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of hbase-server Show documentation
Show all versions of hbase-server Show documentation
Server functionality for HBase
/**
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.hadoop.hbase.io.hfile;
import java.util.concurrent.atomic.AtomicLong;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import com.yammer.metrics.core.Histogram;
import com.yammer.metrics.core.MetricsRegistry;
/**
* Class that implements cache metrics.
*/
@InterfaceAudience.Private
public class CacheStats {
/**
* Needed making histograms.
*/
private static final MetricsRegistry METRICS = new MetricsRegistry();
/** 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);
/**
* The number of getBlock requests that were cache hits, but only from
* requests that were set to use the block cache. This is because all reads
* attempt to read from the block cache even if they will not put new blocks
* into the block cache. See HBASE-2253 for more information.
*/
private final AtomicLong hitCachingCount = new AtomicLong(0);
/** The number of getBlock requests that were cache misses */
private final AtomicLong missCount = new AtomicLong(0);
/**
* The number of getBlock requests that were cache misses, but only from
* requests that were set to use the block cache.
*/
private final AtomicLong missCachingCount = new AtomicLong(0);
/** The number of times an eviction has occurred */
private final AtomicLong evictionCount = new AtomicLong(0);
/** 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;
/**
* Keep running age at eviction time
*/
private Histogram ageAtEviction;
private long startTime = System.nanoTime();
public CacheStats(final String name) {
this(name, DEFAULT_WINDOW_PERIODS);
}
public CacheStats(final String name, int numPeriodsInWindow) {
this.numPeriodsInWindow = numPeriodsInWindow;
this.hitCounts = initializeZeros(numPeriodsInWindow);
this.hitCachingCounts = initializeZeros(numPeriodsInWindow);
this.requestCounts = initializeZeros(numPeriodsInWindow);
this.requestCachingCounts = initializeZeros(numPeriodsInWindow);
this.ageAtEviction = METRICS.newHistogram(CacheStats.class, name + ".ageAtEviction");
}
@Override
public String toString() {
AgeSnapshot snapshot = getAgeAtEvictionSnapshot();
return "hitCount=" + getHitCount() + ", hitCachingCount=" + getHitCachingCount() +
", missCount=" + getMissCount() + ", missCachingCount=" + getMissCachingCount() +
", evictionCount=" + getEvictionCount() +
", evictedBlockCount=" + getEvictedCount() +
", evictedAgeMean=" + snapshot.getMean() +
", evictedAgeStdDev=" + snapshot.getStdDev();
}
public void miss(boolean caching) {
missCount.incrementAndGet();
if (caching) missCachingCount.incrementAndGet();
}
public void hit(boolean caching) {
hitCount.incrementAndGet();
if (caching) hitCachingCount.incrementAndGet();
}
public void evict() {
evictionCount.incrementAndGet();
}
public void evicted(final long t) {
if (t > this.startTime) this.ageAtEviction.update(t - this.startTime);
this.evictedBlockCount.incrementAndGet();
}
public long getRequestCount() {
return getHitCount() + getMissCount();
}
public long getRequestCachingCount() {
return getHitCachingCount() + getMissCachingCount();
}
public long getMissCount() {
return missCount.get();
}
public long getMissCachingCount() {
return missCachingCount.get();
}
public long getHitCount() {
return hitCount.get();
}
public long getHitCachingCount() {
return hitCachingCount.get();
}
public long getEvictionCount() {
return evictionCount.get();
}
public long getEvictedCount() {
return this.evictedBlockCount.get();
}
public double getHitRatio() {
return ((float)getHitCount()/(float)getRequestCount());
}
public double getHitCachingRatio() {
return ((float)getHitCachingCount()/(float)getRequestCachingCount());
}
public double getMissRatio() {
return ((float)getMissCount()/(float)getRequestCount());
}
public double getMissCachingRatio() {
return ((float)getMissCachingCount()/(float)getRequestCachingCount());
}
public double evictedPerEviction() {
return ((float)getEvictedCount()/(float)getEvictionCount());
}
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 long getSumHitCountsPastNPeriods() {
return sum(hitCounts);
}
public long getSumRequestCountsPastNPeriods() {
return sum(requestCounts);
}
public long getSumHitCachingCountsPastNPeriods() {
return sum(hitCachingCounts);
}
public long getSumRequestCachingCountsPastNPeriods() {
return sum(requestCachingCounts);
}
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;
}
public AgeSnapshot getAgeAtEvictionSnapshot() {
return new AgeSnapshot(this.ageAtEviction);
}
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