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