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 final MetricsTable metricsTable;
051  private MetricsRegionServerQuotaSource quotaSource;
052
053  private MetricRegistry metricRegistry;
054  private Timer bulkLoadTimer;
055  private Meter serverReadQueryMeter;
056  private Meter serverWriteQueryMeter;
057
058  public MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper, Configuration conf,
059      MetricsTable metricsTable) {
060    this(regionServerWrapper,
061        CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)
062            .createServer(regionServerWrapper),
063        createTableMetrics(conf),
064        metricsTable);
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,
080                      RegionServerTableMetrics tableMetrics,
081                      MetricsTable metricsTable) {
082    this.regionServerWrapper = regionServerWrapper;
083    this.serverSource = serverSource;
084    this.tableMetrics = tableMetrics;
085    this.metricsTable = metricsTable;
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  public MetricsRegionServerWrapper getRegionServerWrapper() {
104    return regionServerWrapper;
105  }
106
107  public void updatePutBatch(TableName tn, long t) {
108    if (tableMetrics != null && tn != null) {
109      tableMetrics.updatePutBatch(tn, t);
110    }
111    if (t > 1000) {
112      serverSource.incrSlowPut();
113    }
114    serverSource.updatePutBatch(t);
115  }
116
117  public void updatePut(TableName tn, long t) {
118    if (tableMetrics != null && tn != null) {
119      tableMetrics.updatePut(tn, t);
120    }
121    serverSource.updatePut(t);
122  }
123
124  public void updateDelete(TableName tn, long t) {
125    if (tableMetrics != null && tn != null) {
126      tableMetrics.updateDelete(tn, t);
127    }
128    serverSource.updateDelete(t);
129  }
130
131  public void updateDeleteBatch(TableName tn, long t) {
132    if (tableMetrics != null && tn != null) {
133      tableMetrics.updateDeleteBatch(tn, t);
134    }
135    if (t > 1000) {
136      serverSource.incrSlowDelete();
137    }
138    serverSource.updateDeleteBatch(t);
139  }
140
141  public void updateCheckAndDelete(long t) {
142    serverSource.updateCheckAndDelete(t);
143  }
144
145  public void updateCheckAndPut(long t) {
146    serverSource.updateCheckAndPut(t);
147  }
148
149  public void updateGet(TableName tn, long t) {
150    if (tableMetrics != null && tn != null) {
151      tableMetrics.updateGet(tn, t);
152    }
153    if (t > 1000) {
154      serverSource.incrSlowGet();
155    }
156    serverSource.updateGet(t);
157  }
158
159  public void updateIncrement(TableName tn, long t) {
160    if (tableMetrics != null && tn != null) {
161      tableMetrics.updateIncrement(tn, t);
162    }
163    if (t > 1000) {
164      serverSource.incrSlowIncrement();
165    }
166    serverSource.updateIncrement(t);
167  }
168
169  public void updateAppend(TableName tn, long t) {
170    if (tableMetrics != null && tn != null) {
171      tableMetrics.updateAppend(tn, t);
172    }
173    if (t > 1000) {
174      serverSource.incrSlowAppend();
175    }
176    serverSource.updateAppend(t);
177  }
178
179  public void updateReplay(long t){
180    serverSource.updateReplay(t);
181  }
182
183  public void updateScanSize(TableName tn, long scanSize){
184    if (tableMetrics != null && tn != null) {
185      tableMetrics.updateScanSize(tn, scanSize);
186    }
187    serverSource.updateScanSize(scanSize);
188  }
189
190  public void updateScanTime(TableName tn, long t) {
191    if (tableMetrics != null && tn != null) {
192      tableMetrics.updateScanTime(tn, t);
193    }
194    serverSource.updateScanTime(t);
195  }
196
197  public void updateSplitTime(long t) {
198    serverSource.updateSplitTime(t);
199  }
200
201  public void incrSplitRequest() {
202    serverSource.incrSplitRequest();
203  }
204
205  public void incrSplitSuccess() {
206    serverSource.incrSplitSuccess();
207  }
208
209  public void updateFlush(String table, long t, long memstoreSize, long fileSize) {
210    serverSource.updateFlushTime(t);
211    serverSource.updateFlushMemStoreSize(memstoreSize);
212    serverSource.updateFlushOutputSize(fileSize);
213
214    if (table != null) {
215      metricsTable.updateFlushTime(table, memstoreSize);
216      metricsTable.updateFlushMemstoreSize(table, memstoreSize);
217      metricsTable.updateFlushOutputSize(table, fileSize);
218    }
219
220  }
221
222  public void updateCompaction(String table, boolean isMajor, long t, int inputFileCount, int outputFileCount,
223      long inputBytes, long outputBytes) {
224    serverSource.updateCompactionTime(isMajor, t);
225    serverSource.updateCompactionInputFileCount(isMajor, inputFileCount);
226    serverSource.updateCompactionOutputFileCount(isMajor, outputFileCount);
227    serverSource.updateCompactionInputSize(isMajor, inputBytes);
228    serverSource.updateCompactionOutputSize(isMajor, outputBytes);
229
230    if (table != null) {
231      metricsTable.updateCompactionTime(table, isMajor, t);
232      metricsTable.updateCompactionInputFileCount(table, isMajor, inputFileCount);
233      metricsTable.updateCompactionOutputFileCount(table, isMajor, outputFileCount);
234      metricsTable.updateCompactionInputSize(table, isMajor, inputBytes);
235      metricsTable.updateCompactionOutputSize(table, isMajor, outputBytes);
236    }
237  }
238
239  public void updateBulkLoad(long millis) {
240    this.bulkLoadTimer.updateMillis(millis);
241  }
242
243  public void updateReadQueryMeter(TableName tn, long count) {
244    if (tableMetrics != null && tn != null) {
245      tableMetrics.updateTableReadQueryMeter(tn, count);
246    }
247    this.serverReadQueryMeter.mark(count);
248  }
249
250  public void updateReadQueryMeter(TableName tn) {
251    if (tableMetrics != null && tn != null) {
252      tableMetrics.updateTableReadQueryMeter(tn);
253    }
254    this.serverReadQueryMeter.mark();
255  }
256
257  public void updateWriteQueryMeter(TableName tn, long count) {
258    if (tableMetrics != null && tn != null) {
259      tableMetrics.updateTableWriteQueryMeter(tn, count);
260    }
261    this.serverWriteQueryMeter.mark(count);
262  }
263
264  public void updateWriteQueryMeter(TableName tn) {
265    if (tableMetrics != null && tn != null) {
266      tableMetrics.updateTableWriteQueryMeter(tn);
267    }
268    this.serverWriteQueryMeter.mark();
269  }
270
271  /**
272   * @see MetricsRegionServerQuotaSource#incrementNumRegionSizeReportsSent(long)
273   */
274  public void incrementNumRegionSizeReportsSent(long numReportsSent) {
275    quotaSource.incrementNumRegionSizeReportsSent(numReportsSent);
276  }
277
278  /**
279   * @see MetricsRegionServerQuotaSource#incrementRegionSizeReportingChoreTime(long)
280   */
281  public void incrementRegionSizeReportingChoreTime(long time) {
282    quotaSource.incrementRegionSizeReportingChoreTime(time);
283  }
284}