View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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            // this will add the Wrapper to the list of TableMetrics
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 }