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.Arrays;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.LongAdder;
import org.apache.hadoop.hbase.metrics.impl.FastLongHistogram;
import org.apache.yetus.audience.InterfaceAudience;
/**
* Class that implements cache metrics.
*/
@InterfaceAudience.Private
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 LongAdder hitCount = new LongAdder();
/** The number of getBlock requests that were cache hits from primary replica */
private final LongAdder primaryHitCount = new LongAdder();
/**
* 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 LongAdder hitCachingCount = new LongAdder();
/** The number of getBlock requests that were cache misses */
private final LongAdder missCount = new LongAdder();
/** The number of getBlock requests for primary replica that were cache misses */
private final LongAdder primaryMissCount = new LongAdder();
/**
* The number of getBlock requests that were cache misses, but only from requests that were set to
* use the block cache.
*/
private final LongAdder missCachingCount = new LongAdder();
/** The number of times an eviction has occurred */
private final LongAdder evictionCount = new LongAdder();
/** The total number of blocks that have been evicted */
private final LongAdder evictedBlockCount = new LongAdder();
/** The total number of blocks for primary replica that have been evicted */
private final LongAdder primaryEvictedBlockCount = new LongAdder();
/** The total number of blocks that were not inserted. */
private final AtomicLong failedInserts = new AtomicLong(0);
/** Per Block Type Counts */
private final LongAdder dataMissCount = new LongAdder();
private final LongAdder leafIndexMissCount = new LongAdder();
private final LongAdder bloomChunkMissCount = new LongAdder();
private final LongAdder metaMissCount = new LongAdder();
private final LongAdder rootIndexMissCount = new LongAdder();
private final LongAdder intermediateIndexMissCount = new LongAdder();
private final LongAdder fileInfoMissCount = new LongAdder();
private final LongAdder generalBloomMetaMissCount = new LongAdder();
private final LongAdder deleteFamilyBloomMissCount = new LongAdder();
private final LongAdder trailerMissCount = new LongAdder();
private final LongAdder dataHitCount = new LongAdder();
private final LongAdder leafIndexHitCount = new LongAdder();
private final LongAdder bloomChunkHitCount = new LongAdder();
private final LongAdder metaHitCount = new LongAdder();
private final LongAdder rootIndexHitCount = new LongAdder();
private final LongAdder intermediateIndexHitCount = new LongAdder();
private final LongAdder fileInfoHitCount = new LongAdder();
private final LongAdder generalBloomMetaHitCount = new LongAdder();
private final LongAdder deleteFamilyBloomHitCount = new LongAdder();
private final LongAdder trailerHitCount = new LongAdder();
/** 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 FastLongHistogram 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 = new long[numPeriodsInWindow];
this.hitCachingCounts = new long[numPeriodsInWindow];
this.requestCounts = new long[numPeriodsInWindow];
this.requestCachingCounts = new long[numPeriodsInWindow];
this.ageAtEviction = new FastLongHistogram();
}
@Override
public String toString() {
AgeSnapshot snapshot = getAgeAtEvictionSnapshot();
return "hitCount=" + getHitCount() + ", hitCachingCount=" + getHitCachingCount()
+ ", missCount=" + getMissCount() + ", missCachingCount=" + getMissCachingCount()
+ ", evictionCount=" + getEvictionCount() + ", evictedBlockCount=" + getEvictedCount()
+ ", primaryMissCount=" + getPrimaryMissCount() + ", primaryHitCount=" + getPrimaryHitCount()
+ ", evictedAgeMean=" + snapshot.getMean();
}
public void miss(boolean caching, boolean primary, BlockType type) {
missCount.increment();
if (primary) primaryMissCount.increment();
if (caching) missCachingCount.increment();
if (type == null) {
return;
}
switch (type) {
case DATA:
case ENCODED_DATA:
dataMissCount.increment();
break;
case LEAF_INDEX:
leafIndexMissCount.increment();
break;
case BLOOM_CHUNK:
bloomChunkMissCount.increment();
break;
case META:
metaMissCount.increment();
break;
case INTERMEDIATE_INDEX:
intermediateIndexMissCount.increment();
break;
case ROOT_INDEX:
rootIndexMissCount.increment();
break;
case FILE_INFO:
fileInfoMissCount.increment();
break;
case GENERAL_BLOOM_META:
generalBloomMetaMissCount.increment();
break;
case DELETE_FAMILY_BLOOM_META:
deleteFamilyBloomMissCount.increment();
break;
case TRAILER:
trailerMissCount.increment();
break;
default:
// If there's a new type that's fine
// Ignore it for now. This is metrics don't exception.
break;
}
}
public void hit(boolean caching, boolean primary, BlockType type) {
hitCount.increment();
if (primary) primaryHitCount.increment();
if (caching) hitCachingCount.increment();
if (type == null) {
return;
}
switch (type) {
case DATA:
case ENCODED_DATA:
dataHitCount.increment();
break;
case LEAF_INDEX:
leafIndexHitCount.increment();
break;
case BLOOM_CHUNK:
bloomChunkHitCount.increment();
break;
case META:
metaHitCount.increment();
break;
case INTERMEDIATE_INDEX:
intermediateIndexHitCount.increment();
break;
case ROOT_INDEX:
rootIndexHitCount.increment();
break;
case FILE_INFO:
fileInfoHitCount.increment();
break;
case GENERAL_BLOOM_META:
generalBloomMetaHitCount.increment();
break;
case DELETE_FAMILY_BLOOM_META:
deleteFamilyBloomHitCount.increment();
break;
case TRAILER:
trailerHitCount.increment();
break;
default:
// If there's a new type that's fine
// Ignore it for now. This is metrics don't exception.
break;
}
}
public void evict() {
evictionCount.increment();
}
public void evicted(final long t, boolean primary) {
if (t > this.startTime) {
this.ageAtEviction.add((t - this.startTime) / BlockCacheUtil.NANOS_PER_SECOND, 1);
}
this.evictedBlockCount.increment();
if (primary) {
primaryEvictedBlockCount.increment();
}
}
public long failInsert() {
return failedInserts.incrementAndGet();
}
// All of the counts of misses and hits.
public long getDataMissCount() {
return dataMissCount.sum();
}
public long getLeafIndexMissCount() {
return leafIndexMissCount.sum();
}
public long getBloomChunkMissCount() {
return bloomChunkMissCount.sum();
}
public long getMetaMissCount() {
return metaMissCount.sum();
}
public long getRootIndexMissCount() {
return rootIndexMissCount.sum();
}
public long getIntermediateIndexMissCount() {
return intermediateIndexMissCount.sum();
}
public long getFileInfoMissCount() {
return fileInfoMissCount.sum();
}
public long getGeneralBloomMetaMissCount() {
return generalBloomMetaMissCount.sum();
}
public long getDeleteFamilyBloomMissCount() {
return deleteFamilyBloomMissCount.sum();
}
public long getTrailerMissCount() {
return trailerMissCount.sum();
}
public long getDataHitCount() {
return dataHitCount.sum();
}
public long getLeafIndexHitCount() {
return leafIndexHitCount.sum();
}
public long getBloomChunkHitCount() {
return bloomChunkHitCount.sum();
}
public long getMetaHitCount() {
return metaHitCount.sum();
}
public long getRootIndexHitCount() {
return rootIndexHitCount.sum();
}
public long getIntermediateIndexHitCount() {
return intermediateIndexHitCount.sum();
}
public long getFileInfoHitCount() {
return fileInfoHitCount.sum();
}
public long getGeneralBloomMetaHitCount() {
return generalBloomMetaHitCount.sum();
}
public long getDeleteFamilyBloomHitCount() {
return deleteFamilyBloomHitCount.sum();
}
public long getTrailerHitCount() {
return trailerHitCount.sum();
}
public long getRequestCount() {
return getHitCount() + getMissCount();
}
public long getRequestCachingCount() {
return getHitCachingCount() + getMissCachingCount();
}
public long getMissCount() {
return missCount.sum();
}
public long getPrimaryMissCount() {
return primaryMissCount.sum();
}
public long getMissCachingCount() {
return missCachingCount.sum();
}
public long getHitCount() {
return hitCount.sum();
}
public long getPrimaryHitCount() {
return primaryHitCount.sum();
}
public long getHitCachingCount() {
return hitCachingCount.sum();
}
public long getEvictionCount() {
return evictionCount.sum();
}
public long getEvictedCount() {
return this.evictedBlockCount.sum();
}
public long getPrimaryEvictedCount() {
return primaryEvictedBlockCount.sum();
}
public double getHitRatio() {
double requestCount = getRequestCount();
if (requestCount == 0) {
return 0;
}
return getHitCount() / requestCount;
}
public double getHitCachingRatio() {
double requestCachingCount = getRequestCachingCount();
if (requestCachingCount == 0) {
return 0;
}
return getHitCachingCount() / requestCachingCount;
}
public double getMissRatio() {
double requestCount = getRequestCount();
if (requestCount == 0) {
return 0;
}
return getMissCount() / requestCount;
}
public double getMissCachingRatio() {
double requestCachingCount = getRequestCachingCount();
if (requestCachingCount == 0) {
return 0;
}
return getMissCachingCount() / requestCachingCount;
}
public double evictedPerEviction() {
double evictionCount = getEvictionCount();
if (evictionCount == 0) {
return 0;
}
return getEvictedCount() / evictionCount;
}
public long getFailedInserts() {
return failedInserts.get();
}
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) getSumHitCountsPastNPeriods() / (double) getSumRequestCountsPastNPeriods());
return Double.isNaN(ratio) ? 0 : ratio;
}
public double getHitCachingRatioPastNPeriods() {
double ratio = ((double) getSumHitCachingCountsPastNPeriods()
/ (double) getSumRequestCachingCountsPastNPeriods());
return Double.isNaN(ratio) ? 0 : ratio;
}
public AgeSnapshot getAgeAtEvictionSnapshot() {
return new AgeSnapshot(this.ageAtEviction);
}
private static long sum(long[] counts) {
return Arrays.stream(counts).sum();
}
}