1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.regionserver;
20
21 import java.io.Closeable;
22 import java.io.IOException;
23 import java.util.HashMap;
24 import java.util.Map;
25 import java.util.Set;
26 import java.util.concurrent.ConcurrentHashMap;
27 import java.util.concurrent.ScheduledExecutorService;
28 import java.util.concurrent.ScheduledFuture;
29 import java.util.concurrent.TimeUnit;
30
31 import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.TableName;
34 import org.apache.hadoop.hbase.classification.InterfaceAudience;
35 import org.apache.hadoop.metrics2.MetricsExecutor;
36
37 import com.google.common.collect.Sets;
38
39 @InterfaceAudience.Private
40 public class MetricsTableWrapperAggregateImpl implements MetricsTableWrapperAggregate, Closeable {
41 private final HRegionServer regionServer;
42 private ScheduledExecutorService executor;
43 private Runnable runnable;
44 private long period;
45 private ScheduledFuture<?> tableMetricsUpdateTask;
46 private ConcurrentHashMap<TableName, MetricsTableValues> metricsTableMap
47 = new ConcurrentHashMap<>();
48
49 public MetricsTableWrapperAggregateImpl(final HRegionServer regionServer) {
50 this.regionServer = regionServer;
51 this.period = regionServer.conf.getLong(HConstants.REGIONSERVER_METRICS_PERIOD,
52 HConstants.DEFAULT_REGIONSERVER_METRICS_PERIOD) + 1000;
53 this.executor = CompatibilitySingletonFactory.getInstance(MetricsExecutor.class).getExecutor();
54 this.runnable = new TableMetricsWrapperRunnable();
55 this.tableMetricsUpdateTask = this.executor.scheduleWithFixedDelay(this.runnable, period,
56 this.period, TimeUnit.MILLISECONDS);
57 }
58
59 public class TableMetricsWrapperRunnable implements Runnable {
60
61 @Override
62 public void run() {
63 Map<TableName, MetricsTableValues> localMetricsTableMap = new HashMap<>();
64
65 for (Region r : regionServer.getOnlineRegionsLocalContext()) {
66 TableName tbl = r.getTableDesc().getTableName();
67 MetricsTableValues mt = localMetricsTableMap.get(tbl);
68 if (mt == null) {
69 mt = new MetricsTableValues();
70 localMetricsTableMap.put(tbl, mt);
71 }
72
73 if (r.getStores() != null) {
74 for (Store store : r.getStores()) {
75 mt.storeFileCount += store.getStorefilesCount();
76 mt.memstoreSize += store.getMemStoreSize();
77 mt.storeFileSize += store.getStorefilesSize();
78 mt.referenceFileCount += store.getNumReferenceFiles();
79
80 mt.maxStoreFileAge = Math.max(mt.maxStoreFileAge, store.getMaxStoreFileAge());
81 mt.minStoreFileAge = Math.min(mt.minStoreFileAge, store.getMinStoreFileAge());
82 mt.totalStoreFileAge = store.getAvgStoreFileAge() * store.getStorefilesCount();
83 mt.storeCount += 1;
84 }
85 }
86
87 mt.regionCount += 1;
88
89 mt.readRequestCount += r.getReadRequestsCount();
90 mt.writeRequestCount += r.getWriteRequestsCount();
91 }
92
93 for (Map.Entry<TableName, MetricsTableValues> entry : localMetricsTableMap.entrySet()) {
94 TableName tbl = entry.getKey();
95 if (metricsTableMap.get(tbl) == null) {
96
97 CompatibilitySingletonFactory
98 .getInstance(MetricsRegionServerSourceFactory.class)
99 .getTableAggregate()
100 .getOrCreateTableSource(tbl.getNameAsString(), MetricsTableWrapperAggregateImpl.this);
101
102 }
103 metricsTableMap.put(entry.getKey(), entry.getValue());
104 }
105 Set<TableName> existingTableNames = Sets.newHashSet(metricsTableMap.keySet());
106 existingTableNames.removeAll(localMetricsTableMap.keySet());
107 MetricsTableAggregateSource agg = CompatibilitySingletonFactory
108 .getInstance(MetricsRegionServerSourceFactory.class).getTableAggregate();
109 for (TableName table : existingTableNames) {
110 agg.deleteTableSource(table.getNameAsString());
111 if (metricsTableMap.get(table) != null) {
112 metricsTableMap.remove(table);
113 }
114 }
115 }
116 }
117
118 @Override
119 public long getReadRequestCount(String table) {
120 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
121 if (metricsTable == null)
122 return 0;
123 else
124 return metricsTable.readRequestCount;
125 }
126
127 @Override
128 public long getWriteRequestCount(String table) {
129 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
130 if (metricsTable == null) {
131 return 0;
132 }
133 return metricsTable.writeRequestCount;
134 }
135
136 @Override
137 public long getTotalRequestsCount(String table) {
138 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
139 if (metricsTable == null) {
140 return 0;
141 }
142 return metricsTable.readRequestCount + metricsTable.writeRequestCount;
143 }
144
145 @Override
146 public long getMemstoreSize(String table) {
147 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
148 if (metricsTable == null) {
149 return 0;
150 }
151 return metricsTable.memstoreSize;
152 }
153
154 @Override
155 public long getStoreFileSize(String table) {
156 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
157 if (metricsTable == null) {
158 return 0;
159 }
160 return metricsTable.storeFileSize;
161 }
162
163 @Override
164 public long getTableSize(String table) {
165 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
166 if (metricsTable == null) {
167 return 0;
168 }
169 return metricsTable.memstoreSize + metricsTable.storeFileSize;
170 }
171
172 @Override
173 public long getNumRegions(String table) {
174 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
175 if (metricsTable == null) {
176 return 0;
177 }
178 return metricsTable.regionCount;
179 }
180
181 @Override
182 public long getNumStores(String table) {
183 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
184 if (metricsTable == null) {
185 return 0;
186 }
187 return metricsTable.storeCount;
188 }
189
190 @Override
191 public long getNumStoreFiles(String table) {
192 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
193 if (metricsTable == null) {
194 return 0;
195 }
196 return metricsTable.storeFileCount;
197 }
198
199 @Override
200 public long getMaxStoreFileAge(String table) {
201 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
202 if (metricsTable == null) {
203 return 0;
204 }
205 return metricsTable.maxStoreFileAge;
206 }
207
208 @Override
209 public long getMinStoreFileAge(String table) {
210 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
211 if (metricsTable == null) {
212 return 0;
213 }
214
215 return metricsTable.minStoreFileAge == Long.MAX_VALUE ? 0 : metricsTable.minStoreFileAge;
216 }
217
218 @Override
219 public long getAvgStoreFileAge(String table) {
220 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
221 if (metricsTable == null) {
222 return 0;
223 }
224
225 return metricsTable.storeFileCount == 0
226 ? 0
227 : (metricsTable.totalStoreFileAge / metricsTable.storeFileCount);
228 }
229
230 @Override
231 public long getNumReferenceFiles(String table) {
232 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
233 if (metricsTable == null) {
234 return 0;
235 }
236 return metricsTable.referenceFileCount;
237 }
238
239 @Override
240 public long getAvgRegionSize(String table) {
241 MetricsTableValues metricsTable = metricsTableMap.get(TableName.valueOf(table));
242 if (metricsTable == null) {
243 return 0;
244 }
245
246 return metricsTable.regionCount == 0
247 ? 0
248 : (metricsTable.memstoreSize + metricsTable.storeFileSize) / metricsTable.regionCount;
249 }
250
251 @Override
252 public void close() throws IOException {
253 tableMetricsUpdateTask.cancel(true);
254 }
255
256 private static class MetricsTableValues {
257 long readRequestCount;
258 long writeRequestCount;
259 long memstoreSize;
260 long regionCount;
261 long storeCount;
262 long storeFileCount;
263 long storeFileSize;
264 long maxStoreFileAge;
265 long minStoreFileAge = Long.MAX_VALUE;
266 long totalStoreFileAge;
267 long referenceFileCount;
268 }
269
270 }