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