001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.hbase.regionserver; 020 021import java.io.Closeable; 022import java.io.IOException; 023import java.util.Map; 024import java.util.OptionalDouble; 025import java.util.OptionalLong; 026import java.util.concurrent.ScheduledExecutorService; 027import java.util.concurrent.ScheduledFuture; 028import java.util.concurrent.TimeUnit; 029 030import org.apache.hadoop.hbase.CompatibilitySingletonFactory; 031import org.apache.hadoop.hbase.client.RegionInfo; 032import org.apache.hadoop.hbase.client.TableDescriptor; 033import org.apache.hadoop.hbase.util.EnvironmentEdgeManager; 034import org.apache.hadoop.metrics2.MetricsExecutor; 035import org.apache.yetus.audience.InterfaceAudience; 036import org.slf4j.Logger; 037import org.slf4j.LoggerFactory; 038 039@InterfaceAudience.Private 040public class MetricsRegionWrapperImpl implements MetricsRegionWrapper, Closeable { 041 042 private static final Logger LOG = LoggerFactory.getLogger(MetricsRegionWrapperImpl.class); 043 044 public static final int PERIOD = 45; 045 public static final String UNKNOWN = "unknown"; 046 047 private final HRegion region; 048 private ScheduledExecutorService executor; 049 private Runnable runnable; 050 private long numStoreFiles; 051 private long memstoreSize; 052 private long storeFileSize; 053 private long maxStoreFileAge; 054 private long minStoreFileAge; 055 private long avgStoreFileAge; 056 private long numReferenceFiles; 057 private long maxFlushQueueSize; 058 private long maxCompactionQueueSize; 059 060 private ScheduledFuture<?> regionMetricsUpdateTask; 061 062 public MetricsRegionWrapperImpl(HRegion region) { 063 this.region = region; 064 this.executor = CompatibilitySingletonFactory.getInstance(MetricsExecutor.class).getExecutor(); 065 this.runnable = new HRegionMetricsWrapperRunnable(); 066 this.regionMetricsUpdateTask = this.executor.scheduleWithFixedDelay(this.runnable, PERIOD, 067 PERIOD, TimeUnit.SECONDS); 068 } 069 070 @Override 071 public String getTableName() { 072 TableDescriptor tableDesc = this.region.getTableDescriptor(); 073 if (tableDesc == null) { 074 return UNKNOWN; 075 } 076 return tableDesc.getTableName().getQualifierAsString(); 077 } 078 079 @Override 080 public String getNamespace() { 081 TableDescriptor tableDesc = this.region.getTableDescriptor(); 082 if (tableDesc == null) { 083 return UNKNOWN; 084 } 085 return tableDesc.getTableName().getNamespaceAsString(); 086 } 087 088 089 @Override 090 public String getRegionName() { 091 RegionInfo regionInfo = this.region.getRegionInfo(); 092 if (regionInfo == null) { 093 return UNKNOWN; 094 } 095 return regionInfo.getEncodedName(); 096 } 097 098 @Override 099 public long getNumStores() { 100 Map<byte[], HStore> stores = this.region.stores; 101 if (stores == null) { 102 return 0; 103 } 104 return stores.size(); 105 } 106 107 @Override 108 public long getNumStoreFiles() { 109 return numStoreFiles; 110 } 111 112 @Override 113 public long getMemStoreSize() { 114 return memstoreSize; 115 } 116 117 @Override 118 public long getStoreFileSize() { 119 return storeFileSize; 120 } 121 122 @Override 123 public long getReadRequestCount() { 124 return this.region.getReadRequestsCount(); 125 } 126 127 @Override 128 public long getFilteredReadRequestCount() { 129 return this.region.getFilteredReadRequestsCount(); 130 } 131 132 @Override 133 public long getWriteRequestCount() { 134 return this.region.getWriteRequestsCount(); 135 } 136 137 @Override 138 public long getNumFilesCompacted() { 139 return this.region.compactionNumFilesCompacted.sum(); 140 } 141 142 @Override 143 public long getNumBytesCompacted() { 144 return this.region.compactionNumBytesCompacted.sum(); 145 } 146 147 @Override 148 public long getNumCompactionsCompleted() { 149 return this.region.compactionsFinished.sum(); 150 } 151 152 @Override 153 public long getLastMajorCompactionAge() { 154 long lastMajorCompactionTs = 0L; 155 try { 156 lastMajorCompactionTs = this.region.getOldestHfileTs(true); 157 } catch (IOException ioe) { 158 LOG.error("Could not load HFile info ", ioe); 159 } 160 long now = EnvironmentEdgeManager.currentTime(); 161 return now - lastMajorCompactionTs; 162 } 163 164 @Override 165 public long getTotalRequestCount() { 166 return getReadRequestCount() + getWriteRequestCount(); 167 } 168 169 @Override 170 public long getNumCompactionsFailed() { 171 return this.region.compactionsFailed.sum(); 172 } 173 174 @Override 175 public long getNumCompactionsQueued() { 176 return this.region.compactionsQueued.sum(); 177 } 178 179 @Override 180 public long getNumFlushesQueued() { 181 return this.region.flushesQueued.sum(); 182 } 183 184 @Override 185 public long getMaxCompactionQueueSize() { 186 return maxCompactionQueueSize; 187 } 188 189 @Override 190 public long getMaxFlushQueueSize() { 191 return maxFlushQueueSize; 192 } 193 194 @Override 195 public long getMaxStoreFileAge() { 196 return maxStoreFileAge; 197 } 198 199 @Override 200 public long getMinStoreFileAge() { 201 return minStoreFileAge; 202 } 203 204 @Override 205 public long getAvgStoreFileAge() { 206 return avgStoreFileAge; 207 } 208 209 @Override 210 public long getNumReferenceFiles() { 211 return numReferenceFiles; 212 } 213 214 @Override 215 public int getRegionHashCode() { 216 return this.region.hashCode(); 217 } 218 219 public class HRegionMetricsWrapperRunnable implements Runnable { 220 221 @Override 222 public void run() { 223 long tempNumStoreFiles = 0; 224 long tempMemstoreSize = 0; 225 long tempStoreFileSize = 0; 226 long tempMaxStoreFileAge = 0; 227 long tempMinStoreFileAge = Long.MAX_VALUE; 228 long tempNumReferenceFiles = 0; 229 long tempMaxCompactionQueueSize = 0; 230 long tempMaxFlushQueueSize = 0; 231 232 long avgAgeNumerator = 0; 233 long numHFiles = 0; 234 if (region.stores != null) { 235 for (Store store : region.stores.values()) { 236 tempNumStoreFiles += store.getStorefilesCount(); 237 tempMemstoreSize += store.getMemStoreSize().getDataSize(); 238 tempStoreFileSize += store.getStorefilesSize(); 239 OptionalLong storeMaxStoreFileAge = store.getMaxStoreFileAge(); 240 if (storeMaxStoreFileAge.isPresent() && 241 storeMaxStoreFileAge.getAsLong() > tempMaxStoreFileAge) { 242 tempMaxStoreFileAge = storeMaxStoreFileAge.getAsLong(); 243 } 244 245 OptionalLong storeMinStoreFileAge = store.getMinStoreFileAge(); 246 if (storeMinStoreFileAge.isPresent() && 247 storeMinStoreFileAge.getAsLong() < tempMinStoreFileAge) { 248 tempMinStoreFileAge = storeMinStoreFileAge.getAsLong(); 249 } 250 251 long storeHFiles = store.getNumHFiles(); 252 numHFiles += storeHFiles; 253 tempNumReferenceFiles += store.getNumReferenceFiles(); 254 255 OptionalDouble storeAvgStoreFileAge = store.getAvgStoreFileAge(); 256 if (storeAvgStoreFileAge.isPresent()) { 257 avgAgeNumerator += (long) storeAvgStoreFileAge.getAsDouble() * storeHFiles; 258 } 259 } 260 } 261 262 numStoreFiles = tempNumStoreFiles; 263 memstoreSize = tempMemstoreSize; 264 storeFileSize = tempStoreFileSize; 265 maxStoreFileAge = tempMaxStoreFileAge; 266 if (tempMinStoreFileAge != Long.MAX_VALUE) { 267 minStoreFileAge = tempMinStoreFileAge; 268 } 269 270 if (numHFiles != 0) { 271 avgStoreFileAge = avgAgeNumerator / numHFiles; 272 } 273 274 numReferenceFiles = tempNumReferenceFiles; 275 tempMaxCompactionQueueSize = getNumCompactionsQueued(); 276 tempMaxFlushQueueSize = getNumFlushesQueued(); 277 if (tempMaxCompactionQueueSize > maxCompactionQueueSize) { 278 maxCompactionQueueSize = tempMaxCompactionQueueSize; 279 } 280 if (tempMaxFlushQueueSize > maxFlushQueueSize) { 281 maxFlushQueueSize = tempMaxFlushQueueSize; 282 } 283 } 284 } 285 286 @Override 287 public void close() throws IOException { 288 regionMetricsUpdateTask.cancel(true); 289 } 290 291 /** 292 * Get the replica id of this region. 293 */ 294 @Override 295 public int getReplicaId() { 296 return region.getRegionInfo().getReplicaId(); 297 } 298 299}