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.MetricRegistries;
023import org.apache.hadoop.hbase.metrics.MetricRegistry;
024import org.apache.hadoop.hbase.metrics.Timer;
025import org.apache.hadoop.conf.Configuration;
026import org.apache.yetus.audience.InterfaceAudience;
027import org.apache.yetus.audience.InterfaceStability;
028
029import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting;
030
031/**
032 * <p>
033 * This class is for maintaining the various regionserver statistics
034 * and publishing them through the metrics interfaces.
035 * </p>
036 * This class has a number of metrics variables that are publicly accessible;
037 * these variables (objects) have methods to update their values.
038 */
039@InterfaceStability.Evolving
040@InterfaceAudience.Private
041public class MetricsRegionServer {
042  public static final String RS_ENABLE_TABLE_METRICS_KEY =
043      "hbase.regionserver.enable.table.latencies";
044  public static final boolean RS_ENABLE_TABLE_METRICS_DEFAULT = true;
045
046  private MetricsRegionServerSource serverSource;
047  private MetricsRegionServerWrapper regionServerWrapper;
048  private RegionServerTableMetrics tableMetrics;
049
050  private MetricRegistry metricRegistry;
051  private Timer bulkLoadTimer;
052
053  public MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper, Configuration conf) {
054    this(regionServerWrapper,
055        CompatibilitySingletonFactory.getInstance(MetricsRegionServerSourceFactory.class)
056            .createServer(regionServerWrapper),
057        createTableMetrics(conf));
058
059    // Create hbase-metrics module based metrics. The registry should already be registered by the
060    // MetricsRegionServerSource
061    metricRegistry = MetricRegistries.global().get(serverSource.getMetricRegistryInfo()).get();
062
063    // create and use metrics from the new hbase-metrics based registry.
064    bulkLoadTimer = metricRegistry.timer("Bulkload");
065  }
066
067  MetricsRegionServer(MetricsRegionServerWrapper regionServerWrapper,
068                      MetricsRegionServerSource serverSource,
069                      RegionServerTableMetrics tableMetrics) {
070    this.regionServerWrapper = regionServerWrapper;
071    this.serverSource = serverSource;
072    this.tableMetrics = tableMetrics;
073  }
074
075  /**
076   * Creates an instance of {@link RegionServerTableMetrics} only if the feature is enabled.
077   */
078  static RegionServerTableMetrics createTableMetrics(Configuration conf) {
079    if (conf.getBoolean(RS_ENABLE_TABLE_METRICS_KEY, RS_ENABLE_TABLE_METRICS_DEFAULT)) {
080      return new RegionServerTableMetrics();
081    }
082    return null;
083  }
084
085  @VisibleForTesting
086  public MetricsRegionServerSource getMetricsSource() {
087    return serverSource;
088  }
089
090  public MetricsRegionServerWrapper getRegionServerWrapper() {
091    return regionServerWrapper;
092  }
093
094  public void updatePutBatch(TableName tn, long t) {
095    if (tableMetrics != null && tn != null) {
096      tableMetrics.updatePut(tn, t);
097    }
098    if (t > 1000) {
099      serverSource.incrSlowPut();
100    }
101    serverSource.updatePutBatch(t);
102  }
103
104  public void updatePut(TableName tn, long t) {
105    if (tableMetrics != null && tn != null) {
106      tableMetrics.updatePut(tn, t);
107    }
108    serverSource.updatePut(t);
109  }
110
111  public void updateDelete(TableName tn, long t) {
112    if (tableMetrics != null && tn != null) {
113      tableMetrics.updateDelete(tn, t);
114    }
115    serverSource.updateDelete(t);
116  }
117
118  public void updateDeleteBatch(TableName tn, long t) {
119    if (tableMetrics != null && tn != null) {
120      tableMetrics.updateDelete(tn, t);
121    }
122    if (t > 1000) {
123      serverSource.incrSlowDelete();
124    }
125    serverSource.updateDeleteBatch(t);
126  }
127
128  public void updateCheckAndDelete(long t) {
129    serverSource.updateCheckAndDelete(t);
130  }
131
132  public void updateCheckAndPut(long t) {
133    serverSource.updateCheckAndPut(t);
134  }
135
136  public void updateGet(TableName tn, long t) {
137    if (tableMetrics != null && tn != null) {
138      tableMetrics.updateGet(tn, t);
139    }
140    if (t > 1000) {
141      serverSource.incrSlowGet();
142    }
143    serverSource.updateGet(t);
144  }
145
146  public void updateIncrement(TableName tn, long t) {
147    if (tableMetrics != null && tn != null) {
148      tableMetrics.updateIncrement(tn, t);
149    }
150    if (t > 1000) {
151      serverSource.incrSlowIncrement();
152    }
153    serverSource.updateIncrement(t);
154  }
155
156  public void updateAppend(TableName tn, long t) {
157    if (tableMetrics != null && tn != null) {
158      tableMetrics.updateAppend(tn, t);
159    }
160    if (t > 1000) {
161      serverSource.incrSlowAppend();
162    }
163    serverSource.updateAppend(t);
164  }
165
166  public void updateReplay(long t){
167    serverSource.updateReplay(t);
168  }
169
170  public void updateScanSize(TableName tn, long scanSize){
171    if (tableMetrics != null && tn != null) {
172      tableMetrics.updateScanSize(tn, scanSize);
173    }
174    serverSource.updateScanSize(scanSize);
175  }
176
177  public void updateScanTime(TableName tn, long t) {
178    if (tableMetrics != null && tn != null) {
179      tableMetrics.updateScanTime(tn, t);
180    }
181    serverSource.updateScanTime(t);
182  }
183
184  public void updateSplitTime(long t) {
185    serverSource.updateSplitTime(t);
186  }
187
188  public void incrSplitRequest() {
189    serverSource.incrSplitRequest();
190  }
191
192  public void incrSplitSuccess() {
193    serverSource.incrSplitSuccess();
194  }
195
196  public void updateFlush(long t, long memstoreSize, long fileSize) {
197    serverSource.updateFlushTime(t);
198    serverSource.updateFlushMemStoreSize(memstoreSize);
199    serverSource.updateFlushOutputSize(fileSize);
200  }
201
202  public void updateCompaction(boolean isMajor, long t, int inputFileCount, int outputFileCount,
203      long inputBytes, long outputBytes) {
204    serverSource.updateCompactionTime(isMajor, t);
205    serverSource.updateCompactionInputFileCount(isMajor, inputFileCount);
206    serverSource.updateCompactionOutputFileCount(isMajor, outputFileCount);
207    serverSource.updateCompactionInputSize(isMajor, inputBytes);
208    serverSource.updateCompactionOutputSize(isMajor, outputBytes);
209  }
210
211  public void updateBulkLoad(long millis) {
212    this.bulkLoadTimer.updateMillis(millis);
213  }
214}