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.metrics;
019
020import org.apache.hadoop.conf.Configuration;
021import org.apache.hadoop.hbase.TableName;
022import org.apache.hadoop.hbase.metrics.Counter;
023import org.apache.hadoop.hbase.metrics.Histogram;
024import org.apache.hadoop.hbase.metrics.Meter;
025import org.apache.hadoop.hbase.metrics.MetricRegistries;
026import org.apache.hadoop.hbase.metrics.MetricRegistry;
027import org.apache.hadoop.hbase.metrics.MetricRegistryInfo;
028import org.apache.yetus.audience.InterfaceAudience;
029
030@InterfaceAudience.Private
031public class MetricsTableRequests {
032
033  public static final String ENABLE_TABLE_LATENCIES_METRICS_KEY =
034    "hbase.regionserver.enable.table.latencies";
035
036  public static final boolean ENABLE_TABLE_LATENCIES_METRICS_DEFAULT = true;
037
038  public static final String ENABLE_TABLE_QUERY_METER_METRICS_KEY =
039    "hbase.regionserver.enable.table.query.meter";
040
041  public static final boolean ENABLE_TABLE_QUERY_METER_METRICS_KEY_DEFAULT = false;
042
043  /**
044   * The name of the metrics
045   */
046  private final static String METRICS_NAME = "TableRequests";
047
048  /**
049   * The name of the metrics context that metrics will be under.
050   */
051  private final static String METRICS_CONTEXT = "regionserver";
052
053  /**
054   * Description
055   */
056  private final static String METRICS_DESCRIPTION =
057    "Metrics about Tables on a single HBase RegionServer";
058
059  /**
060   * The name of the metrics context that metrics will be under in jmx
061   */
062  private final static String METRICS_JMX_CONTEXT = "RegionServer,sub=" + METRICS_NAME;
063
064  private final static String GET_TIME = "getTime";
065  private final static String SCAN_TIME = "scanTime";
066  private final static String SCAN_SIZE = "scanSize";
067  private final static String PUT_TIME = "putTime";
068  private final static String PUT_BATCH_TIME = "putBatchTime";
069  private final static String DELETE_TIME = "deleteTime";
070  private final static String DELETE_BATCH_TIME = "deleteBatchTime";
071  private final static String INCREMENT_TIME = "incrementTime";
072  private final static String APPEND_TIME = "appendTime";
073  private final static String CHECK_AND_DELETE_TIME = "checkAndDeleteTime";
074  private final static String CHECK_AND_PUT_TIME = "checkAndPutTime";
075  private final static String CHECK_AND_MUTATE_TIME = "checkAndMutateTime";
076  String BLOCK_BYTES_SCANNED_KEY = "blockBytesScannedCount";
077  String GET_BLOCK_BYTES_SCANNED_KEY = "getBlockBytesScanned";
078  String SCAN_BLOCK_BYTES_SCANNED_KEY = "scanBlockBytesScanned";
079  String CHECK_AND_MUTATE_BLOCK_BYTES_SCANNED_KEY = "checkAndMutateBlockBytesScanned";
080  String INCREMENT_BLOCK_BYTES_SCANNED_KEY = "incrementBlockBytesScanned";
081  String APPEND_BLOCK_BYTES_SCANNED_KEY = "appendBlockBytesScanned";
082  private final static String TABLE_READ_QUERY_PER_SECOND = "tableReadQueryPerSecond";
083  private final static String TABLE_WRITE_QUERY_PER_SECOND = "tableWriteQueryPerSecond";
084
085  private Histogram getTimeHistogram;
086  private Histogram scanTimeHistogram;
087  private Histogram scanSizeHistogram;
088  private Histogram putTimeHistogram;
089  private Histogram putBatchTimeHistogram;
090  private Histogram deleteTimeHistogram;
091  private Histogram deleteBatchTimeHistogram;
092  private Histogram incrementTimeHistogram;
093  private Histogram appendTimeHistogram;
094  private Histogram checkAndDeleteTimeHistogram;
095  private Histogram checkAndPutTimeHistogram;
096  private Histogram checkAndMutateTimeHistogram;
097  private Counter blockBytesScannedCount;
098  private Histogram checkAndMutateBlockBytesScanned;
099  private Histogram getBlockBytesScanned;
100  private Histogram incrementBlockBytesScanned;
101  private Histogram appendBlockBytesScanned;
102  private Histogram scanBlockBytesScanned;
103
104  private Meter readMeter;
105  private Meter writeMeter;
106
107  private MetricRegistry registry;
108  private TableName tableName;
109  private Configuration conf;
110  private MetricRegistryInfo registryInfo;
111
112  private boolean enableTableLatenciesMetrics;
113  private boolean enabTableQueryMeterMetrics;
114
115  public boolean isEnableTableLatenciesMetrics() {
116    return enableTableLatenciesMetrics;
117  }
118
119  public boolean isEnabTableQueryMeterMetrics() {
120    return enabTableQueryMeterMetrics;
121  }
122
123  public MetricsTableRequests(TableName tableName, Configuration conf) {
124    init(tableName, conf);
125  }
126
127  private void init(TableName tableName, Configuration conf) {
128    this.tableName = tableName;
129    this.conf = conf;
130    enableTableLatenciesMetrics = this.conf.getBoolean(ENABLE_TABLE_LATENCIES_METRICS_KEY,
131      ENABLE_TABLE_LATENCIES_METRICS_DEFAULT);
132    enabTableQueryMeterMetrics = this.conf.getBoolean(ENABLE_TABLE_QUERY_METER_METRICS_KEY,
133      ENABLE_TABLE_QUERY_METER_METRICS_KEY_DEFAULT);
134    if (enableTableLatenciesMetrics || enabTableQueryMeterMetrics) {
135      registry = createRegistryForTableRequests();
136      if (enableTableLatenciesMetrics) {
137        getTimeHistogram = registry.histogram(GET_TIME);
138        scanTimeHistogram = registry.histogram(SCAN_TIME);
139        scanSizeHistogram = registry.histogram(SCAN_SIZE);
140        putTimeHistogram = registry.histogram(PUT_TIME);
141        putBatchTimeHistogram = registry.histogram(PUT_BATCH_TIME);
142        deleteTimeHistogram = registry.histogram(DELETE_TIME);
143        deleteBatchTimeHistogram = registry.histogram(DELETE_BATCH_TIME);
144        incrementTimeHistogram = registry.histogram(INCREMENT_TIME);
145        appendTimeHistogram = registry.histogram(APPEND_TIME);
146        checkAndDeleteTimeHistogram = registry.histogram(CHECK_AND_DELETE_TIME);
147        checkAndPutTimeHistogram = registry.histogram(CHECK_AND_PUT_TIME);
148        checkAndMutateTimeHistogram = registry.histogram(CHECK_AND_MUTATE_TIME);
149        blockBytesScannedCount = registry.counter(BLOCK_BYTES_SCANNED_KEY);
150        checkAndMutateBlockBytesScanned =
151          registry.histogram(CHECK_AND_MUTATE_BLOCK_BYTES_SCANNED_KEY);
152        getBlockBytesScanned = registry.histogram(GET_BLOCK_BYTES_SCANNED_KEY);
153        incrementBlockBytesScanned = registry.histogram(INCREMENT_BLOCK_BYTES_SCANNED_KEY);
154        appendBlockBytesScanned = registry.histogram(APPEND_BLOCK_BYTES_SCANNED_KEY);
155        scanBlockBytesScanned = registry.histogram(SCAN_BLOCK_BYTES_SCANNED_KEY);
156      }
157
158      if (enabTableQueryMeterMetrics) {
159        readMeter = registry.meter(TABLE_READ_QUERY_PER_SECOND);
160        writeMeter = registry.meter(TABLE_WRITE_QUERY_PER_SECOND);
161      }
162    }
163  }
164
165  private MetricRegistry createRegistryForTableRequests() {
166    return MetricRegistries.global().create(createRegistryInfoForTableRequests());
167  }
168
169  private MetricRegistryInfo createRegistryInfoForTableRequests() {
170    registryInfo = new MetricRegistryInfo(qualifyMetrics(METRICS_NAME, tableName),
171      METRICS_DESCRIPTION, qualifyMetrics(METRICS_JMX_CONTEXT, tableName), METRICS_CONTEXT, false);
172    return registryInfo;
173  }
174
175  public void removeRegistry() {
176    if (enableTableLatenciesMetrics || enabTableQueryMeterMetrics) {
177      MetricRegistries.global().remove(registry.getMetricRegistryInfo());
178    }
179  }
180
181  private static String qualifyMetrics(String prefix, TableName tableName) {
182    StringBuilder sb = new StringBuilder();
183    sb.append(prefix).append("_");
184    sb.append("Namespace_").append(tableName.getNamespaceAsString());
185    sb.append("_table_").append(tableName.getQualifierAsString());
186    return sb.toString();
187  }
188
189  /**
190   * Update the Put time histogram
191   * @param t time it took
192   */
193  public void updatePut(long t) {
194    if (isEnableTableLatenciesMetrics()) {
195      putTimeHistogram.update(t);
196    }
197  }
198
199  /**
200   * Update the batch Put time histogram
201   * @param t time it took
202   */
203  public void updatePutBatch(long t) {
204    if (isEnableTableLatenciesMetrics()) {
205      putBatchTimeHistogram.update(t);
206    }
207  }
208
209  /**
210   * Update the Delete time histogram
211   * @param t time it took
212   */
213  public void updateDelete(long t) {
214    if (isEnableTableLatenciesMetrics()) {
215      deleteTimeHistogram.update(t);
216    }
217  }
218
219  /**
220   * Update the batch Delete time histogram
221   * @param t time it took
222   */
223  public void updateDeleteBatch(long t) {
224    if (isEnableTableLatenciesMetrics()) {
225      deleteBatchTimeHistogram.update(t);
226    }
227  }
228
229  /**
230   * Update the Get time histogram .
231   * @param time              time it took
232   * @param blockBytesScanned size of block bytes scanned to retrieve the response
233   */
234  public void updateGet(long time, long blockBytesScanned) {
235    if (isEnableTableLatenciesMetrics()) {
236      getTimeHistogram.update(time);
237      if (blockBytesScanned > 0) {
238        blockBytesScannedCount.increment(blockBytesScanned);
239        getBlockBytesScanned.update(blockBytesScanned);
240      }
241    }
242  }
243
244  /**
245   * Update the Increment time histogram.
246   * @param time              time it took
247   * @param blockBytesScanned size of block bytes scanned to retrieve the response
248   */
249  public void updateIncrement(long time, long blockBytesScanned) {
250    if (isEnableTableLatenciesMetrics()) {
251      incrementTimeHistogram.update(time);
252      if (blockBytesScanned > 0) {
253        blockBytesScannedCount.increment(blockBytesScanned);
254        incrementBlockBytesScanned.update(blockBytesScanned);
255      }
256    }
257  }
258
259  /**
260   * Update the Append time histogram.
261   * @param time              time it took
262   * @param blockBytesScanned size of block bytes scanned to retrieve the response
263   */
264  public void updateAppend(long time, long blockBytesScanned) {
265    if (isEnableTableLatenciesMetrics()) {
266      appendTimeHistogram.update(time);
267      if (blockBytesScanned > 0) {
268        blockBytesScannedCount.increment(blockBytesScanned);
269        appendBlockBytesScanned.update(blockBytesScanned);
270      }
271    }
272  }
273
274  /**
275   * Update the scan metrics.
276   * @param time              response time of scan
277   * @param responseCellSize  size of the scan resposne
278   * @param blockBytesScanned size of block bytes scanned to retrieve the response
279   */
280  public void updateScan(long time, long responseCellSize, long blockBytesScanned) {
281    if (isEnableTableLatenciesMetrics()) {
282      scanTimeHistogram.update(time);
283      scanSizeHistogram.update(responseCellSize);
284      if (blockBytesScanned > 0) {
285        blockBytesScannedCount.increment(blockBytesScanned);
286        scanBlockBytesScanned.update(blockBytesScanned);
287      }
288    }
289  }
290
291  /**
292   * Update the CheckAndDelete time histogram.
293   * @param time time it took
294   */
295  public void updateCheckAndDelete(long time) {
296    if (isEnableTableLatenciesMetrics()) {
297      checkAndDeleteTimeHistogram.update(time);
298    }
299  }
300
301  /**
302   * Update the CheckAndPut time histogram.
303   * @param time time it took
304   */
305  public void updateCheckAndPut(long time) {
306    if (isEnableTableLatenciesMetrics()) {
307      checkAndPutTimeHistogram.update(time);
308    }
309  }
310
311  /**
312   * Update the CheckAndMutate time histogram.
313   * @param time time it took
314   */
315  public void updateCheckAndMutate(long time, long blockBytesScanned) {
316    if (isEnableTableLatenciesMetrics()) {
317      checkAndMutateTimeHistogram.update(time);
318      if (blockBytesScanned > 0) {
319        blockBytesScannedCount.increment(blockBytesScanned);
320        checkAndMutateBlockBytesScanned.update(blockBytesScanned);
321      }
322    }
323  }
324
325  /**
326   * Update table read QPS
327   * @param count Number of occurrences to record
328   */
329  public void updateTableReadQueryMeter(long count) {
330    if (isEnabTableQueryMeterMetrics()) {
331      readMeter.mark(count);
332    }
333  }
334
335  /**
336   * Update table read QPS
337   */
338  public void updateTableReadQueryMeter() {
339    if (isEnabTableQueryMeterMetrics()) {
340      readMeter.mark();
341    }
342  }
343
344  /**
345   * Update table write QPS
346   * @param count Number of occurrences to record
347   */
348  public void updateTableWriteQueryMeter(long count) {
349    if (isEnabTableQueryMeterMetrics()) {
350      writeMeter.mark(count);
351    }
352  }
353
354  /**
355   * Update table write QPS
356   */
357  public void updateTableWriteQueryMeter() {
358    if (isEnabTableQueryMeterMetrics()) {
359      writeMeter.mark();
360    }
361  }
362
363  // Visible for testing
364  public MetricRegistryInfo getMetricRegistryInfo() {
365    return registryInfo;
366  }
367}