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