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