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.HashMap; 024import java.util.Map; 025import java.util.Set; 026import java.util.concurrent.ConcurrentHashMap; 027import java.util.concurrent.ScheduledExecutorService; 028import java.util.concurrent.ScheduledFuture; 029import java.util.concurrent.TimeUnit; 030 031import org.apache.hadoop.hbase.CompatibilitySingletonFactory; 032import org.apache.hadoop.hbase.HConstants; 033import org.apache.hadoop.hbase.TableName; 034import org.apache.yetus.audience.InterfaceAudience; 035import org.apache.hadoop.metrics2.MetricsExecutor; 036 037import org.apache.hbase.thirdparty.com.google.common.collect.Sets; 038 039@InterfaceAudience.Private 040public class MetricsTableWrapperAggregateImpl implements MetricsTableWrapperAggregate, Closeable { 041 private final HRegionServer regionServer; 042 private ScheduledExecutorService executor; 043 private Runnable runnable; 044 private long period; 045 private ScheduledFuture<?> tableMetricsUpdateTask; 046 private ConcurrentHashMap<TableName, MetricsTableValues> metricsTableMap 047 = new ConcurrentHashMap<>(); 048 049 public MetricsTableWrapperAggregateImpl(final HRegionServer regionServer) { 050 this.regionServer = regionServer; 051 this.period = regionServer.conf.getLong(HConstants.REGIONSERVER_METRICS_PERIOD, 052 HConstants.DEFAULT_REGIONSERVER_METRICS_PERIOD) + 1000; 053 this.executor = CompatibilitySingletonFactory.getInstance(MetricsExecutor.class).getExecutor(); 054 this.runnable = new TableMetricsWrapperRunnable(); 055 this.tableMetricsUpdateTask = this.executor.scheduleWithFixedDelay(this.runnable, period, 056 this.period, TimeUnit.MILLISECONDS); 057 } 058 059 public class TableMetricsWrapperRunnable implements Runnable { 060 061 @Override 062 public void run() { 063 Map<TableName, MetricsTableValues> localMetricsTableMap = new HashMap<>(); 064 065 for (Region r : regionServer.getOnlineRegionsLocalContext()) { 066 TableName tbl = r.getTableDescriptor().getTableName(); 067 MetricsTableValues mt = localMetricsTableMap.get(tbl); 068 if (mt == null) { 069 mt = new MetricsTableValues(); 070 localMetricsTableMap.put(tbl, mt); 071 } 072 if (r.getStores() != null) { 073 for (Store store : r.getStores()) { 074 mt.storeFileCount += store.getStorefilesCount(); 075 mt.memstoreSize += (store.getMemStoreSize().getDataSize() + 076 store.getMemStoreSize().getHeapSize() + store.getMemStoreSize().getOffHeapSize()); 077 mt.storeFileSize += store.getStorefilesSize(); 078 mt.referenceFileCount += store.getNumReferenceFiles(); 079 080 mt.maxStoreFileAge = Math.max(mt.maxStoreFileAge, store.getMaxStoreFileAge().getAsLong()); 081 mt.minStoreFileAge = Math.min(mt.minStoreFileAge, store.getMinStoreFileAge().getAsLong()); 082 mt.totalStoreFileAge = (long)store.getAvgStoreFileAge().getAsDouble() * 083 store.getStorefilesCount(); 084 mt.storeCount += 1; 085 } 086 mt.regionCount += 1; 087 088 mt.readRequestCount += r.getReadRequestsCount(); 089 mt.filteredReadRequestCount += getFilteredReadRequestCount(tbl.getNameAsString()); 090 mt.writeRequestCount += r.getWriteRequestsCount(); 091 092 } 093 } 094 095 for (Map.Entry<TableName, MetricsTableValues> entry : localMetricsTableMap.entrySet()) { 096 TableName tbl = entry.getKey(); 097 if (metricsTableMap.get(tbl) == null) { 098 // this will add the Wrapper to the list of TableMetrics 099 CompatibilitySingletonFactory 100 .getInstance(MetricsRegionServerSourceFactory.class) 101 .getTableAggregate() 102 .getOrCreateTableSource(tbl.getNameAsString(), MetricsTableWrapperAggregateImpl.this); 103 } 104 metricsTableMap.put(entry.getKey(), entry.getValue()); 105 } 106 Set<TableName> existingTableNames = Sets.newHashSet(metricsTableMap.keySet()); 107 existingTableNames.removeAll(localMetricsTableMap.keySet()); 108 MetricsTableAggregateSource agg = CompatibilitySingletonFactory 109 .getInstance(MetricsRegionServerSourceFactory.class).getTableAggregate(); 110 for (TableName table : existingTableNames) { 111 agg.deleteTableSource(table.getNameAsString()); 112 if (metricsTableMap.get(table) != null) { 113 metricsTableMap.remove(table); 114 } 115 } 116 } 117 } 118 119 @Override 120 public long getReadRequestCount(String table) { 121 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 122 if (metricsTable == null) { 123 return 0; 124 } else { 125 return metricsTable.readRequestCount; 126 } 127 } 128 129 public long getFilteredReadRequestCount(String table) { 130 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 131 if (metricsTable == null) { 132 return 0; 133 } 134 return metricsTable.filteredReadRequestCount; 135 } 136 137 @Override 138 public long getWriteRequestCount(String table) { 139 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 140 if (metricsTable == null) { 141 return 0; 142 } else { 143 return metricsTable.writeRequestCount; 144 } 145 } 146 147 @Override 148 public long getTotalRequestsCount(String table) { 149 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 150 if (metricsTable == null) { 151 return 0; 152 } else { 153 return metricsTable.readRequestCount + metricsTable.writeRequestCount; 154 } 155 } 156 157 @Override 158 public long getMemStoreSize(String table) { 159 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 160 if (metricsTable == null) { 161 return 0; 162 } else { 163 return metricsTable.memstoreSize; 164 } 165 } 166 167 @Override 168 public long getStoreFileSize(String table) { 169 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 170 if (metricsTable == null) { 171 return 0; 172 } else { 173 return metricsTable.storeFileSize; 174 } 175 } 176 177 @Override 178 public long getTableSize(String table) { 179 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 180 if (metricsTable == null) { 181 return 0; 182 } else { 183 return metricsTable.memstoreSize + metricsTable.storeFileSize; 184 } 185 } 186 187 public long getNumRegions(String table) { 188 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 189 if (metricsTable == null) { 190 return 0; 191 } 192 return metricsTable.regionCount; 193 } 194 195 @Override 196 public long getNumStores(String table) { 197 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 198 if (metricsTable == null) { 199 return 0; 200 } 201 return metricsTable.storeCount; 202 } 203 204 @Override 205 public long getNumStoreFiles(String table) { 206 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 207 if (metricsTable == null) { 208 return 0; 209 } 210 return metricsTable.storeFileCount; 211 } 212 213 @Override 214 public long getMaxStoreFileAge(String table) { 215 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 216 if (metricsTable == null) { 217 return 0; 218 } 219 return metricsTable.maxStoreFileAge; 220 } 221 222 @Override 223 public long getMinStoreFileAge(String table) { 224 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 225 if (metricsTable == null) { 226 return 0; 227 } 228 return metricsTable.minStoreFileAge == Long.MAX_VALUE ? 0 : metricsTable.minStoreFileAge; 229 } 230 231 @Override 232 public long getAvgStoreFileAge(String table) { 233 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 234 if (metricsTable == null) { 235 return 0; 236 } 237 238 return metricsTable.storeFileCount == 0 239 ? 0 240 : (metricsTable.totalStoreFileAge / metricsTable.storeFileCount); 241 } 242 243 @Override 244 public long getNumReferenceFiles(String table) { 245 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 246 if (metricsTable == null) { 247 return 0; 248 } 249 return metricsTable.referenceFileCount; 250 } 251 252 @Override 253 public long getAvgRegionSize(String table) { 254 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 255 if (metricsTable == null) { 256 return 0; 257 } 258 return metricsTable.regionCount == 0 259 ? 0 260 : (metricsTable.memstoreSize + metricsTable.storeFileSize) / metricsTable.regionCount; 261 } 262 263 public long getCpRequestCount(String table) { 264 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table)); 265 if (metricsTable == null) { 266 return 0; 267 } 268 return metricsTable.cpRequestCount; 269 } 270 271 @Override 272 public void close() throws IOException { 273 tableMetricsUpdateTask.cancel(true); 274 } 275 276 private static class MetricsTableValues { 277 long readRequestCount; 278 long filteredReadRequestCount; 279 long writeRequestCount; 280 long memstoreSize; 281 long regionCount; 282 long storeCount; 283 long storeFileCount; 284 long storeFileSize; 285 long maxStoreFileAge; 286 long minStoreFileAge = Long.MAX_VALUE; 287 long totalStoreFileAge; 288 long referenceFileCount; 289 long cpRequestCount; 290 } 291 292}