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 MetricsRegionServerSource serverSource;
048  private MetricsRegionServerWrapper regionServerWrapper;
049  private RegionServerTableMetrics tableMetrics;
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    this(regionServerWrapper,
059        CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)
060            .createServer(regionServerWrapper),
061        createTableMetrics(conf));
062
063    // Create hbase-metrics module based metrics. The registry should already be registered by the
064    // MetricsRegionServerSource
065    metricRegistry = MetricRegistries.global().get(serverSource.getMetricRegistryInfo()).get();
066
067    // create and use metrics from the new hbase-metrics based registry.
068    bulkLoadTimer = metricRegistry.timer("Bulkload");
069
070    serverReadQueryMeter = metricRegistry.meter("ServerReadQueryPerSecond");
071    serverWriteQueryMeter = metricRegistry.meter("ServerWriteQueryPerSecond");
072    quotaSource = CompatibilitySingletonFactory.getInstance(MetricsRegionServerQuotaSource.class);
073  }
074
075  MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper,
076                      MetricsRegionServerSource serverSource,
077                      RegionServerTableMetrics tableMetrics) {
078    this.regionServerWrapper = regionServerWrapper;
079    this.serverSource = serverSource;
080    this.tableMetrics = tableMetrics;
081  }
082
083  /**
084   * Creates an instance of {@link RegionServerTableMetrics} only if the feature is enabled.
085   */
086  static RegionServerTableMetrics createTableMetrics(Configuration conf) {
087    if (conf.getBoolean(RS_ENABLE_TABLE_METRICS_KEY, RS_ENABLE_TABLE_METRICS_DEFAULT)) {
088      return new RegionServerTableMetrics();
089    }
090    return null;
091  }
092
093  @VisibleForTesting
094  public MetricsRegionServerSource getMetricsSource() {
095    return serverSource;
096  }
097
098  public MetricsRegionServerWrapper getRegionServerWrapper() {
099    return regionServerWrapper;
100  }
101
102  public void updatePutBatch(TableName tn, long t) {
103    if (tableMetrics != null && tn != null) {
104      tableMetrics.updatePutBatch(tn, t);
105    }
106    if (t > 1000) {
107      serverSource.incrSlowPut();
108    }
109    serverSource.updatePutBatch(t);
110  }
111
112  public void updatePut(TableName tn, long t) {
113    if (tableMetrics != null && tn != null) {
114      tableMetrics.updatePut(tn, t);
115    }
116    serverSource.updatePut(t);
117  }
118
119  public void updateDelete(TableName tn, long t) {
120    if (tableMetrics != null && tn != null) {
121      tableMetrics.updateDelete(tn, t);
122    }
123    serverSource.updateDelete(t);
124  }
125
126  public void updateDeleteBatch(TableName tn, long t) {
127    if (tableMetrics != null && tn != null) {
128      tableMetrics.updateDeleteBatch(tn, t);
129    }
130    if (t > 1000) {
131      serverSource.incrSlowDelete();
132    }
133    serverSource.updateDeleteBatch(t);
134  }
135
136  public void updateCheckAndDelete(long t) {
137    serverSource.updateCheckAndDelete(t);
138  }
139
140  public void updateCheckAndPut(long t) {
141    serverSource.updateCheckAndPut(t);
142  }
143
144  public void updateGet(TableName tn, long t) {
145    if (tableMetrics != null && tn != null) {
146      tableMetrics.updateGet(tn, t);
147    }
148    if (t > 1000) {
149      serverSource.incrSlowGet();
150    }
151    serverSource.updateGet(t);
152  }
153
154  public void updateIncrement(TableName tn, long t) {
155    if (tableMetrics != null && tn != null) {
156      tableMetrics.updateIncrement(tn, t);
157    }
158    if (t > 1000) {
159      serverSource.incrSlowIncrement();
160    }
161    serverSource.updateIncrement(t);
162  }
163
164  public void updateAppend(TableName tn, long t) {
165    if (tableMetrics != null && tn != null) {
166      tableMetrics.updateAppend(tn, t);
167    }
168    if (t > 1000) {
169      serverSource.incrSlowAppend();
170    }
171    serverSource.updateAppend(t);
172  }
173
174  public void updateReplay(long t){
175    serverSource.updateReplay(t);
176  }
177
178  public void updateScanSize(TableName tn, long scanSize){
179    if (tableMetrics != null && tn != null) {
180      tableMetrics.updateScanSize(tn, scanSize);
181    }
182    serverSource.updateScanSize(scanSize);
183  }
184
185  public void updateScanTime(TableName tn, long t) {
186    if (tableMetrics != null && tn != null) {
187      tableMetrics.updateScanTime(tn, t);
188    }
189    serverSource.updateScanTime(t);
190  }
191
192  public void updateSplitTime(long t) {
193    serverSource.updateSplitTime(t);
194  }
195
196  public void incrSplitRequest() {
197    serverSource.incrSplitRequest();
198  }
199
200  public void incrSplitSuccess() {
201    serverSource.incrSplitSuccess();
202  }
203
204  public void updateFlush(long t, long memstoreSize, long fileSize) {
205    serverSource.updateFlushTime(t);
206    serverSource.updateFlushMemStoreSize(memstoreSize);
207    serverSource.updateFlushOutputSize(fileSize);
208  }
209
210  public void updateCompaction(boolean isMajor, long t, int inputFileCount, int outputFileCount,
211      long inputBytes, long outputBytes) {
212    serverSource.updateCompactionTime(isMajor, t);
213    serverSource.updateCompactionInputFileCount(isMajor, inputFileCount);
214    serverSource.updateCompactionOutputFileCount(isMajor, outputFileCount);
215    serverSource.updateCompactionInputSize(isMajor, inputBytes);
216    serverSource.updateCompactionOutputSize(isMajor, outputBytes);
217  }
218
219  public void updateBulkLoad(long millis) {
220    this.bulkLoadTimer.updateMillis(millis);
221  }
222
223  public void updateReadQueryMeter(TableName tn, long count) {
224    if (tableMetrics != null && tn != null) {
225      tableMetrics.updateTableReadQueryMeter(tn, count);
226    }
227    this.serverReadQueryMeter.mark(count);
228  }
229
230  public void updateReadQueryMeter(TableName tn) {
231    if (tableMetrics != null && tn != null) {
232      tableMetrics.updateTableReadQueryMeter(tn);
233    }
234    this.serverReadQueryMeter.mark();
235  }
236
237  public void updateWriteQueryMeter(TableName tn, long count) {
238    if (tableMetrics != null && tn != null) {
239      tableMetrics.updateTableWriteQueryMeter(tn, count);
240    }
241    this.serverWriteQueryMeter.mark(count);
242  }
243
244  public void updateWriteQueryMeter(TableName tn) {
245    if (tableMetrics != null && tn != null) {
246      tableMetrics.updateTableWriteQueryMeter(tn);
247    }
248    this.serverWriteQueryMeter.mark();
249  }
250
251  /**
252   * @see MetricsRegionServerQuotaSource#incrementNumRegionSizeReportsSent(long)
253   */
254  public void incrementNumRegionSizeReportsSent(long numReportsSent) {
255    quotaSource.incrementNumRegionSizeReportsSent(numReportsSent);
256  }
257
258  /**
259   * @see MetricsRegionServerQuotaSource#incrementRegionSizeReportingChoreTime(long)
260   */
261  public void incrementRegionSizeReportingChoreTime(long time) {
262    quotaSource.incrementRegionSizeReportingChoreTime(time);
263  }
264}