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 */
018package org.apache.hadoop.hbase.regionserver;
019
020import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
021import org.apache.hadoop.hbase.TableName;
022import org.apache.hadoop.hbase.metrics.Meter;
023import org.apache.hadoop.hbase.metrics.MetricRegistries;
024import org.apache.hadoop.hbase.metrics.MetricRegistry;
025import org.apache.hadoop.hbase.metrics.Timer;
026import org.apache.hadoop.conf.Configuration;
027import org.apache.yetus.audience.InterfaceAudience;
028import org.apache.yetus.audience.InterfaceStability;
029
030/**
031 * <p>
032 * This class is for maintaining the various regionserver statistics
033 * and publishing them through the metrics interfaces.
034 * </p>
035 * This class has a number of metrics variables that are publicly accessible;
036 * these variables (objects) have methods to update their values.
037 */
038@InterfaceStability.Evolving
039@InterfaceAudience.Private
040public class MetricsRegionServer {
041  public static final String RS_ENABLE_TABLE_METRICS_KEY =
042      "hbase.regionserver.enable.table.latencies";
043  public static final boolean RS_ENABLE_TABLE_METRICS_DEFAULT = true;
044
045  private final MetricsRegionServerSource serverSource;
046  private final MetricsRegionServerWrapper regionServerWrapper;
047  private RegionServerTableMetrics tableMetrics;
048  private final MetricsTable metricsTable;
049  private final MetricsUserAggregate userAggregate;
050  private MetricsRegionServerQuotaSource quotaSource;
051
052  private MetricRegistry metricRegistry;
053  private Timer bulkLoadTimer;
054  private Meter serverReadQueryMeter;
055  private Meter serverWriteQueryMeter;
056
057  public MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper, Configuration conf,
058      MetricsTable metricsTable) {
059    this(regionServerWrapper,
060        CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)
061            .createServer(regionServerWrapper), createTableMetrics(conf), metricsTable,
062        MetricsUserAggregateFactory.getMetricsUserAggregate(conf));
063
064    // Create hbase-metrics module based metrics. The registry should already be registered by the
065    // MetricsRegionServerSource
066    metricRegistry = MetricRegistries.global().get(serverSource.getMetricRegistryInfo()).get();
067
068    // create and use metrics from the new hbase-metrics based registry.
069    bulkLoadTimer = metricRegistry.timer("Bulkload");
070
071    serverReadQueryMeter = metricRegistry.meter("ServerReadQueryPerSecond");
072    serverWriteQueryMeter = metricRegistry.meter("ServerWriteQueryPerSecond");
073    quotaSource = CompatibilitySingletonFactory.getInstance(MetricsRegionServerQuotaSource.class);
074  }
075
076  MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper,
077      MetricsRegionServerSource serverSource, RegionServerTableMetrics tableMetrics,
078      MetricsTable metricsTable, MetricsUserAggregate userAggregate) {
079    this.regionServerWrapper = regionServerWrapper;
080    this.serverSource = serverSource;
081    this.tableMetrics = tableMetrics;
082    this.metricsTable = metricsTable;
083    this.userAggregate = userAggregate;
084  }
085
086  /**
087   * Creates an instance of {@link RegionServerTableMetrics} only if the feature is enabled.
088   */
089  static RegionServerTableMetrics createTableMetrics(Configuration conf) {
090    if (conf.getBoolean(RS_ENABLE_TABLE_METRICS_KEY, RS_ENABLE_TABLE_METRICS_DEFAULT)) {
091      return new RegionServerTableMetrics();
092    }
093    return null;
094  }
095
096  public MetricsRegionServerSource getMetricsSource() {
097    return serverSource;
098  }
099
100  public MetricsUserAggregate getMetricsUserAggregate() {
101    return userAggregate;
102  }
103
104  public MetricsRegionServerWrapper getRegionServerWrapper() {
105    return regionServerWrapper;
106  }
107
108  public void updatePutBatch(TableName tn, long t) {
109    if (tableMetrics != null && tn != null) {
110      tableMetrics.updatePutBatch(tn, t);
111    }
112    if (t > 1000) {
113      serverSource.incrSlowPut();
114    }
115    serverSource.updatePutBatch(t);
116  }
117
118  public void updatePut(TableName tn, long t) {
119    if (tableMetrics != null && tn != null) {
120      tableMetrics.updatePut(tn, t);
121    }
122    serverSource.updatePut(t);
123    userAggregate.updatePut(t);
124  }
125
126  public void updateDelete(TableName tn, long t) {
127    if (tableMetrics != null && tn != null) {
128      tableMetrics.updateDelete(tn, t);
129    }
130    serverSource.updateDelete(t);
131    userAggregate.updateDelete(t);
132  }
133
134  public void updateDeleteBatch(TableName tn, long t) {
135    if (tableMetrics != null && tn != null) {
136      tableMetrics.updateDeleteBatch(tn, t);
137    }
138    if (t > 1000) {
139      serverSource.incrSlowDelete();
140    }
141    serverSource.updateDeleteBatch(t);
142  }
143
144  public void updateCheckAndDelete(TableName tn, long t) {
145    if (tableMetrics != null && tn != null) {
146      tableMetrics.updateCheckAndDelete(tn, t);
147    }
148    serverSource.updateCheckAndDelete(t);
149  }
150
151  public void updateCheckAndPut(TableName tn, long t) {
152    if (tableMetrics != null && tn != null) {
153      tableMetrics.updateCheckAndPut(tn, t);
154    }
155    serverSource.updateCheckAndPut(t);
156  }
157
158  public void updateCheckAndMutate(TableName tn, long t) {
159    if (tableMetrics != null && tn != null) {
160      tableMetrics.updateCheckAndMutate(tn, t);
161    }
162    serverSource.updateCheckAndMutate(t);
163  }
164
165  public void updateGet(TableName tn, long t) {
166    if (tableMetrics != null && tn != null) {
167      tableMetrics.updateGet(tn, t);
168    }
169    if (t > 1000) {
170      serverSource.incrSlowGet();
171    }
172    serverSource.updateGet(t);
173    userAggregate.updateGet(t);
174  }
175
176  public void updateIncrement(TableName tn, long t) {
177    if (tableMetrics != null && tn != null) {
178      tableMetrics.updateIncrement(tn, t);
179    }
180    if (t > 1000) {
181      serverSource.incrSlowIncrement();
182    }
183    serverSource.updateIncrement(t);
184    userAggregate.updateIncrement(t);
185  }
186
187  public void updateAppend(TableName tn, long t) {
188    if (tableMetrics != null && tn != null) {
189      tableMetrics.updateAppend(tn, t);
190    }
191    if (t > 1000) {
192      serverSource.incrSlowAppend();
193    }
194    serverSource.updateAppend(t);
195    userAggregate.updateAppend(t);
196  }
197
198  public void updateReplay(long t){
199    serverSource.updateReplay(t);
200    userAggregate.updateReplay(t);
201  }
202
203  public void updateScanSize(TableName tn, long scanSize){
204    if (tableMetrics != null && tn != null) {
205      tableMetrics.updateScanSize(tn, scanSize);
206    }
207    serverSource.updateScanSize(scanSize);
208  }
209
210  public void updateScanTime(TableName tn, long t) {
211    if (tableMetrics != null && tn != null) {
212      tableMetrics.updateScanTime(tn, t);
213    }
214    serverSource.updateScanTime(t);
215    userAggregate.updateScanTime(t);
216  }
217
218  public void updateSplitTime(long t) {
219    serverSource.updateSplitTime(t);
220  }
221
222  public void incrSplitRequest() {
223    serverSource.incrSplitRequest();
224  }
225
226  public void incrSplitSuccess() {
227    serverSource.incrSplitSuccess();
228  }
229
230  public void updateFlush(String table, long t, long memstoreSize, long fileSize) {
231    serverSource.updateFlushTime(t);
232    serverSource.updateFlushMemStoreSize(memstoreSize);
233    serverSource.updateFlushOutputSize(fileSize);
234
235    if (table != null) {
236      metricsTable.updateFlushTime(table, t);
237      metricsTable.updateFlushMemstoreSize(table, memstoreSize);
238      metricsTable.updateFlushOutputSize(table, fileSize);
239    }
240
241  }
242
243  public void updateCompaction(String table, boolean isMajor, long t, int inputFileCount, int outputFileCount,
244      long inputBytes, long outputBytes) {
245    serverSource.updateCompactionTime(isMajor, t);
246    serverSource.updateCompactionInputFileCount(isMajor, inputFileCount);
247    serverSource.updateCompactionOutputFileCount(isMajor, outputFileCount);
248    serverSource.updateCompactionInputSize(isMajor, inputBytes);
249    serverSource.updateCompactionOutputSize(isMajor, outputBytes);
250
251    if (table != null) {
252      metricsTable.updateCompactionTime(table, isMajor, t);
253      metricsTable.updateCompactionInputFileCount(table, isMajor, inputFileCount);
254      metricsTable.updateCompactionOutputFileCount(table, isMajor, outputFileCount);
255      metricsTable.updateCompactionInputSize(table, isMajor, inputBytes);
256      metricsTable.updateCompactionOutputSize(table, isMajor, outputBytes);
257    }
258  }
259
260  public void updateBulkLoad(long millis) {
261    this.bulkLoadTimer.updateMillis(millis);
262  }
263
264  public void updateReadQueryMeter(TableName tn, long count) {
265    if (tableMetrics != null && tn != null) {
266      tableMetrics.updateTableReadQueryMeter(tn, count);
267    }
268    this.serverReadQueryMeter.mark(count);
269  }
270
271  public void updateReadQueryMeter(TableName tn) {
272    if (tableMetrics != null && tn != null) {
273      tableMetrics.updateTableReadQueryMeter(tn);
274    }
275    this.serverReadQueryMeter.mark();
276  }
277
278  public void updateWriteQueryMeter(TableName tn, long count) {
279    if (tableMetrics != null && tn != null) {
280      tableMetrics.updateTableWriteQueryMeter(tn, count);
281    }
282    this.serverWriteQueryMeter.mark(count);
283  }
284
285  public void updateWriteQueryMeter(TableName tn) {
286    if (tableMetrics != null && tn != null) {
287      tableMetrics.updateTableWriteQueryMeter(tn);
288    }
289    this.serverWriteQueryMeter.mark();
290  }
291
292  /**
293   * @see MetricsRegionServerQuotaSource#incrementNumRegionSizeReportsSent(long)
294   */
295  public void incrementNumRegionSizeReportsSent(long numReportsSent) {
296    quotaSource.incrementNumRegionSizeReportsSent(numReportsSent);
297  }
298
299  /**
300   * @see MetricsRegionServerQuotaSource#incrementRegionSizeReportingChoreTime(long)
301   */
302  public void incrementRegionSizeReportingChoreTime(long time) {
303    quotaSource.incrementRegionSizeReportingChoreTime(time);
304  }
305}