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.conf.Configuration;
021import org.apache.hadoop.hbase.CompatibilitySingletonFactory;
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.yetus.audience.InterfaceAudience;
027import org.apache.yetus.audience.InterfaceStability;
028
029/**
030 * Maintains regionserver statistics and publishes them through the metrics interfaces. This class
031 * has a number of metrics variables that are publicly accessible; these variables (objects) have
032 * methods to update their values. Batch your updates rather than call on each instance else all
033 * threads will do nothing but contend trying to maintain metric counters!
034 */
035@InterfaceStability.Evolving
036@InterfaceAudience.Private
037public class MetricsRegionServer {
038  public static final String RS_ENABLE_SERVER_QUERY_METER_METRICS_KEY =
039    "hbase.regionserver.enable.server.query.meter";
040  public static final boolean RS_ENABLE_SERVER_QUERY_METER_METRICS_KEY_DEFAULT = false;
041  public static final String SLOW_METRIC_TIME = "hbase.ipc.slow.metric.time";
042  private final MetricsRegionServerSource serverSource;
043  private final MetricsRegionServerWrapper regionServerWrapper;
044  private final MetricsTable metricsTable;
045  private MetricsRegionServerQuotaSource quotaSource;
046  private final MetricsUserAggregate userAggregate;
047
048  private MetricRegistry metricRegistry;
049  private Timer bulkLoadTimer;
050  // Incremented once for each call to Scan#nextRaw
051  private Meter serverReadQueryMeter;
052  // Incremented per write.
053  private Meter serverWriteQueryMeter;
054  protected long slowMetricTime;
055  protected static final int DEFAULT_SLOW_METRIC_TIME = 1000; // milliseconds
056
057  public MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper, Configuration conf,
058    MetricsTable metricsTable) {
059    this(regionServerWrapper,
060      CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)
061        .createServer(regionServerWrapper),
062      metricsTable, 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    slowMetricTime = conf.getLong(SLOW_METRIC_TIME, DEFAULT_SLOW_METRIC_TIME);
072    quotaSource = CompatibilitySingletonFactory.getInstance(MetricsRegionServerQuotaSource.class);
073    if (
074      conf.getBoolean(RS_ENABLE_SERVER_QUERY_METER_METRICS_KEY,
075        RS_ENABLE_SERVER_QUERY_METER_METRICS_KEY_DEFAULT)
076    ) {
077      serverReadQueryMeter = metricRegistry.meter("ServerReadQueryPerSecond");
078      serverWriteQueryMeter = metricRegistry.meter("ServerWriteQueryPerSecond");
079    }
080  }
081
082  MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper,
083    MetricsRegionServerSource serverSource, MetricsTable metricsTable,
084    MetricsUserAggregate userAggregate) {
085    this.regionServerWrapper = regionServerWrapper;
086    this.serverSource = serverSource;
087    this.metricsTable = metricsTable;
088    this.userAggregate = userAggregate;
089  }
090
091  public MetricsRegionServerSource getMetricsSource() {
092    return serverSource;
093  }
094
095  public MetricsUserAggregate getMetricsUserAggregate() {
096    return userAggregate;
097  }
098
099  public MetricsRegionServerWrapper getRegionServerWrapper() {
100    return regionServerWrapper;
101  }
102
103  public void updatePutBatch(HRegion region, long t) {
104    if (region.getMetricsTableRequests() != null) {
105      region.getMetricsTableRequests().updatePutBatch(t);
106    }
107    serverSource.updatePutBatch(t);
108  }
109
110  public void updatePut(HRegion region, long t) {
111    if (region.getMetricsTableRequests() != null) {
112      region.getMetricsTableRequests().updatePut(t);
113    }
114    if (t > slowMetricTime) {
115      serverSource.incrSlowPut();
116    }
117    serverSource.updatePut(t);
118    userAggregate.updatePut(t);
119  }
120
121  public void updateDelete(HRegion region, long t) {
122    if (region.getMetricsTableRequests() != null) {
123      region.getMetricsTableRequests().updateDelete(t);
124    }
125    if (t > slowMetricTime) {
126      serverSource.incrSlowDelete();
127    }
128    serverSource.updateDelete(t);
129    userAggregate.updateDelete(t);
130  }
131
132  public void updateDeleteBatch(HRegion region, long t) {
133    if (region.getMetricsTableRequests() != null) {
134      region.getMetricsTableRequests().updateDeleteBatch(t);
135    }
136    serverSource.updateDeleteBatch(t);
137  }
138
139  public void updateCheckAndDelete(HRegion region, long t) {
140    if (region.getMetricsTableRequests() != null) {
141      region.getMetricsTableRequests().updateCheckAndDelete(t);
142    }
143    serverSource.updateCheckAndDelete(t);
144  }
145
146  public void updateCheckAndPut(HRegion region, long t) {
147    if (region.getMetricsTableRequests() != null) {
148      region.getMetricsTableRequests().updateCheckAndPut(t);
149    }
150    serverSource.updateCheckAndPut(t);
151  }
152
153  public void updateCheckAndMutate(HRegion region, long time, long blockBytesScanned) {
154    if (region.getMetricsTableRequests() != null) {
155      region.getMetricsTableRequests().updateCheckAndMutate(time, blockBytesScanned);
156    }
157    serverSource.updateCheckAndMutate(time, blockBytesScanned);
158    userAggregate.updateCheckAndMutate(blockBytesScanned);
159  }
160
161  public void updateGet(HRegion region, long time, long blockBytesScanned) {
162    if (region.getMetricsTableRequests() != null) {
163      region.getMetricsTableRequests().updateGet(time, blockBytesScanned);
164    }
165    if (time > slowMetricTime) {
166      serverSource.incrSlowGet();
167    }
168    serverSource.updateGet(time, blockBytesScanned);
169    userAggregate.updateGet(time, blockBytesScanned);
170  }
171
172  public void updateIncrement(HRegion region, long time, long blockBytesScanned) {
173    if (region.getMetricsTableRequests() != null) {
174      region.getMetricsTableRequests().updateIncrement(time, blockBytesScanned);
175    }
176    if (time > slowMetricTime) {
177      serverSource.incrSlowIncrement();
178    }
179    serverSource.updateIncrement(time, blockBytesScanned);
180    userAggregate.updateIncrement(time, blockBytesScanned);
181  }
182
183  public void updateAppend(HRegion region, long time, long blockBytesScanned) {
184    if (region.getMetricsTableRequests() != null) {
185      region.getMetricsTableRequests().updateAppend(time, blockBytesScanned);
186    }
187    if (time > slowMetricTime) {
188      serverSource.incrSlowAppend();
189    }
190    serverSource.updateAppend(time, blockBytesScanned);
191    userAggregate.updateAppend(time, blockBytesScanned);
192  }
193
194  public void updateReplay(long t) {
195    serverSource.updateReplay(t);
196    userAggregate.updateReplay(t);
197  }
198
199  public void updateScan(HRegion region, long time, long responseCellSize, long blockBytesScanned) {
200    if (region.getMetricsTableRequests() != null) {
201      region.getMetricsTableRequests().updateScan(time, responseCellSize, blockBytesScanned);
202    }
203    serverSource.updateScan(time, responseCellSize, blockBytesScanned);
204    userAggregate.updateScan(time, blockBytesScanned);
205  }
206
207  public void updateSplitTime(long t) {
208    serverSource.updateSplitTime(t);
209  }
210
211  public void incrSplitRequest() {
212    serverSource.incrSplitRequest();
213  }
214
215  public void incrSplitSuccess() {
216    serverSource.incrSplitSuccess();
217  }
218
219  public void updateFlush(String table, long t, long memstoreSize, long fileSize) {
220    serverSource.updateFlushTime(t);
221    serverSource.updateFlushMemStoreSize(memstoreSize);
222    serverSource.updateFlushOutputSize(fileSize);
223
224    if (table != null) {
225      metricsTable.updateFlushTime(table, t);
226      metricsTable.updateFlushMemstoreSize(table, memstoreSize);
227      metricsTable.updateFlushOutputSize(table, fileSize);
228    }
229
230  }
231
232  public void updateCompaction(String table, boolean isMajor, long t, int inputFileCount,
233    int outputFileCount, long inputBytes, long outputBytes) {
234    serverSource.updateCompactionTime(isMajor, t);
235    serverSource.updateCompactionInputFileCount(isMajor, inputFileCount);
236    serverSource.updateCompactionOutputFileCount(isMajor, outputFileCount);
237    serverSource.updateCompactionInputSize(isMajor, inputBytes);
238    serverSource.updateCompactionOutputSize(isMajor, outputBytes);
239
240    if (table != null) {
241      metricsTable.updateCompactionTime(table, isMajor, t);
242      metricsTable.updateCompactionInputFileCount(table, isMajor, inputFileCount);
243      metricsTable.updateCompactionOutputFileCount(table, isMajor, outputFileCount);
244      metricsTable.updateCompactionInputSize(table, isMajor, inputBytes);
245      metricsTable.updateCompactionOutputSize(table, isMajor, outputBytes);
246    }
247  }
248
249  public void updateBulkLoad(long millis) {
250    this.bulkLoadTimer.updateMillis(millis);
251  }
252
253  /**
254   * @see MetricsRegionServerQuotaSource#incrementNumRegionSizeReportsSent(long)
255   */
256  public void incrementNumRegionSizeReportsSent(long numReportsSent) {
257    quotaSource.incrementNumRegionSizeReportsSent(numReportsSent);
258  }
259
260  /**
261   * @see MetricsRegionServerQuotaSource#incrementRegionSizeReportingChoreTime(long)
262   */
263  public void incrementRegionSizeReportingChoreTime(long time) {
264    quotaSource.incrementRegionSizeReportingChoreTime(time);
265  }
266
267  public void updateReadQueryMeter(HRegion region, long count) {
268    if (region.getMetricsTableRequests() != null) {
269      region.getMetricsTableRequests().updateTableReadQueryMeter(count);
270    }
271    if (serverReadQueryMeter != null) {
272      serverReadQueryMeter.mark(count);
273    }
274  }
275
276  public void updateWriteQueryMeter(HRegion region, long count) {
277    if (region.getMetricsTableRequests() != null) {
278      region.getMetricsTableRequests().updateTableWriteQueryMeter(count);
279    }
280    if (serverWriteQueryMeter != null) {
281      serverWriteQueryMeter.mark(count);
282    }
283  }
284
285  public void updateWriteQueryMeter(HRegion region) {
286    if (region.getMetricsTableRequests() != null) {
287      region.getMetricsTableRequests().updateTableWriteQueryMeter();
288    }
289    if (serverWriteQueryMeter != null) {
290      serverWriteQueryMeter.mark();
291    }
292  }
293
294  public void incrScannerLeaseExpired() {
295    serverSource.incrScannerLeaseExpired();
296  }
297
298}