This is an automated email from the ASF dual-hosted git repository.
bbeaudreault pushed a commit to branch branch-2.5
in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/branch-2.5 by this push:
new 24ae92fbf25 HBASE-28206 [JDK17] JVM crashes intermittently on aarch64
(#5561)
24ae92fbf25 is described below
commit 24ae92fbf253d7ad547bd1c50e5e818e67a50939
Author: Bryan Beaudreault <[email protected]>
AuthorDate: Wed Dec 6 12:53:32 2023 -0500
HBASE-28206 [JDK17] JVM crashes intermittently on aarch64 (#5561)
Signed-off-by: Duo Zhang <[email protected]>
---
.../MetricsRegionServerWrapperImpl.java | 617 ++++++++++-----------
.../org/apache/hadoop/hbase/wal/WALFactory.java | 4 +-
.../TestMetricsRegionServerAggregate.java | 222 ++++++++
3 files changed, 524 insertions(+), 319 deletions(-)
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 26d3c050807..6efc4df2361 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
@@ -24,7 +24,6 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.OptionalDouble;
-import java.util.OptionalLong;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
@@ -72,60 +71,16 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
private CacheStats cacheStats;
private CacheStats l1Stats = null;
private CacheStats l2Stats = null;
-
- private volatile long numStores = 0;
private volatile long numWALFiles = 0;
private volatile long walFileSize = 0;
- private volatile long numStoreFiles = 0;
- private volatile long memstoreSize = 0;
- private volatile long onHeapMemstoreSize = 0;
- private volatile long offHeapMemstoreSize = 0;
- private volatile long storeFileSize = 0;
- private volatile long maxStoreFileCount = 0;
- private volatile long maxStoreFileAge = 0;
- private volatile long minStoreFileAge = 0;
- private volatile long avgStoreFileAge = 0;
- private volatile long numReferenceFiles = 0;
- private volatile double requestsPerSecond = 0.0;
- private volatile long readRequestsCount = 0;
- private volatile double readRequestsRatePerSecond = 0;
- private volatile long filteredReadRequestsCount = 0;
- private volatile long writeRequestsCount = 0;
- private volatile double writeRequestsRatePerSecond = 0;
- private volatile long checkAndMutateChecksFailed = 0;
- private volatile long checkAndMutateChecksPassed = 0;
- private volatile long storefileIndexSize = 0;
- private volatile long totalStaticIndexSize = 0;
- private volatile long totalStaticBloomSize = 0;
- private volatile long bloomFilterRequestsCount = 0;
- private volatile long bloomFilterNegativeResultsCount = 0;
- private volatile long bloomFilterEligibleRequestsCount = 0;
- private volatile long numMutationsWithoutWAL = 0;
- private volatile long dataInMemoryWithoutWAL = 0;
- private volatile double percentFileLocal = 0;
- private volatile double percentFileLocalSecondaryRegions = 0;
- private volatile long flushedCellsCount = 0;
- private volatile long compactedCellsCount = 0;
- private volatile long majorCompactedCellsCount = 0;
- private volatile long flushedCellsSize = 0;
- private volatile long compactedCellsSize = 0;
- private volatile long majorCompactedCellsSize = 0;
- private volatile long cellsCountCompactedToMob = 0;
- private volatile long cellsCountCompactedFromMob = 0;
- private volatile long cellsSizeCompactedToMob = 0;
- private volatile long cellsSizeCompactedFromMob = 0;
- private volatile long mobFlushCount = 0;
- private volatile long mobFlushedCellsCount = 0;
- private volatile long mobFlushedCellsSize = 0;
- private volatile long mobScanCellsCount = 0;
- private volatile long mobScanCellsSize = 0;
private volatile long mobFileCacheAccessCount = 0;
private volatile long mobFileCacheMissCount = 0;
private volatile double mobFileCacheHitRatio = 0;
private volatile long mobFileCacheEvictedCount = 0;
private volatile long mobFileCacheCount = 0;
- private volatile long blockedRequestsCount = 0L;
- private volatile long averageRegionSize = 0L;
+
+ private volatile RegionMetricAggregate aggregate = new
RegionMetricAggregate(null);
+
protected final Map<String, ArrayList<Long>> requestsCountCache =
new ConcurrentHashMap<String, ArrayList<Long>>();
@@ -247,7 +202,7 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
@Override
public long getTotalRowActionRequestCount() {
- return readRequestsCount + writeRequestsCount;
+ return aggregate.readRequestsCount + aggregate.writeRequestsCount;
}
@Override
@@ -460,7 +415,7 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
@Override
public long getNumStores() {
- return numStores;
+ return aggregate.numStores;
}
@Override
@@ -489,82 +444,82 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
@Override
public long getNumStoreFiles() {
- return numStoreFiles;
+ return aggregate.numStoreFiles;
}
@Override
public long getMaxStoreFiles() {
- return maxStoreFileCount;
+ return aggregate.maxStoreFileCount;
}
@Override
public long getMaxStoreFileAge() {
- return maxStoreFileAge;
+ return aggregate.maxStoreFileAge;
}
@Override
public long getMinStoreFileAge() {
- return minStoreFileAge;
+ return aggregate.minStoreFileAge;
}
@Override
public long getAvgStoreFileAge() {
- return avgStoreFileAge;
+ return aggregate.avgStoreFileAge;
}
@Override
public long getNumReferenceFiles() {
- return numReferenceFiles;
+ return aggregate.numReferenceFiles;
}
@Override
public long getMemStoreSize() {
- return memstoreSize;
+ return aggregate.memstoreSize;
}
@Override
public long getOnHeapMemStoreSize() {
- return onHeapMemstoreSize;
+ return aggregate.onHeapMemstoreSize;
}
@Override
public long getOffHeapMemStoreSize() {
- return offHeapMemstoreSize;
+ return aggregate.offHeapMemstoreSize;
}
@Override
public long getStoreFileSize() {
- return storeFileSize;
+ return aggregate.storeFileSize;
}
@Override
public double getRequestsPerSecond() {
- return requestsPerSecond;
+ return aggregate.requestsPerSecond;
}
@Override
public long getReadRequestsCount() {
- return readRequestsCount;
+ return aggregate.readRequestsCount;
}
@Override
public double getReadRequestsRatePerSecond() {
- return readRequestsRatePerSecond;
+ return aggregate.readRequestsRatePerSecond;
}
@Override
public long getFilteredReadRequestsCount() {
- return filteredReadRequestsCount;
+ return aggregate.filteredReadRequestsCount;
}
@Override
public long getWriteRequestsCount() {
- return writeRequestsCount;
+ return aggregate.writeRequestsCount;
}
@Override
public double getWriteRequestsRatePerSecond() {
- return writeRequestsRatePerSecond;
+ return aggregate.writeRequestsRatePerSecond;
}
@Override
@@ -594,62 +549,62 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
@Override
public long getCheckAndMutateChecksFailed() {
- return checkAndMutateChecksFailed;
+ return aggregate.checkAndMutateChecksFailed;
}
@Override
public long getCheckAndMutateChecksPassed() {
- return checkAndMutateChecksPassed;
+ return aggregate.checkAndMutateChecksPassed;
}
@Override
public long getStoreFileIndexSize() {
- return storefileIndexSize;
+ return aggregate.storefileIndexSize;
}
@Override
public long getTotalStaticIndexSize() {
- return totalStaticIndexSize;
+ return aggregate.totalStaticIndexSize;
}
@Override
public long getTotalStaticBloomSize() {
- return totalStaticBloomSize;
+ return aggregate.totalStaticBloomSize;
}
@Override
public long getBloomFilterRequestsCount() {
- return bloomFilterRequestsCount;
+ return aggregate.bloomFilterRequestsCount;
}
@Override
public long getBloomFilterNegativeResultsCount() {
- return bloomFilterNegativeResultsCount;
+ return aggregate.bloomFilterNegativeResultsCount;
}
@Override
public long getBloomFilterEligibleRequestsCount() {
- return bloomFilterEligibleRequestsCount;
+ return aggregate.bloomFilterEligibleRequestsCount;
}
@Override
public long getNumMutationsWithoutWAL() {
- return numMutationsWithoutWAL;
+ return aggregate.numMutationsWithoutWAL;
}
@Override
public long getDataInMemoryWithoutWAL() {
- return dataInMemoryWithoutWAL;
+ return aggregate.dataInMemoryWithoutWAL;
}
@Override
public double getPercentFileLocal() {
- return percentFileLocal;
+ return aggregate.percentFileLocal;
}
@Override
public double getPercentFileLocalSecondaryRegions() {
- return percentFileLocalSecondaryRegions;
+ return aggregate.percentFileLocalSecondaryRegions;
}
@Override
@@ -662,77 +617,77 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
@Override
public long getFlushedCellsCount() {
- return flushedCellsCount;
+ return aggregate.flushedCellsCount;
}
@Override
public long getCompactedCellsCount() {
- return compactedCellsCount;
+ return aggregate.compactedCellsCount;
}
@Override
public long getMajorCompactedCellsCount() {
- return majorCompactedCellsCount;
+ return aggregate.majorCompactedCellsCount;
}
@Override
public long getFlushedCellsSize() {
- return flushedCellsSize;
+ return aggregate.flushedCellsSize;
}
@Override
public long getCompactedCellsSize() {
- return compactedCellsSize;
+ return aggregate.compactedCellsSize;
}
@Override
public long getMajorCompactedCellsSize() {
- return majorCompactedCellsSize;
+ return aggregate.majorCompactedCellsSize;
}
@Override
public long getCellsCountCompactedFromMob() {
- return cellsCountCompactedFromMob;
+ return aggregate.cellsCountCompactedFromMob;
}
@Override
public long getCellsCountCompactedToMob() {
- return cellsCountCompactedToMob;
+ return aggregate.cellsCountCompactedToMob;
}
@Override
public long getCellsSizeCompactedFromMob() {
- return cellsSizeCompactedFromMob;
+ return aggregate.cellsSizeCompactedFromMob;
}
@Override
public long getCellsSizeCompactedToMob() {
- return cellsSizeCompactedToMob;
+ return aggregate.cellsSizeCompactedToMob;
}
@Override
public long getMobFlushCount() {
- return mobFlushCount;
+ return aggregate.mobFlushCount;
}
@Override
public long getMobFlushedCellsCount() {
- return mobFlushedCellsCount;
+ return aggregate.mobFlushedCellsCount;
}
@Override
public long getMobFlushedCellsSize() {
- return mobFlushedCellsSize;
+ return aggregate.mobFlushedCellsSize;
}
@Override
public long getMobScanCellsCount() {
- return mobScanCellsCount;
+ return aggregate.mobScanCellsCount;
}
@Override
public long getMobScanCellsSize() {
- return mobScanCellsSize;
+ return aggregate.mobScanCellsSize;
}
@Override
@@ -765,6 +720,241 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
return regionServer.getRSRpcServices().getScannersCount();
}
+ private static final class RegionMetricAggregate {
+ private long numStores = 0;
+ private long numStoreFiles = 0;
+ private long memstoreSize = 0;
+ private long onHeapMemstoreSize = 0;
+ private long offHeapMemstoreSize = 0;
+ private long storeFileSize = 0;
+ private long maxStoreFileCount = 0;
+ private long maxStoreFileAge = 0;
+ private long minStoreFileAge = Long.MAX_VALUE;
+ private long avgStoreFileAge = 0;
+ private long numReferenceFiles = 0;
+
+ private double requestsPerSecond = 0.0;
+ private long readRequestsCount = 0;
+ private double readRequestsRatePerSecond = 0;
+ private long filteredReadRequestsCount = 0;
+ private long writeRequestsCount = 0;
+ private double writeRequestsRatePerSecond = 0;
+ private long checkAndMutateChecksFailed = 0;
+ private long checkAndMutateChecksPassed = 0;
+ private long storefileIndexSize = 0;
+ private long totalStaticIndexSize = 0;
+ private long totalStaticBloomSize = 0;
+ private long bloomFilterRequestsCount = 0;
+ private long bloomFilterNegativeResultsCount = 0;
+ private long bloomFilterEligibleRequestsCount = 0;
+ private long numMutationsWithoutWAL = 0;
+ private long dataInMemoryWithoutWAL = 0;
+ private double percentFileLocal = 0;
+ private double percentFileLocalSecondaryRegions = 0;
+ private long flushedCellsCount = 0;
+ private long compactedCellsCount = 0;
+ private long majorCompactedCellsCount = 0;
+ private long flushedCellsSize = 0;
+ private long compactedCellsSize = 0;
+ private long majorCompactedCellsSize = 0;
+ private long cellsCountCompactedToMob = 0;
+ private long cellsCountCompactedFromMob = 0;
+ private long cellsSizeCompactedToMob = 0;
+ private long cellsSizeCompactedFromMob = 0;
+ private long mobFlushCount = 0;
+ private long mobFlushedCellsCount = 0;
+ private long mobFlushedCellsSize = 0;
+ private long mobScanCellsCount = 0;
+ private long mobScanCellsSize = 0;
+ private long blockedRequestsCount = 0L;
+ private long averageRegionSize = 0L;
+ private long totalReadRequestsDelta = 0;
+ private long totalWriteRequestsDelta = 0;
+
+ private RegionMetricAggregate(RegionMetricAggregate other) {
+ if (other != null) {
+ requestsPerSecond = other.requestsPerSecond;
+ readRequestsRatePerSecond = other.readRequestsRatePerSecond;
+ writeRequestsRatePerSecond = other.writeRequestsRatePerSecond;
+ }
+ }
+
+ private void aggregate(HRegionServer regionServer,
+ Map<String, ArrayList<Long>> requestsCountCache) {
+ HDFSBlocksDistribution hdfsBlocksDistribution = new
HDFSBlocksDistribution();
+ HDFSBlocksDistribution hdfsBlocksDistributionSecondaryRegions = new
HDFSBlocksDistribution();
+
+ long avgAgeNumerator = 0;
+ long numHFiles = 0;
+ int regionCount = 0;
+
+ for (HRegion r : regionServer.getOnlineRegionsLocalContext()) {
+ Deltas deltas = calculateReadWriteDeltas(r, requestsCountCache);
+ totalReadRequestsDelta += deltas.readRequestsCountDelta;
+ totalWriteRequestsDelta += deltas.writeRequestsCountDelta;
+
+ numMutationsWithoutWAL += r.getNumMutationsWithoutWAL();
+ dataInMemoryWithoutWAL += r.getDataInMemoryWithoutWAL();
+ readRequestsCount += r.getReadRequestsCount();
+ filteredReadRequestsCount += r.getFilteredReadRequestsCount();
+ writeRequestsCount += r.getWriteRequestsCount();
+ checkAndMutateChecksFailed += r.getCheckAndMutateChecksFailed();
+ checkAndMutateChecksPassed += r.getCheckAndMutateChecksPassed();
+ blockedRequestsCount += r.getBlockedRequestsCount();
+
+ StoreFileStats storeFileStats = aggregateStores(r.getStores());
+ numHFiles += storeFileStats.numHFiles;
+ avgAgeNumerator += storeFileStats.avgAgeNumerator;
+
+ HDFSBlocksDistribution distro = r.getHDFSBlocksDistribution();
+ hdfsBlocksDistribution.add(distro);
+ if (r.getRegionInfo().getReplicaId() !=
HRegionInfo.DEFAULT_REPLICA_ID) {
+ hdfsBlocksDistributionSecondaryRegions.add(distro);
+ }
+
+ regionCount++;
+ }
+
+ float localityIndex =
+
hdfsBlocksDistribution.getBlockLocalityIndex(regionServer.getServerName().getHostname());
+ percentFileLocal = Double.isNaN(localityIndex) ? 0 : (localityIndex *
100);
+
+ float localityIndexSecondaryRegions =
hdfsBlocksDistributionSecondaryRegions
+ .getBlockLocalityIndex(regionServer.getServerName().getHostname());
+ percentFileLocalSecondaryRegions =
+ Double.isNaN(localityIndexSecondaryRegions) ? 0 :
(localityIndexSecondaryRegions * 100);
+
+ if (regionCount > 0) {
+ averageRegionSize = (memstoreSize + storeFileSize) / regionCount;
+ }
+
+ // if there were no store files, we'll never have updated this with
Math.min
+ // so set it to 0, which is a better value to display in case of no
storefiles
+ if (minStoreFileAge == Long.MAX_VALUE) {
+ this.minStoreFileAge = 0;
+ }
+
+ if (numHFiles != 0) {
+ avgStoreFileAge = avgAgeNumerator / numHFiles;
+ }
+ }
+
+ private static final class Deltas {
+ private final long readRequestsCountDelta;
+ private final long writeRequestsCountDelta;
+
+ private Deltas(long readRequestsCountDelta, long
writeRequestsCountDelta) {
+ this.readRequestsCountDelta = readRequestsCountDelta;
+ this.writeRequestsCountDelta = writeRequestsCountDelta;
+ }
+ }
+
+ private Deltas calculateReadWriteDeltas(HRegion r,
+ Map<String, ArrayList<Long>> requestsCountCache) {
+ String encodedRegionName = r.getRegionInfo().getEncodedName();
+ long currentReadRequestsCount = r.getReadRequestsCount();
+ long currentWriteRequestsCount = r.getWriteRequestsCount();
+ if (requestsCountCache.containsKey(encodedRegionName)) {
+ long lastReadRequestsCount =
requestsCountCache.get(encodedRegionName).get(0);
+ long lastWriteRequestsCount =
requestsCountCache.get(encodedRegionName).get(1);
+
+ // Update cache for our next comparison
+ requestsCountCache.get(encodedRegionName).set(0,
currentReadRequestsCount);
+ requestsCountCache.get(encodedRegionName).set(1,
currentWriteRequestsCount);
+
+ long readRequestsDelta = currentReadRequestsCount -
lastReadRequestsCount;
+ long writeRequestsDelta = currentWriteRequestsCount -
lastWriteRequestsCount;
+ return new Deltas(readRequestsDelta, writeRequestsDelta);
+ } else {
+ // List[0] -> readRequestCount
+ // List[1] -> writeRequestCount
+ ArrayList<Long> requests = new ArrayList<Long>(2);
+ requests.add(currentReadRequestsCount);
+ requests.add(currentWriteRequestsCount);
+ requestsCountCache.put(encodedRegionName, requests);
+ return new Deltas(currentReadRequestsCount, currentWriteRequestsCount);
+ }
+ }
+
+ public void updateRates(long timeSinceLastRun, long expectedPeriod) {
+ requestsPerSecond =
+ (totalReadRequestsDelta + totalWriteRequestsDelta) / (timeSinceLastRun
/ 1000.0);
+
+ double readRequestsRatePerMilliSecond = (double) totalReadRequestsDelta
/ expectedPeriod;
+ double writeRequestsRatePerMilliSecond = (double)
totalWriteRequestsDelta / expectedPeriod;
+
+ readRequestsRatePerSecond = readRequestsRatePerMilliSecond * 1000.0;
+ writeRequestsRatePerSecond = writeRequestsRatePerMilliSecond * 1000.0;
+ }
+
+ private static final class StoreFileStats {
+ private final long numHFiles;
+ private final long avgAgeNumerator;
+
+ private StoreFileStats(long numHFiles, long avgAgeNumerator) {
+ this.numHFiles = numHFiles;
+ this.avgAgeNumerator = avgAgeNumerator;
+ }
+ }
+
+ private StoreFileStats aggregateStores(List<HStore> stores) {
+ numStores += stores.size();
+ long numHFiles = 0;
+ long avgAgeNumerator = 0;
+ for (Store store : stores) {
+ numStoreFiles += store.getStorefilesCount();
+ memstoreSize += store.getMemStoreSize().getDataSize();
+ onHeapMemstoreSize += store.getMemStoreSize().getHeapSize();
+ offHeapMemstoreSize += store.getMemStoreSize().getOffHeapSize();
+ storeFileSize += store.getStorefilesSize();
+ maxStoreFileCount = Math.max(maxStoreFileCount,
store.getStorefilesCount());
+
+ maxStoreFileAge =
+ Math.max(store.getMaxStoreFileAge().orElse(maxStoreFileAge),
maxStoreFileAge);
+ minStoreFileAge =
+ Math.min(store.getMinStoreFileAge().orElse(minStoreFileAge),
minStoreFileAge);
+
+ long storeHFiles = store.getNumHFiles();
+ numHFiles += storeHFiles;
+ numReferenceFiles += store.getNumReferenceFiles();
+
+ OptionalDouble storeAvgStoreFileAge = store.getAvgStoreFileAge();
+ if (storeAvgStoreFileAge.isPresent()) {
+ avgAgeNumerator =
+ (long) (avgAgeNumerator + storeAvgStoreFileAge.getAsDouble() *
storeHFiles);
+ }
+
+ storefileIndexSize += store.getStorefilesRootLevelIndexSize();
+ totalStaticBloomSize += store.getTotalStaticBloomSize();
+ totalStaticIndexSize += store.getTotalStaticIndexSize();
+ bloomFilterRequestsCount += store.getBloomFilterRequestsCount();
+ bloomFilterNegativeResultsCount +=
store.getBloomFilterNegativeResultsCount();
+ bloomFilterEligibleRequestsCount +=
store.getBloomFilterEligibleRequestsCount();
+ flushedCellsCount += store.getFlushedCellsCount();
+ compactedCellsCount += store.getCompactedCellsCount();
+ majorCompactedCellsCount += store.getMajorCompactedCellsCount();
+ flushedCellsSize += store.getFlushedCellsSize();
+ compactedCellsSize += store.getCompactedCellsSize();
+ majorCompactedCellsSize += store.getMajorCompactedCellsSize();
+ if (store instanceof HMobStore) {
+ HMobStore mobStore = (HMobStore) store;
+ cellsCountCompactedToMob += mobStore.getCellsCountCompactedToMob();
+ cellsCountCompactedFromMob +=
mobStore.getCellsCountCompactedFromMob();
+ cellsSizeCompactedToMob += mobStore.getCellsSizeCompactedToMob();
+ cellsSizeCompactedFromMob += mobStore.getCellsSizeCompactedFromMob();
+ mobFlushCount += mobStore.getMobFlushCount();
+ mobFlushedCellsCount += mobStore.getMobFlushedCellsCount();
+ mobFlushedCellsSize += mobStore.getMobFlushedCellsSize();
+ mobScanCellsCount += mobStore.getMobScanCellsCount();
+ mobScanCellsSize += mobStore.getMobScanCellsSize();
+ }
+ }
+
+ return new StoreFileStats(numHFiles, avgAgeNumerator);
+ }
+
+ }
+
/**
* This is the runnable that will be executed on the executor every PERIOD
number of seconds It
* will take metrics/numbers from all of the regions and use them to compute
point in time
@@ -777,167 +967,8 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
@Override
synchronized public void run() {
try {
- HDFSBlocksDistribution hdfsBlocksDistribution = new
HDFSBlocksDistribution();
- HDFSBlocksDistribution hdfsBlocksDistributionSecondaryRegions =
- new HDFSBlocksDistribution();
-
- long tempNumStores = 0, tempNumStoreFiles = 0, tempStoreFileSize = 0;
- long tempMemstoreSize = 0, tempOnHeapMemstoreSize = 0,
tempOffHeapMemstoreSize = 0;
- long tempMaxStoreFileAge = 0, tempNumReferenceFiles = 0;
- long tempMaxStoreFileCount = 0;
- long avgAgeNumerator = 0, numHFiles = 0;
- long tempMinStoreFileAge = Long.MAX_VALUE;
- long tempReadRequestsCount = 0, tempFilteredReadRequestsCount = 0,
- tempWriteRequestsCount = 0;
- long tempCheckAndMutateChecksFailed = 0;
- long tempCheckAndMutateChecksPassed = 0;
- long tempStorefileIndexSize = 0;
- long tempTotalStaticIndexSize = 0;
- long tempTotalStaticBloomSize = 0;
- long tempBloomFilterRequestsCount = 0;
- long tempBloomFilterNegativeResultsCount = 0;
- long tempBloomFilterEligibleRequestsCount = 0;
- long tempNumMutationsWithoutWAL = 0;
- long tempDataInMemoryWithoutWAL = 0;
- double tempPercentFileLocal = 0;
- double tempPercentFileLocalSecondaryRegions = 0;
- long tempFlushedCellsCount = 0;
- long tempCompactedCellsCount = 0;
- long tempMajorCompactedCellsCount = 0;
- long tempFlushedCellsSize = 0;
- long tempCompactedCellsSize = 0;
- long tempMajorCompactedCellsSize = 0;
- long tempCellsCountCompactedToMob = 0;
- long tempCellsCountCompactedFromMob = 0;
- long tempCellsSizeCompactedToMob = 0;
- long tempCellsSizeCompactedFromMob = 0;
- long tempMobFlushCount = 0;
- long tempMobFlushedCellsCount = 0;
- long tempMobFlushedCellsSize = 0;
- long tempMobScanCellsCount = 0;
- long tempMobScanCellsSize = 0;
- long tempBlockedRequestsCount = 0;
- int regionCount = 0;
-
- long currentReadRequestsCount = 0;
- long currentWriteRequestsCount = 0;
- long lastReadRequestsCount = 0;
- long lastWriteRequestsCount = 0;
- long readRequestsDelta = 0;
- long writeRequestsDelta = 0;
- long totalReadRequestsDelta = 0;
- long totalWriteRequestsDelta = 0;
- String encodedRegionName;
- for (HRegion r : regionServer.getOnlineRegionsLocalContext()) {
- encodedRegionName = r.getRegionInfo().getEncodedName();
- currentReadRequestsCount = r.getReadRequestsCount();
- currentWriteRequestsCount = r.getWriteRequestsCount();
- if (requestsCountCache.containsKey(encodedRegionName)) {
- lastReadRequestsCount =
requestsCountCache.get(encodedRegionName).get(0);
- lastWriteRequestsCount =
requestsCountCache.get(encodedRegionName).get(1);
- readRequestsDelta = currentReadRequestsCount -
lastReadRequestsCount;
- writeRequestsDelta = currentWriteRequestsCount -
lastWriteRequestsCount;
- totalReadRequestsDelta += readRequestsDelta;
- totalWriteRequestsDelta += writeRequestsDelta;
- // Update cache for our next comparision
- requestsCountCache.get(encodedRegionName).set(0,
currentReadRequestsCount);
- requestsCountCache.get(encodedRegionName).set(1,
currentWriteRequestsCount);
- } else {
- // List[0] -> readRequestCount
- // List[1] -> writeRequestCount
- ArrayList<Long> requests = new ArrayList<Long>(2);
- requests.add(currentReadRequestsCount);
- requests.add(currentWriteRequestsCount);
- requestsCountCache.put(encodedRegionName, requests);
- totalReadRequestsDelta += currentReadRequestsCount;
- totalWriteRequestsDelta += currentWriteRequestsCount;
- }
- tempNumMutationsWithoutWAL += r.getNumMutationsWithoutWAL();
- tempDataInMemoryWithoutWAL += r.getDataInMemoryWithoutWAL();
- tempReadRequestsCount += r.getReadRequestsCount();
- tempFilteredReadRequestsCount += r.getFilteredReadRequestsCount();
- tempWriteRequestsCount += r.getWriteRequestsCount();
- tempCheckAndMutateChecksFailed += r.getCheckAndMutateChecksFailed();
- tempCheckAndMutateChecksPassed += r.getCheckAndMutateChecksPassed();
- tempBlockedRequestsCount += r.getBlockedRequestsCount();
- List<? extends Store> storeList = r.getStores();
- tempNumStores += storeList.size();
- for (Store store : storeList) {
- tempNumStoreFiles += store.getStorefilesCount();
- tempMemstoreSize += store.getMemStoreSize().getDataSize();
- tempOnHeapMemstoreSize += store.getMemStoreSize().getHeapSize();
- tempOffHeapMemstoreSize +=
store.getMemStoreSize().getOffHeapSize();
- tempStoreFileSize += store.getStorefilesSize();
-
- tempMaxStoreFileCount = Math.max(tempMaxStoreFileCount,
store.getStorefilesCount());
-
- OptionalLong storeMaxStoreFileAge = store.getMaxStoreFileAge();
- if (
- storeMaxStoreFileAge.isPresent()
- && storeMaxStoreFileAge.getAsLong() > tempMaxStoreFileAge
- ) {
- tempMaxStoreFileAge = storeMaxStoreFileAge.getAsLong();
- }
-
- OptionalLong storeMinStoreFileAge = store.getMinStoreFileAge();
- if (
- storeMinStoreFileAge.isPresent()
- && storeMinStoreFileAge.getAsLong() < tempMinStoreFileAge
- ) {
- tempMinStoreFileAge = storeMinStoreFileAge.getAsLong();
- }
-
- long storeHFiles = store.getNumHFiles();
- numHFiles += storeHFiles;
- tempNumReferenceFiles += store.getNumReferenceFiles();
-
- OptionalDouble storeAvgStoreFileAge = store.getAvgStoreFileAge();
- if (storeAvgStoreFileAge.isPresent()) {
- avgAgeNumerator =
- (long) (avgAgeNumerator + storeAvgStoreFileAge.getAsDouble() *
storeHFiles);
- }
-
- tempStorefileIndexSize += store.getStorefilesRootLevelIndexSize();
- tempTotalStaticBloomSize += store.getTotalStaticBloomSize();
- tempTotalStaticIndexSize += store.getTotalStaticIndexSize();
- tempBloomFilterRequestsCount +=
store.getBloomFilterRequestsCount();
- tempBloomFilterNegativeResultsCount +=
store.getBloomFilterNegativeResultsCount();
- tempBloomFilterEligibleRequestsCount +=
store.getBloomFilterEligibleRequestsCount();
- tempFlushedCellsCount += store.getFlushedCellsCount();
- tempCompactedCellsCount += store.getCompactedCellsCount();
- tempMajorCompactedCellsCount +=
store.getMajorCompactedCellsCount();
- tempFlushedCellsSize += store.getFlushedCellsSize();
- tempCompactedCellsSize += store.getCompactedCellsSize();
- tempMajorCompactedCellsSize += store.getMajorCompactedCellsSize();
- if (store instanceof HMobStore) {
- HMobStore mobStore = (HMobStore) store;
- tempCellsCountCompactedToMob +=
mobStore.getCellsCountCompactedToMob();
- tempCellsCountCompactedFromMob +=
mobStore.getCellsCountCompactedFromMob();
- tempCellsSizeCompactedToMob +=
mobStore.getCellsSizeCompactedToMob();
- tempCellsSizeCompactedFromMob +=
mobStore.getCellsSizeCompactedFromMob();
- tempMobFlushCount += mobStore.getMobFlushCount();
- tempMobFlushedCellsCount += mobStore.getMobFlushedCellsCount();
- tempMobFlushedCellsSize += mobStore.getMobFlushedCellsSize();
- tempMobScanCellsCount += mobStore.getMobScanCellsCount();
- tempMobScanCellsSize += mobStore.getMobScanCellsSize();
- }
- }
-
- HDFSBlocksDistribution distro = r.getHDFSBlocksDistribution();
- hdfsBlocksDistribution.add(distro);
- if (r.getRegionInfo().getReplicaId() !=
HRegionInfo.DEFAULT_REPLICA_ID) {
- hdfsBlocksDistributionSecondaryRegions.add(distro);
- }
- regionCount++;
- }
- float localityIndex =
-
hdfsBlocksDistribution.getBlockLocalityIndex(regionServer.getServerName().getHostname());
- tempPercentFileLocal = Double.isNaN(tempBlockedRequestsCount) ? 0 :
(localityIndex * 100);
-
- float localityIndexSecondaryRegions =
hdfsBlocksDistributionSecondaryRegions
- .getBlockLocalityIndex(regionServer.getServerName().getHostname());
- tempPercentFileLocalSecondaryRegions =
- Double.isNaN(localityIndexSecondaryRegions) ? 0 :
(localityIndexSecondaryRegions * 100);
+ RegionMetricAggregate newVal = new RegionMetricAggregate(aggregate);
+ newVal.aggregate(regionServer, requestsCountCache);
// Compute the number of requests per second
long currentTime = EnvironmentEdgeManager.currentTime();
@@ -947,18 +978,14 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
if (lastRan == 0) {
lastRan = currentTime - period;
}
- // If we've time traveled keep the last requests per second.
- if ((currentTime - lastRan) > 0) {
- requestsPerSecond =
- (totalReadRequestsDelta + totalWriteRequestsDelta) / ((currentTime
- lastRan) / 1000.0);
- double readRequestsRatePerMilliSecond = (double)
totalReadRequestsDelta / period;
- double writeRequestsRatePerMilliSecond = (double)
totalWriteRequestsDelta / period;
-
- readRequestsRatePerSecond = readRequestsRatePerMilliSecond * 1000.0;
- writeRequestsRatePerSecond = writeRequestsRatePerMilliSecond *
1000.0;
+ long timeSinceLastRun = currentTime - lastRan;
+ // If we've time traveled keep the last requests per second.
+ if (timeSinceLastRun > 0) {
+ newVal.updateRates(timeSinceLastRun, period);
}
- lastRan = currentTime;
+
+ aggregate = newVal;
final WALProvider provider =
regionServer.getWalFactory().getWALProvider();
final WALProvider metaProvider =
regionServer.getWalFactory().getMetaWALProvider();
@@ -966,57 +993,7 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
+ (metaProvider == null ? 0 : metaProvider.getNumLogFiles());
walFileSize = (provider == null ? 0 : provider.getLogFileSize())
+ (metaProvider == null ? 0 : metaProvider.getLogFileSize());
- // Copy over computed values so that no thread sees half computed
values.
- numStores = tempNumStores;
- numStoreFiles = tempNumStoreFiles;
- memstoreSize = tempMemstoreSize;
- onHeapMemstoreSize = tempOnHeapMemstoreSize;
- offHeapMemstoreSize = tempOffHeapMemstoreSize;
- storeFileSize = tempStoreFileSize;
- maxStoreFileCount = tempMaxStoreFileCount;
- maxStoreFileAge = tempMaxStoreFileAge;
- if (regionCount > 0) {
- averageRegionSize = (memstoreSize + storeFileSize) / regionCount;
- }
- if (tempMinStoreFileAge != Long.MAX_VALUE) {
- minStoreFileAge = tempMinStoreFileAge;
- }
-
- if (numHFiles != 0) {
- avgStoreFileAge = avgAgeNumerator / numHFiles;
- }
- numReferenceFiles = tempNumReferenceFiles;
- readRequestsCount = tempReadRequestsCount;
- filteredReadRequestsCount = tempFilteredReadRequestsCount;
- writeRequestsCount = tempWriteRequestsCount;
- checkAndMutateChecksFailed = tempCheckAndMutateChecksFailed;
- checkAndMutateChecksPassed = tempCheckAndMutateChecksPassed;
- storefileIndexSize = tempStorefileIndexSize;
- totalStaticIndexSize = tempTotalStaticIndexSize;
- totalStaticBloomSize = tempTotalStaticBloomSize;
- bloomFilterRequestsCount = tempBloomFilterRequestsCount;
- bloomFilterNegativeResultsCount = tempBloomFilterNegativeResultsCount;
- bloomFilterEligibleRequestsCount =
tempBloomFilterEligibleRequestsCount;
- numMutationsWithoutWAL = tempNumMutationsWithoutWAL;
- dataInMemoryWithoutWAL = tempDataInMemoryWithoutWAL;
- percentFileLocal = tempPercentFileLocal;
- percentFileLocalSecondaryRegions =
tempPercentFileLocalSecondaryRegions;
- flushedCellsCount = tempFlushedCellsCount;
- compactedCellsCount = tempCompactedCellsCount;
- majorCompactedCellsCount = tempMajorCompactedCellsCount;
- flushedCellsSize = tempFlushedCellsSize;
- compactedCellsSize = tempCompactedCellsSize;
- majorCompactedCellsSize = tempMajorCompactedCellsSize;
- cellsCountCompactedToMob = tempCellsCountCompactedToMob;
- cellsCountCompactedFromMob = tempCellsCountCompactedFromMob;
- cellsSizeCompactedToMob = tempCellsSizeCompactedToMob;
- cellsSizeCompactedFromMob = tempCellsSizeCompactedFromMob;
- mobFlushCount = tempMobFlushCount;
- mobFlushedCellsCount = tempMobFlushedCellsCount;
- mobFlushedCellsSize = tempMobFlushedCellsSize;
- mobScanCellsCount = tempMobScanCellsCount;
- mobScanCellsSize = tempMobScanCellsSize;
mobFileCacheAccessCount = mobFileCache != null ?
mobFileCache.getAccessCount() : 0L;
mobFileCacheMissCount = mobFileCache != null ?
mobFileCache.getMissCount() : 0L;
mobFileCacheHitRatio = mobFileCache != null ?
mobFileCache.getHitRatio() : 0.0;
@@ -1025,7 +1002,8 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
}
mobFileCacheEvictedCount = mobFileCache != null ?
mobFileCache.getEvictedFileCount() : 0L;
mobFileCacheCount = mobFileCache != null ? mobFileCache.getCacheSize()
: 0;
- blockedRequestsCount = tempBlockedRequestsCount;
+
+ lastRan = currentTime;
} catch (Throwable e) {
LOG.warn("Caught exception! Will suppress and retry.", e);
}
@@ -1071,12 +1049,12 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
@Override
public long getBlockedRequestsCount() {
- return blockedRequestsCount;
+ return aggregate.blockedRequestsCount;
}
@Override
public long getAverageRegionSize() {
- return averageRegionSize;
+ return aggregate.averageRegionSize;
}
@Override
@@ -1203,4 +1181,9 @@ class MetricsRegionServerWrapperImpl implements
MetricsRegionServerWrapper {
public long getByteBuffAllocatorUsedBufferCount() {
return this.allocator.getUsedBufferCount();
}
+
+ // Visible for testing
+ long getPeriod() {
+ return period;
+ }
}
diff --git
a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java
b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java
index e3968ae3cff..d43a88899a2 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/wal/WALFactory.java
@@ -487,7 +487,7 @@ public class WALFactory {
return factoryId;
}
- public final WALProvider getWALProvider() {
+ public WALProvider getWALProvider() {
return this.provider;
}
@@ -495,7 +495,7 @@ public class WALFactory {
* @return Current metaProvider... may be null if not yet initialized.
* @see #getMetaProvider()
*/
- public final WALProvider getMetaWALProvider() {
+ public WALProvider getMetaWALProvider() {
return this.metaProvider.get();
}
diff --git
a/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegionServerAggregate.java
b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegionServerAggregate.java
new file mode 100644
index 00000000000..89c8b384093
--- /dev/null
+++
b/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestMetricsRegionServerAggregate.java
@@ -0,0 +1,222 @@
+/*
+ * 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.regionserver;
+
+import static org.junit.Assert.assertEquals;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.util.List;
+import java.util.OptionalDouble;
+import java.util.OptionalLong;
+import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.hbase.HBaseClassTestRule;
+import org.apache.hadoop.hbase.HBaseConfiguration;
+import org.apache.hadoop.hbase.HConstants;
+import org.apache.hadoop.hbase.HDFSBlocksDistribution;
+import org.apache.hadoop.hbase.ServerName;
+import org.apache.hadoop.hbase.client.RegionInfo;
+import org.apache.hadoop.hbase.ipc.RpcServerInterface;
+import org.apache.hadoop.hbase.testclassification.RegionServerTests;
+import org.apache.hadoop.hbase.testclassification.SmallTests;
+import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
+import org.apache.hadoop.hbase.util.ManualEnvironmentEdge;
+import org.apache.hadoop.hbase.wal.WALFactory;
+import org.junit.ClassRule;
+import org.junit.Test;
+import org.junit.experimental.categories.Category;
+import org.mockito.Mockito;
+import org.mockito.stubbing.Answer;
+
+import org.apache.hbase.thirdparty.com.google.common.collect.Lists;
+
+@Category({ SmallTests.class, RegionServerTests.class })
+public class TestMetricsRegionServerAggregate {
+
+ @ClassRule
+ public static final HBaseClassTestRule CLASS_RULE =
+ HBaseClassTestRule.forClass(TestMetricsRegionServerAggregate.class);
+
+ @Test
+ public void test() {
+ AtomicInteger retVal = new AtomicInteger(0);
+ Answer defaultAnswer = invocation -> {
+ Class<?> returnType = invocation.getMethod().getReturnType();
+
+ if (returnType.equals(Integer.TYPE) || returnType.equals(Integer.class))
{
+ return retVal.get();
+ } else if (returnType.equals(Long.TYPE) ||
returnType.equals(Long.class)) {
+ return (long) retVal.get();
+ }
+ return Mockito.RETURNS_DEFAULTS.answer(invocation);
+ };
+
+ ServerName serverName = mock(ServerName.class);
+ when(serverName.getHostname()).thenReturn("foo");
+ WALFactory walFactory = mock(WALFactory.class);
+ RpcServerInterface rpcServer = mock(RpcServerInterface.class);
+ AtomicInteger storeFileCount = new AtomicInteger(1);
+ HRegion regionOne = getMockedRegion(defaultAnswer, "a", "foo", true,
storeFileCount);
+ HRegion regionTwo = getMockedRegion(defaultAnswer, "b", "bar", true,
storeFileCount);
+ HRegion regionThree = getMockedRegion(defaultAnswer, "c", "foo", false,
storeFileCount);
+ HRegion regionFour = getMockedRegion(defaultAnswer, "d", "bar", false,
storeFileCount);
+ List<HRegion> regions = Lists.newArrayList(regionOne, regionTwo,
regionThree, regionFour);
+
+ int numStoresPerRegion = 2;
+ for (HRegion region : regions) {
+ // if adding more stores, update numStoresPerRegion so that tests below
continue working
+ assertEquals(numStoresPerRegion, region.getStores().size());
+ }
+
+ HRegionServer regionServer = mock(HRegionServer.class, defaultAnswer);
+ when(regionServer.getWalFactory()).thenReturn(walFactory);
+ when(regionServer.getOnlineRegionsLocalContext()).thenReturn(regions);
+ when(regionServer.getServerName()).thenReturn(serverName);
+ Configuration conf = HBaseConfiguration.create();
+ int metricsPeriodSec = 600;
+ // set a very long period so that it doesn't actually run during our very
quick test
+ conf.setLong(HConstants.REGIONSERVER_METRICS_PERIOD, metricsPeriodSec *
1000);
+ when(regionServer.getConfiguration()).thenReturn(conf);
+ when(regionServer.getRpcServer()).thenReturn(rpcServer);
+
+ MetricsRegionServerWrapperImpl wrapper = new
MetricsRegionServerWrapperImpl(regionServer);
+
+ // we need to control the edge because rate calculations expect a
+ // stable interval relative to the configured period
+ ManualEnvironmentEdge edge = new ManualEnvironmentEdge();
+ EnvironmentEdgeManager.injectEdge(edge);
+
+ try {
+ for (int i = 1; i <= 10; i++) {
+ edge.incValue(wrapper.getPeriod());
+ retVal.incrementAndGet();
+ wrapper.forceRecompute();
+
+ int numRegions = regions.size();
+ int totalStores = numRegions * numStoresPerRegion;
+
+ // there are N regions, and each has M stores. everything gets
aggregated, so
+ // multiply expected values accordingly
+ int expectedForRegions = retVal.get() * numRegions;
+ int expectedForStores = retVal.get() * totalStores;
+
+ assertEquals(totalStores, wrapper.getNumStores());
+ assertEquals(expectedForStores, wrapper.getFlushedCellsCount());
+ assertEquals(expectedForStores, wrapper.getCompactedCellsCount());
+ assertEquals(expectedForStores, wrapper.getMajorCompactedCellsCount());
+ assertEquals(expectedForStores, wrapper.getFlushedCellsSize());
+ assertEquals(expectedForStores, wrapper.getCompactedCellsSize());
+ assertEquals(expectedForStores, wrapper.getMajorCompactedCellsSize());
+ assertEquals(expectedForRegions,
wrapper.getCellsCountCompactedFromMob());
+ assertEquals(expectedForRegions,
wrapper.getCellsCountCompactedToMob());
+ assertEquals(expectedForRegions,
wrapper.getCellsSizeCompactedFromMob());
+ assertEquals(expectedForRegions, wrapper.getCellsSizeCompactedToMob());
+ assertEquals(expectedForRegions, wrapper.getMobFlushCount());
+ assertEquals(expectedForRegions, wrapper.getMobFlushedCellsCount());
+ assertEquals(expectedForRegions, wrapper.getMobFlushedCellsSize());
+ assertEquals(expectedForRegions, wrapper.getMobScanCellsCount());
+ assertEquals(expectedForRegions, wrapper.getMobScanCellsSize());
+ assertEquals(expectedForRegions,
wrapper.getCheckAndMutateChecksFailed());
+ assertEquals(expectedForRegions,
wrapper.getCheckAndMutateChecksPassed());
+ assertEquals(expectedForStores, wrapper.getStoreFileIndexSize());
+ assertEquals(expectedForStores, wrapper.getTotalStaticIndexSize());
+ assertEquals(expectedForStores, wrapper.getTotalStaticBloomSize());
+ assertEquals(expectedForStores, wrapper.getBloomFilterRequestsCount());
+ assertEquals(expectedForStores,
wrapper.getBloomFilterNegativeResultsCount());
+ assertEquals(expectedForStores,
wrapper.getBloomFilterEligibleRequestsCount());
+ assertEquals(expectedForRegions, wrapper.getNumMutationsWithoutWAL());
+ assertEquals(expectedForRegions, wrapper.getDataInMemoryWithoutWAL());
+ assertEquals(expectedForRegions, wrapper.getAverageRegionSize());
+ assertEquals(expectedForRegions, wrapper.getBlockedRequestsCount());
+ assertEquals(expectedForStores, wrapper.getNumReferenceFiles());
+ assertEquals(expectedForStores, wrapper.getMemStoreSize());
+ assertEquals(expectedForStores, wrapper.getOnHeapMemStoreSize());
+ assertEquals(expectedForStores, wrapper.getOffHeapMemStoreSize());
+ assertEquals(expectedForStores, wrapper.getStoreFileSize());
+ assertEquals(expectedForRegions, wrapper.getReadRequestsCount());
+ assertEquals(expectedForRegions,
wrapper.getFilteredReadRequestsCount());
+ assertEquals(expectedForRegions, wrapper.getWriteRequestsCount());
+ assertEquals(expectedForRegions * 2,
wrapper.getTotalRowActionRequestCount());
+
+ // If we have N regions, each with M stores. That's N*M stores in
total. In creating those
+ // stores, we increment the number and age of storefiles for each one.
So the first
+ // store has 1 file of 1 age, then 2 files of 2 age, etc.
+ // formula for 1+2+3..+n
+ assertEquals((totalStores * (totalStores + 1)) / 2,
wrapper.getNumStoreFiles());
+ assertEquals(totalStores, wrapper.getMaxStoreFiles());
+ assertEquals(totalStores, wrapper.getMaxStoreFileAge());
+ assertEquals(1, wrapper.getMinStoreFileAge());
+ assertEquals(totalStores / 2, wrapper.getAvgStoreFileAge());
+
+ // there are four regions, two are primary and the other two secondary
+ // for each type, one region has 100% locality, the other has 0%.
+ // this just proves we correctly aggregate for each
+ assertEquals(50.0, wrapper.getPercentFileLocal(), 0.0001);
+ assertEquals(50.0, wrapper.getPercentFileLocalSecondaryRegions(),
0.0001);
+
+ // readRequestCount and writeRequestCount are tracking the value of i,
which increases by 1
+ // each interval. There are N regions, so the delta each interval is
N*i=N. So the rate is
+ // simply N / period.
+ assertEquals((double) numRegions / metricsPeriodSec,
wrapper.getReadRequestsRatePerSecond(),
+ 0.0001);
+ assertEquals((double) numRegions / metricsPeriodSec,
+ wrapper.getWriteRequestsRatePerSecond(), 0.0001);
+ // total of above, so multiply by 2
+ assertEquals((double) numRegions / metricsPeriodSec * 2,
wrapper.getRequestsPerSecond(),
+ 0.0001);
+ }
+ } finally {
+ EnvironmentEdgeManager.reset();
+ }
+ }
+
+ private HRegion getMockedRegion(Answer defaultAnswer, String name, String
localOnHost,
+ boolean isPrimary, AtomicInteger storeFileCount) {
+ RegionInfo regionInfo = mock(RegionInfo.class);
+ when(regionInfo.getEncodedName()).thenReturn(name);
+ if (!isPrimary) {
+ when(regionInfo.getReplicaId()).thenReturn(RegionInfo.DEFAULT_REPLICA_ID
+ 1);
+ }
+ HDFSBlocksDistribution distribution = new HDFSBlocksDistribution();
+ distribution.addHostsAndBlockWeight(new String[] { localOnHost }, 100);
+
+ HStore store = getMockedStore(HStore.class, defaultAnswer, storeFileCount);
+ HMobStore mobStore = getMockedStore(HMobStore.class, defaultAnswer,
storeFileCount);
+
+ HRegion region = mock(HRegion.class, defaultAnswer);
+ when(region.getRegionInfo()).thenReturn(regionInfo);
+ when(region.getHDFSBlocksDistribution()).thenReturn(distribution);
+ when(region.getStores()).thenReturn(Lists.newArrayList(store, mobStore));
+ return region;
+ }
+
+ private <T extends HStore> T getMockedStore(Class<T> clazz, Answer
defaultAnswer,
+ AtomicInteger storeFileCount) {
+ T store = mock(clazz, defaultAnswer);
+ int storeFileCountVal = storeFileCount.getAndIncrement();
+ when(store.getStorefilesCount()).thenReturn(storeFileCountVal);
+
when(store.getAvgStoreFileAge()).thenReturn(OptionalDouble.of(storeFileCountVal));
+
when(store.getMaxStoreFileAge()).thenReturn(OptionalLong.of(storeFileCountVal));
+
when(store.getMinStoreFileAge()).thenReturn(OptionalLong.of(storeFileCountVal));
+ MemStoreSize memStore = mock(MemStoreSize.class, defaultAnswer);
+ when(store.getMemStoreSize()).thenReturn(memStore);
+ return store;
+ }
+
+}