HBASE-14314 Metrics for block cache should take region replicas into account

This commit is contained in:
tedyu 2015-09-09 13:32:02 -07:00
parent 2da41e5c9a
commit 00bdf14f96
20 changed files with 205 additions and 35 deletions

View File

@ -207,12 +207,20 @@ public interface MetricsRegionServerSource extends BaseSource {
String BLOCK_CACHE_SIZE_DESC = "Size of the block cache."; String BLOCK_CACHE_SIZE_DESC = "Size of the block cache.";
String BLOCK_CACHE_HIT_COUNT = "blockCacheHitCount"; String BLOCK_CACHE_HIT_COUNT = "blockCacheHitCount";
String BLOCK_CACHE_HIT_COUNT_DESC = "Count of the hit on the block cache."; String BLOCK_CACHE_HIT_COUNT_DESC = "Count of the hit on the block cache.";
String BLOCK_CACHE_PRIMARY_HIT_COUNT = "blockCacheHitCountPrimary";
String BLOCK_CACHE_PRIMARY_HIT_COUNT_DESC = "Count of hit on primary replica in the block cache.";
String BLOCK_CACHE_MISS_COUNT = "blockCacheMissCount"; String BLOCK_CACHE_MISS_COUNT = "blockCacheMissCount";
String BLOCK_COUNT_MISS_COUNT_DESC = String BLOCK_COUNT_MISS_COUNT_DESC =
"Number of requests for a block that missed the block cache."; "Number of requests for a block that missed the block cache.";
String BLOCK_CACHE_PRIMARY_MISS_COUNT = "blockCacheMissCountPrimary";
String BLOCK_COUNT_PRIMARY_MISS_COUNT_DESC =
"Number of requests for a block of primary replica that missed the block cache.";
String BLOCK_CACHE_EVICTION_COUNT = "blockCacheEvictionCount"; String BLOCK_CACHE_EVICTION_COUNT = "blockCacheEvictionCount";
String BLOCK_CACHE_EVICTION_COUNT_DESC = String BLOCK_CACHE_EVICTION_COUNT_DESC =
"Count of the number of blocks evicted from the block cache."; "Count of the number of blocks evicted from the block cache.";
String BLOCK_CACHE_PRIMARY_EVICTION_COUNT = "blockCacheEvictionCountPrimary";
String BLOCK_CACHE_PRIMARY_EVICTION_COUNT_DESC =
"Count of the number of blocks evicted from primary replica in the block cache.";
String BLOCK_CACHE_HIT_PERCENT = "blockCacheCountHitPercent"; String BLOCK_CACHE_HIT_PERCENT = "blockCacheCountHitPercent";
String BLOCK_CACHE_HIT_PERCENT_DESC = String BLOCK_CACHE_HIT_PERCENT_DESC =
"Percent of block cache requests that are hits"; "Percent of block cache requests that are hits";

View File

@ -197,16 +197,32 @@ public interface MetricsRegionServerWrapper {
*/ */
long getBlockCacheHitCount(); long getBlockCacheHitCount();
/**
* Get the count of hits to primary replica in the block cache
*/
long getBlockCachePrimaryHitCount();
/** /**
* Get the count of misses to the block cache. * Get the count of misses to the block cache.
*/ */
long getBlockCacheMissCount(); long getBlockCacheMissCount();
/**
* Get the count of misses to primary replica in the block cache.
*/
long getBlockCachePrimaryMissCount();
/** /**
* Get the number of items evicted from the block cache. * Get the number of items evicted from the block cache.
*/ */
long getBlockCacheEvictedCount(); long getBlockCacheEvictedCount();
/**
* Get the number of items evicted from primary replica in the block cache.
*/
long getBlockCachePrimaryEvictedCount();
/** /**
* Get the percent of all requests that hit the block cache. * Get the percent of all requests that hit the block cache.
*/ */

View File

@ -236,10 +236,16 @@ public class MetricsRegionServerSourceImpl
rsWrap.getBlockCacheSize()) rsWrap.getBlockCacheSize())
.addCounter(Interns.info(BLOCK_CACHE_HIT_COUNT, BLOCK_CACHE_HIT_COUNT_DESC), .addCounter(Interns.info(BLOCK_CACHE_HIT_COUNT, BLOCK_CACHE_HIT_COUNT_DESC),
rsWrap.getBlockCacheHitCount()) rsWrap.getBlockCacheHitCount())
.addCounter(Interns.info(BLOCK_CACHE_PRIMARY_HIT_COUNT,
BLOCK_CACHE_PRIMARY_HIT_COUNT_DESC), rsWrap.getBlockCachePrimaryHitCount())
.addCounter(Interns.info(BLOCK_CACHE_MISS_COUNT, BLOCK_COUNT_MISS_COUNT_DESC), .addCounter(Interns.info(BLOCK_CACHE_MISS_COUNT, BLOCK_COUNT_MISS_COUNT_DESC),
rsWrap.getBlockCacheMissCount()) rsWrap.getBlockCacheMissCount())
.addCounter(Interns.info(BLOCK_CACHE_PRIMARY_MISS_COUNT,
BLOCK_COUNT_PRIMARY_MISS_COUNT_DESC), rsWrap.getBlockCachePrimaryMissCount())
.addCounter(Interns.info(BLOCK_CACHE_EVICTION_COUNT, BLOCK_CACHE_EVICTION_COUNT_DESC), .addCounter(Interns.info(BLOCK_CACHE_EVICTION_COUNT, BLOCK_CACHE_EVICTION_COUNT_DESC),
rsWrap.getBlockCacheEvictedCount()) rsWrap.getBlockCacheEvictedCount())
.addCounter(Interns.info(BLOCK_CACHE_PRIMARY_EVICTION_COUNT,
BLOCK_CACHE_PRIMARY_EVICTION_COUNT_DESC), rsWrap.getBlockCachePrimaryEvictedCount())
.addGauge(Interns.info(BLOCK_CACHE_HIT_PERCENT, BLOCK_CACHE_HIT_PERCENT_DESC), .addGauge(Interns.info(BLOCK_CACHE_HIT_PERCENT, BLOCK_CACHE_HIT_PERCENT_DESC),
rsWrap.getBlockCacheHitPercent()) rsWrap.getBlockCacheHitPercent())
.addGauge(Interns.info(BLOCK_CACHE_EXPRESS_HIT_PERCENT, .addGauge(Interns.info(BLOCK_CACHE_EXPRESS_HIT_PERCENT,

View File

@ -58,6 +58,8 @@ public abstract class AbstractHFileReader
/** Filled when we read in the trailer. */ /** Filled when we read in the trailer. */
protected final Compression.Algorithm compressAlgo; protected final Compression.Algorithm compressAlgo;
private boolean isPrimaryReplicaReader;
/** /**
* What kind of data block encoding should be used while reading, writing, * What kind of data block encoding should be used while reading, writing,
* and handling cache. * and handling cache.
@ -251,6 +253,15 @@ public abstract class AbstractHFileReader
} }
@Override @Override
public boolean isPrimaryReplicaReader() {
return isPrimaryReplicaReader;
}
@Override
public void setPrimaryReplicaReader(boolean isPrimaryReplicaReader) {
this.isPrimaryReplicaReader = isPrimaryReplicaReader;
}
public FileInfo loadFileInfo() throws IOException { public FileInfo loadFileInfo() throws IOException {
return fileInfo; return fileInfo;
} }

View File

@ -30,6 +30,7 @@ public class BlockCacheKey implements HeapSize, java.io.Serializable {
private static final long serialVersionUID = -5199992013113130534L; private static final long serialVersionUID = -5199992013113130534L;
private final String hfileName; private final String hfileName;
private final long offset; private final long offset;
private final boolean isPrimaryReplicaBlock;
/** /**
* Construct a new BlockCacheKey * Construct a new BlockCacheKey
@ -37,6 +38,11 @@ public class BlockCacheKey implements HeapSize, java.io.Serializable {
* @param offset Offset of the block into the file * @param offset Offset of the block into the file
*/ */
public BlockCacheKey(String hfileName, long offset) { public BlockCacheKey(String hfileName, long offset) {
this(hfileName, offset, true);
}
public BlockCacheKey(String hfileName, long offset, boolean isPrimaryReplica) {
this.isPrimaryReplicaBlock = isPrimaryReplica;
this.hfileName = hfileName; this.hfileName = hfileName;
this.offset = offset; this.offset = offset;
} }
@ -63,7 +69,7 @@ public class BlockCacheKey implements HeapSize, java.io.Serializable {
return String.format("%s_%d", hfileName, offset); return String.format("%s_%d", hfileName, offset);
} }
public static final long FIXED_OVERHEAD = ClassSize.align(ClassSize.OBJECT + public static final long FIXED_OVERHEAD = ClassSize.align(ClassSize.OBJECT +Bytes.SIZEOF_BOOLEAN +
ClassSize.REFERENCE + // this.hfileName ClassSize.REFERENCE + // this.hfileName
Bytes.SIZEOF_LONG); // this.offset Bytes.SIZEOF_LONG); // this.offset
@ -85,6 +91,10 @@ public class BlockCacheKey implements HeapSize, java.io.Serializable {
return hfileName; return hfileName;
} }
public boolean isPrimary() {
return isPrimaryReplicaBlock;
}
public long getOffset() { public long getOffset() {
return offset; return offset;
} }

View File

@ -43,6 +43,9 @@ public class CacheStats {
/** The number of getBlock requests that were cache hits */ /** The number of getBlock requests that were cache hits */
private final AtomicLong hitCount = new AtomicLong(0); private final AtomicLong hitCount = new AtomicLong(0);
/** The number of getBlock requests that were cache hits from primary replica */
private final AtomicLong primaryHitCount = new AtomicLong(0);
/** /**
* The number of getBlock requests that were cache hits, but only from * 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 * requests that were set to use the block cache. This is because all reads
@ -54,6 +57,8 @@ public class CacheStats {
/** The number of getBlock requests that were cache misses */ /** The number of getBlock requests that were cache misses */
private final AtomicLong missCount = new AtomicLong(0); private final AtomicLong missCount = new AtomicLong(0);
/** The number of getBlock requests for primary replica that were cache misses */
private final AtomicLong primaryMissCount = new AtomicLong(0);
/** /**
* The number of getBlock requests that were cache misses, but only from * The number of getBlock requests that were cache misses, but only from
* requests that were set to use the block cache. * requests that were set to use the block cache.
@ -66,6 +71,9 @@ public class CacheStats {
/** The total number of blocks that have been evicted */ /** The total number of blocks that have been evicted */
private final AtomicLong evictedBlockCount = new AtomicLong(0); private final AtomicLong evictedBlockCount = new AtomicLong(0);
/** The total number of blocks for primary replica that have been evicted */
private final AtomicLong primaryEvictedBlockCount = new AtomicLong(0);
/** The number of metrics periods to include in window */ /** The number of metrics periods to include in window */
private final int numPeriodsInWindow; private final int numPeriodsInWindow;
/** Hit counts for each period in window */ /** Hit counts for each period in window */
@ -112,17 +120,25 @@ public class CacheStats {
", missCount=" + getMissCount() + ", missCachingCount=" + getMissCachingCount() + ", missCount=" + getMissCount() + ", missCachingCount=" + getMissCachingCount() +
", evictionCount=" + getEvictionCount() + ", evictionCount=" + getEvictionCount() +
", evictedBlockCount=" + getEvictedCount() + ", evictedBlockCount=" + getEvictedCount() +
", primaryMissCount=" + getPrimaryMissCount() +
", primaryHitCount=" + getPrimaryHitCount() +
", evictedAgeMean=" + snapshot.getMean() + ", evictedAgeMean=" + snapshot.getMean() +
", evictedAgeStdDev=" + snapshot.getStdDev(); ", evictedAgeStdDev=" + snapshot.getStdDev();
} }
public void miss(boolean caching) { public void miss(boolean caching, boolean primary) {
missCount.incrementAndGet(); missCount.incrementAndGet();
if (primary) primaryMissCount.incrementAndGet();
if (caching) missCachingCount.incrementAndGet(); if (caching) missCachingCount.incrementAndGet();
} }
public void hit(boolean caching) { public void hit(boolean caching) {
hit(caching, true);
}
public void hit(boolean caching, boolean primary) {
hitCount.incrementAndGet(); hitCount.incrementAndGet();
if (primary) primaryHitCount.incrementAndGet();
if (caching) hitCachingCount.incrementAndGet(); if (caching) hitCachingCount.incrementAndGet();
} }
@ -130,9 +146,12 @@ public class CacheStats {
evictionCount.incrementAndGet(); evictionCount.incrementAndGet();
} }
public void evicted(final long t) { public void evicted(final long t, boolean primary) {
if (t > this.startTime) this.ageAtEviction.update(t - this.startTime); if (t > this.startTime) this.ageAtEviction.update(t - this.startTime);
this.evictedBlockCount.incrementAndGet(); this.evictedBlockCount.incrementAndGet();
if (primary) {
primaryEvictedBlockCount.incrementAndGet();
}
} }
public long getRequestCount() { public long getRequestCount() {
@ -147,6 +166,10 @@ public class CacheStats {
return missCount.get(); return missCount.get();
} }
public long getPrimaryMissCount() {
return primaryMissCount.get();
}
public long getMissCachingCount() { public long getMissCachingCount() {
return missCachingCount.get(); return missCachingCount.get();
} }
@ -155,6 +178,10 @@ public class CacheStats {
return hitCount.get(); return hitCount.get();
} }
public long getPrimaryHitCount() {
return primaryHitCount.get();
}
public long getHitCachingCount() { public long getHitCachingCount() {
return hitCachingCount.get(); return hitCachingCount.get();
} }
@ -167,6 +194,10 @@ public class CacheStats {
return this.evictedBlockCount.get(); return this.evictedBlockCount.get();
} }
public long getPrimaryEvictedCount() {
return primaryEvictedBlockCount.get();
}
public double getHitRatio() { public double getHitRatio() {
return ((float)getHitCount()/(float)getRequestCount()); return ((float)getHitCount()/(float)getRequestCount());
} }

View File

@ -129,7 +129,7 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
return lruCache.getBlockCount() + l2Cache.getBlockCount(); return lruCache.getBlockCount() + l2Cache.getBlockCount();
} }
private static class CombinedCacheStats extends CacheStats { public static class CombinedCacheStats extends CacheStats {
private final CacheStats lruCacheStats; private final CacheStats lruCacheStats;
private final CacheStats bucketCacheStats; private final CacheStats bucketCacheStats;
@ -156,6 +156,11 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
return lruCacheStats.getMissCount() + bucketCacheStats.getMissCount(); return lruCacheStats.getMissCount() + bucketCacheStats.getMissCount();
} }
@Override
public long getPrimaryMissCount() {
return lruCacheStats.getPrimaryMissCount() + bucketCacheStats.getPrimaryMissCount();
}
@Override @Override
public long getMissCachingCount() { public long getMissCachingCount() {
return lruCacheStats.getMissCachingCount() return lruCacheStats.getMissCachingCount()
@ -167,6 +172,10 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
return lruCacheStats.getHitCount() + bucketCacheStats.getHitCount(); return lruCacheStats.getHitCount() + bucketCacheStats.getHitCount();
} }
@Override
public long getPrimaryHitCount() {
return lruCacheStats.getPrimaryHitCount() + bucketCacheStats.getPrimaryHitCount();
}
@Override @Override
public long getHitCachingCount() { public long getHitCachingCount() {
return lruCacheStats.getHitCachingCount() return lruCacheStats.getHitCachingCount()
@ -185,6 +194,12 @@ public class CombinedBlockCache implements ResizableBlockCache, HeapSize {
+ bucketCacheStats.getEvictedCount(); + bucketCacheStats.getEvictedCount();
} }
@Override
public long getPrimaryEvictedCount() {
return lruCacheStats.getPrimaryEvictedCount()
+ bucketCacheStats.getPrimaryEvictedCount();
}
@Override @Override
public double getHitRatioPastNPeriods() { public double getHitRatioPastNPeriods() {
double ratio = ((double) (lruCacheStats.getSumHitCountsPastNPeriods() + bucketCacheStats double ratio = ((double) (lruCacheStats.getSumHitCountsPastNPeriods() + bucketCacheStats

View File

@ -450,6 +450,10 @@ public class HFile {
* Return the file context of the HFile this reader belongs to * Return the file context of the HFile this reader belongs to
*/ */
HFileContext getFileContext(); HFileContext getFileContext();
boolean isPrimaryReplicaReader();
void setPrimaryReplicaReader(boolean isPrimaryReplicaReader);
} }
/** /**

View File

@ -341,7 +341,8 @@ public class HFileReaderV2 extends AbstractHFileReader {
synchronized (metaBlockIndexReader.getRootBlockKey(block)) { synchronized (metaBlockIndexReader.getRootBlockKey(block)) {
// Check cache for block. If found return. // Check cache for block. If found return.
long metaBlockOffset = metaBlockIndexReader.getRootBlockOffset(block); long metaBlockOffset = metaBlockIndexReader.getRootBlockOffset(block);
BlockCacheKey cacheKey = new BlockCacheKey(name, metaBlockOffset); BlockCacheKey cacheKey = new BlockCacheKey(name, metaBlockOffset,
this.isPrimaryReplicaReader());
cacheBlock &= cacheConf.shouldCacheDataOnRead(); cacheBlock &= cacheConf.shouldCacheDataOnRead();
if (cacheConf.isBlockCacheEnabled()) { if (cacheConf.isBlockCacheEnabled()) {
@ -387,7 +388,7 @@ public class HFileReaderV2 extends AbstractHFileReader {
// Without a cache, this synchronizing is needless overhead, but really // Without a cache, this synchronizing is needless overhead, but really
// the other choice is to duplicate work (which the cache would prevent you // the other choice is to duplicate work (which the cache would prevent you
// from doing). // from doing).
BlockCacheKey cacheKey = new BlockCacheKey(name, dataBlockOffset); BlockCacheKey cacheKey = new BlockCacheKey(name, dataBlockOffset,this.isPrimaryReplicaReader());
boolean useLock = false; boolean useLock = false;
IdLock.Entry lockEntry = null; IdLock.Entry lockEntry = null;
TraceScope traceScope = Trace.startSpan("HFileReaderV2.readBlock"); TraceScope traceScope = Trace.startSpan("HFileReaderV2.readBlock");

View File

@ -419,7 +419,7 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
boolean updateCacheMetrics) { boolean updateCacheMetrics) {
LruCachedBlock cb = map.get(cacheKey); LruCachedBlock cb = map.get(cacheKey);
if (cb == null) { if (cb == null) {
if (!repeat && updateCacheMetrics) stats.miss(caching); if (!repeat && updateCacheMetrics) stats.miss(caching, cacheKey.isPrimary());
// If there is another block cache then try and read there. // If there is another block cache then try and read there.
// However if this is a retry ( second time in double checked locking ) // 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. // And it's already a miss then the l2 will also be a miss.
@ -434,7 +434,7 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
} }
return null; return null;
} }
if (updateCacheMetrics) stats.hit(caching); if (updateCacheMetrics) stats.hit(caching, cacheKey.isPrimary());
cb.access(count.incrementAndGet()); cb.access(count.incrementAndGet());
return cb.getBuffer(); return cb.getBuffer();
} }
@ -497,7 +497,7 @@ public class LruBlockCache implements ResizableBlockCache, HeapSize {
long size = map.size(); long size = map.size();
assertCounterSanity(size, val); assertCounterSanity(size, val);
} }
stats.evicted(block.getCachedTime()); stats.evicted(block.getCachedTime(), block.getCacheKey().isPrimary());
if (evictedByEvictionProcess && victimHandler != null) { if (evictedByEvictionProcess && victimHandler != null) {
if (victimHandler instanceof BucketCache) { if (victimHandler instanceof BucketCache) {
boolean wait = getCurrentSize() < acceptableSize(); boolean wait = getCurrentSize() < acceptableSize();

View File

@ -145,9 +145,9 @@ public class MemcachedBlockCache implements BlockCache {
// Update stats if this request doesn't have it turned off 100% of the time // Update stats if this request doesn't have it turned off 100% of the time
if (updateCacheMetrics) { if (updateCacheMetrics) {
if (result == null) { if (result == null) {
cacheStats.miss(caching); cacheStats.miss(caching, cacheKey.isPrimary());
} else { } else {
cacheStats.hit(caching); cacheStats.hit(caching, cacheKey.isPrimary());
} }
} }
} }

View File

@ -401,7 +401,7 @@ public class BucketCache implements BlockCache, HeapSize {
RAMQueueEntry re = ramCache.get(key); RAMQueueEntry re = ramCache.get(key);
if (re != null) { if (re != null) {
if (updateCacheMetrics) { if (updateCacheMetrics) {
cacheStats.hit(caching); cacheStats.hit(caching, key.isPrimary());
} }
re.access(accessCount.incrementAndGet()); re.access(accessCount.incrementAndGet());
return re.getData(); return re.getData();
@ -427,7 +427,7 @@ public class BucketCache implements BlockCache, HeapSize {
Cacheable cachedBlock = deserializer.deserialize(bb, true); Cacheable cachedBlock = deserializer.deserialize(bb, true);
long timeTaken = System.nanoTime() - start; long timeTaken = System.nanoTime() - start;
if (updateCacheMetrics) { if (updateCacheMetrics) {
cacheStats.hit(caching); cacheStats.hit(caching, key.isPrimary());
cacheStats.ioHit(timeTaken); cacheStats.ioHit(timeTaken);
} }
bucketEntry.access(accessCount.incrementAndGet()); bucketEntry.access(accessCount.incrementAndGet());
@ -446,7 +446,7 @@ public class BucketCache implements BlockCache, HeapSize {
} }
} }
if (!repeat && updateCacheMetrics) { if (!repeat && updateCacheMetrics) {
cacheStats.miss(caching); cacheStats.miss(caching, key.isPrimary());
} }
return null; return null;
} }
@ -474,7 +474,7 @@ public class BucketCache implements BlockCache, HeapSize {
BucketEntry bucketEntry = backingMap.get(cacheKey); BucketEntry bucketEntry = backingMap.get(cacheKey);
if (bucketEntry == null) { if (bucketEntry == null) {
if (removedBlock != null) { if (removedBlock != null) {
cacheStats.evicted(0); cacheStats.evicted(0, cacheKey.isPrimary());
return true; return true;
} else { } else {
return false; return false;
@ -496,7 +496,7 @@ public class BucketCache implements BlockCache, HeapSize {
offsetLock.releaseLockEntry(lockEntry); offsetLock.releaseLockEntry(lockEntry);
} }
} }
cacheStats.evicted(bucketEntry.getCachedTime()); cacheStats.evicted(bucketEntry.getCachedTime(), cacheKey.isPrimary());
return true; return true;
} }

View File

@ -599,7 +599,8 @@ public class HStore implements Store {
if (newFiles == null) newFiles = new ArrayList<StoreFileInfo>(0); if (newFiles == null) newFiles = new ArrayList<StoreFileInfo>(0);
HashMap<StoreFileInfo, StoreFile> currentFilesSet = new HashMap<StoreFileInfo, StoreFile>(currentFiles.size()); HashMap<StoreFileInfo, StoreFile> currentFilesSet =
new HashMap<StoreFileInfo, StoreFile>(currentFiles.size());
for (StoreFile sf : currentFiles) { for (StoreFile sf : currentFiles) {
currentFilesSet.put(sf.getFileInfo(), sf); currentFilesSet.put(sf.getFileInfo(), sf);
} }
@ -647,7 +648,8 @@ public class HStore implements Store {
info.setRegionCoprocessorHost(this.region.getCoprocessorHost()); info.setRegionCoprocessorHost(this.region.getCoprocessorHost());
StoreFile storeFile = new StoreFile(this.getFileSystem(), info, this.conf, this.cacheConf, StoreFile storeFile = new StoreFile(this.getFileSystem(), info, this.conf, this.cacheConf,
this.family.getBloomFilterType()); this.family.getBloomFilterType());
storeFile.createReader(); StoreFile.Reader r = storeFile.createReader();
r.setReplicaStoreFile(isPrimaryReplicaStore());
return storeFile; return storeFile;
} }
@ -1114,7 +1116,7 @@ public class HStore implements Store {
// but now we get them in ascending order, which I think is // but now we get them in ascending order, which I think is
// actually more correct, since memstore get put at the end. // actually more correct, since memstore get put at the end.
List<StoreFileScanner> sfScanners = StoreFileScanner.getScannersForStoreFiles(storeFilesToScan, List<StoreFileScanner> sfScanners = StoreFileScanner.getScannersForStoreFiles(storeFilesToScan,
cacheBlocks, usePread, isCompaction, false, matcher, readPt); cacheBlocks, usePread, isCompaction, false, matcher, readPt, isPrimaryReplicaStore());
List<KeyValueScanner> scanners = List<KeyValueScanner> scanners =
new ArrayList<KeyValueScanner>(sfScanners.size()+1); new ArrayList<KeyValueScanner>(sfScanners.size()+1);
scanners.addAll(sfScanners); scanners.addAll(sfScanners);
@ -2405,4 +2407,9 @@ public class HStore implements Store {
public double getCompactionPressure() { public double getCompactionPressure() {
return storeEngine.getStoreFileManager().getCompactionPressure(); return storeEngine.getStoreFileManager().getCompactionPressure();
} }
@Override
public boolean isPrimaryReplicaStore() {
return getRegionInfo().getReplicaId() == HRegionInfo.DEFAULT_REPLICA_ID;
}
} }

View File

@ -245,6 +245,14 @@ class MetricsRegionServerWrapperImpl
return this.cacheStats.getHitCount(); return this.cacheStats.getHitCount();
} }
@Override
public long getBlockCachePrimaryHitCount() {
if (this.cacheStats == null) {
return 0;
}
return this.cacheStats.getPrimaryHitCount();
}
@Override @Override
public long getBlockCacheMissCount() { public long getBlockCacheMissCount() {
if (this.cacheStats == null) { if (this.cacheStats == null) {
@ -253,6 +261,14 @@ class MetricsRegionServerWrapperImpl
return this.cacheStats.getMissCount(); return this.cacheStats.getMissCount();
} }
@Override
public long getBlockCachePrimaryMissCount() {
if (this.cacheStats == null) {
return 0;
}
return this.cacheStats.getPrimaryMissCount();
}
@Override @Override
public long getBlockCacheEvictedCount() { public long getBlockCacheEvictedCount() {
if (this.cacheStats == null) { if (this.cacheStats == null) {
@ -261,6 +277,14 @@ class MetricsRegionServerWrapperImpl
return this.cacheStats.getEvictedCount(); return this.cacheStats.getEvictedCount();
} }
@Override
public long getBlockCachePrimaryEvictedCount() {
if (this.cacheStats == null) {
return 0;
}
return this.cacheStats.getPrimaryEvictedCount();
}
@Override @Override
public double getBlockCacheHitPercent() { public double getBlockCacheHitPercent() {
if (this.cacheStats == null) { if (this.cacheStats == null) {

View File

@ -105,7 +105,7 @@ public interface Store extends HeapSize, StoreConfigInformation, PropagatingConf
byte[] stopRow, byte[] stopRow,
long readPt long readPt
) throws IOException; ) throws IOException;
ScanInfo getScanInfo(); ScanInfo getScanInfo();
/** /**
@ -464,4 +464,6 @@ public interface Store extends HeapSize, StoreConfigInformation, PropagatingConf
void refreshStoreFiles(Collection<String> newFiles) throws IOException; void refreshStoreFiles(Collection<String> newFiles) throws IOException;
void bulkLoadHFile(StoreFileInfo fileInfo) throws IOException; void bulkLoadHFile(StoreFileInfo fileInfo) throws IOException;
boolean isPrimaryReplicaStore();
} }

View File

@ -1055,6 +1055,13 @@ public class StoreFile {
bloomFilterType = BloomType.NONE; bloomFilterType = BloomType.NONE;
} }
public void setReplicaStoreFile(boolean isPrimaryReplicaStoreFile) {
reader.setPrimaryReplicaReader(isPrimaryReplicaStoreFile);
}
public boolean isPrimaryReplicaReader() {
return reader.isPrimaryReplicaReader();
}
/** /**
* ONLY USE DEFAULT CONSTRUCTOR FOR UNIT TESTS * ONLY USE DEFAULT CONSTRUCTOR FOR UNIT TESTS
*/ */

View File

@ -81,6 +81,10 @@ public class StoreFileScanner implements KeyValueScanner {
this.hasMVCCInfo = hasMVCC; this.hasMVCCInfo = hasMVCC;
} }
boolean isPrimaryReplica() {
return reader.isPrimaryReplicaReader();
}
/** /**
* Return an array of scanners corresponding to the given * Return an array of scanners corresponding to the given
* set of store files. * set of store files.
@ -111,11 +115,12 @@ public class StoreFileScanner implements KeyValueScanner {
public static List<StoreFileScanner> getScannersForStoreFiles( public static List<StoreFileScanner> getScannersForStoreFiles(
Collection<StoreFile> files, boolean cacheBlocks, boolean usePread, Collection<StoreFile> files, boolean cacheBlocks, boolean usePread,
boolean isCompaction, boolean canUseDrop, boolean isCompaction, boolean canUseDrop,
ScanQueryMatcher matcher, long readPt) throws IOException { ScanQueryMatcher matcher, long readPt, boolean isPrimaryReplica) throws IOException {
List<StoreFileScanner> scanners = new ArrayList<StoreFileScanner>( List<StoreFileScanner> scanners = new ArrayList<StoreFileScanner>(
files.size()); files.size());
for (StoreFile file : files) { for (StoreFile file : files) {
StoreFile.Reader r = file.createReader(canUseDrop); StoreFile.Reader r = file.createReader(canUseDrop);
r.setReplicaStoreFile(isPrimaryReplica);
StoreFileScanner scanner = r.getStoreFileScanner(cacheBlocks, usePread, StoreFileScanner scanner = r.getStoreFileScanner(cacheBlocks, usePread,
isCompaction, readPt); isCompaction, readPt);
scanner.setScanQueryMatcher(matcher); scanner.setScanQueryMatcher(matcher);
@ -124,6 +129,14 @@ public class StoreFileScanner implements KeyValueScanner {
return scanners; return scanners;
} }
public static List<StoreFileScanner> getScannersForStoreFiles(
Collection<StoreFile> files, boolean cacheBlocks, boolean usePread,
boolean isCompaction, boolean canUseDrop,
ScanQueryMatcher matcher, long readPt) throws IOException {
return getScannersForStoreFiles(files, cacheBlocks, usePread, isCompaction, canUseDrop,
matcher, readPt, true);
}
public String toString() { public String toString() {
return "StoreFileScanner[" + hfs.toString() + ", cur=" + cur + "]"; return "StoreFileScanner[" + hfs.toString() + ", cur=" + cur + "]";
} }

View File

@ -618,18 +618,18 @@ public class TestLruBlockCache {
// should be (2/4)=0.5 and (1/1)=1 // should be (2/4)=0.5 and (1/1)=1
stats.hit(false); stats.hit(false);
stats.hit(true); stats.hit(true);
stats.miss(false); stats.miss(false, false);
stats.miss(false); stats.miss(false, false);
stats.rollMetricsPeriod(); stats.rollMetricsPeriod();
assertEquals(0.5, stats.getHitRatioPastNPeriods(), delta); assertEquals(0.5, stats.getHitRatioPastNPeriods(), delta);
assertEquals(1.0, stats.getHitCachingRatioPastNPeriods(), delta); assertEquals(1.0, stats.getHitCachingRatioPastNPeriods(), delta);
// period 2, 1 miss caching, 3 miss non-caching // period 2, 1 miss caching, 3 miss non-caching
// should be (2/8)=0.25 and (1/2)=0.5 // should be (2/8)=0.25 and (1/2)=0.5
stats.miss(true); stats.miss(true, false);
stats.miss(false); stats.miss(false, false);
stats.miss(false); stats.miss(false, false);
stats.miss(false); stats.miss(false, false);
stats.rollMetricsPeriod(); stats.rollMetricsPeriod();
assertEquals(0.25, stats.getHitRatioPastNPeriods(), delta); assertEquals(0.25, stats.getHitRatioPastNPeriods(), delta);
assertEquals(0.5, stats.getHitCachingRatioPastNPeriods(), delta); assertEquals(0.5, stats.getHitCachingRatioPastNPeriods(), delta);
@ -646,16 +646,16 @@ public class TestLruBlockCache {
// period 4, evict period 1, two caching misses // period 4, evict period 1, two caching misses
// should be (4/10)=0.4 and (2/5)=0.4 // should be (4/10)=0.4 and (2/5)=0.4
stats.miss(true); stats.miss(true, false);
stats.miss(true); stats.miss(true, false);
stats.rollMetricsPeriod(); stats.rollMetricsPeriod();
assertEquals(0.4, stats.getHitRatioPastNPeriods(), delta); assertEquals(0.4, stats.getHitRatioPastNPeriods(), delta);
assertEquals(0.4, stats.getHitCachingRatioPastNPeriods(), delta); assertEquals(0.4, stats.getHitCachingRatioPastNPeriods(), delta);
// period 5, evict period 2, 2 caching misses, 2 non-caching hit // period 5, evict period 2, 2 caching misses, 2 non-caching hit
// should be (6/10)=0.6 and (2/6)=1/3 // should be (6/10)=0.6 and (2/6)=1/3
stats.miss(true); stats.miss(true, false);
stats.miss(true); stats.miss(true, false);
stats.hit(false); stats.hit(false);
stats.hit(false); stats.hit(false);
stats.rollMetricsPeriod(); stats.rollMetricsPeriod();
@ -682,8 +682,8 @@ public class TestLruBlockCache {
// period 9, one of each // period 9, one of each
// should be (2/4)=0.5 and (1/2)=0.5 // should be (2/4)=0.5 and (1/2)=0.5
stats.miss(true); stats.miss(true, false);
stats.miss(false); stats.miss(false, false);
stats.hit(true); stats.hit(true);
stats.hit(false); stats.hit(false);
stats.rollMetricsPeriod(); stats.rollMetricsPeriod();

View File

@ -175,16 +175,31 @@ public class MetricsRegionServerWrapperStub implements MetricsRegionServerWrappe
return 416; return 416;
} }
@Override
public long getBlockCachePrimaryHitCount() {
return 422;
}
@Override @Override
public long getBlockCacheMissCount() { public long getBlockCacheMissCount() {
return 417; return 417;
} }
@Override
public long getBlockCachePrimaryMissCount() {
return 421;
}
@Override @Override
public long getBlockCacheEvictedCount() { public long getBlockCacheEvictedCount() {
return 418; return 418;
} }
@Override
public long getBlockCachePrimaryEvictedCount() {
return 420;
}
@Override @Override
public double getBlockCacheHitPercent() { public double getBlockCacheHitPercent() {
return 98; return 98;

View File

@ -522,13 +522,13 @@ public class TestHeapMemoryManager {
@Override @Override
public boolean evictBlock(BlockCacheKey cacheKey) { public boolean evictBlock(BlockCacheKey cacheKey) {
stats.evicted(0); stats.evicted(0, cacheKey != null ? cacheKey.isPrimary() : true);
return false; return false;
} }
@Override @Override
public int evictBlocksByHfileName(String hfileName) { public int evictBlocksByHfileName(String hfileName) {
stats.evicted(0); // Just assuming only one block for file here. stats.evicted(0, true); // Just assuming only one block for file here.
return 0; return 0;
} }