001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to you under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.hadoop.hbase.regionserver; 018 019import java.util.HashMap; 020import org.apache.hadoop.hbase.TableName; 021import org.apache.hadoop.hbase.metrics.BaseSourceImpl; 022import org.apache.hadoop.metrics2.MetricHistogram; 023import org.apache.hadoop.metrics2.MetricsCollector; 024import org.apache.hadoop.metrics2.MetricsRecordBuilder; 025import org.apache.hadoop.metrics2.lib.DynamicMetricsRegistry; 026import org.apache.yetus.audience.InterfaceAudience; 027 028import org.apache.hbase.thirdparty.com.google.common.annotations.VisibleForTesting; 029 030/** 031 * Implementation of {@link MetricsTableLatencies} to track latencies for one table in a 032 * RegionServer. 033 */ 034@InterfaceAudience.Private 035public class MetricsTableLatenciesImpl extends BaseSourceImpl implements MetricsTableLatencies { 036 037 private final HashMap<TableName,TableHistograms> histogramsByTable = new HashMap<>(); 038 039 @VisibleForTesting 040 public static class TableHistograms { 041 final MetricHistogram getTimeHisto; 042 final MetricHistogram incrementTimeHisto; 043 final MetricHistogram appendTimeHisto; 044 final MetricHistogram putTimeHisto; 045 final MetricHistogram putBatchTimeHisto; 046 final MetricHistogram deleteTimeHisto; 047 final MetricHistogram deleteBatchTimeHisto; 048 final MetricHistogram scanTimeHisto; 049 final MetricHistogram scanSizeHisto; 050 051 TableHistograms(DynamicMetricsRegistry registry, TableName tn) { 052 getTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, GET_TIME)); 053 incrementTimeHisto = registry.newTimeHistogram( 054 qualifyMetricsName(tn, INCREMENT_TIME)); 055 appendTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, APPEND_TIME)); 056 putTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, PUT_TIME)); 057 putBatchTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, PUT_BATCH_TIME)); 058 deleteTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, DELETE_TIME)); 059 deleteBatchTimeHisto = registry.newTimeHistogram( 060 qualifyMetricsName(tn, DELETE_BATCH_TIME)); 061 scanTimeHisto = registry.newTimeHistogram(qualifyMetricsName(tn, SCAN_TIME)); 062 scanSizeHisto = registry.newSizeHistogram(qualifyMetricsName(tn, SCAN_SIZE)); 063 } 064 065 public void updatePut(long time) { 066 putTimeHisto.add(time); 067 } 068 069 public void updatePutBatch(long time) { 070 putBatchTimeHisto.add(time); 071 } 072 073 public void updateDelete(long t) { 074 deleteTimeHisto.add(t); 075 } 076 077 public void updateDeleteBatch(long t) { 078 deleteBatchTimeHisto.add(t); 079 } 080 081 public void updateGet(long t) { 082 getTimeHisto.add(t); 083 } 084 085 public void updateIncrement(long t) { 086 incrementTimeHisto.add(t); 087 } 088 089 public void updateAppend(long t) { 090 appendTimeHisto.add(t); 091 } 092 093 public void updateScanSize(long scanSize) { 094 scanSizeHisto.add(scanSize); 095 } 096 097 public void updateScanTime(long t) { 098 scanTimeHisto.add(t); 099 } 100 } 101 102 @VisibleForTesting 103 public static String qualifyMetricsName(TableName tableName, String metric) { 104 StringBuilder sb = new StringBuilder(); 105 sb.append("Namespace_").append(tableName.getNamespaceAsString()); 106 sb.append("_table_").append(tableName.getQualifierAsString()); 107 sb.append("_metric_").append(metric); 108 return sb.toString(); 109 } 110 111 @VisibleForTesting 112 public TableHistograms getOrCreateTableHistogram(String tableName) { 113 // TODO Java8's ConcurrentHashMap#computeIfAbsent would be stellar instead 114 final TableName tn = TableName.valueOf(tableName); 115 TableHistograms latency = histogramsByTable.get(tn); 116 if (latency == null) { 117 latency = new TableHistograms(getMetricsRegistry(), tn); 118 histogramsByTable.put(tn, latency); 119 } 120 return latency; 121 } 122 123 public MetricsTableLatenciesImpl() { 124 this(METRICS_NAME, METRICS_DESCRIPTION, METRICS_CONTEXT, METRICS_JMX_CONTEXT); 125 } 126 127 public MetricsTableLatenciesImpl(String metricsName, String metricsDescription, 128 String metricsContext, String metricsJmxContext) { 129 super(metricsName, metricsDescription, metricsContext, metricsJmxContext); 130 } 131 132 @Override 133 public void updatePut(String tableName, long t) { 134 getOrCreateTableHistogram(tableName).updatePut(t); 135 } 136 137 @Override 138 public void updatePutBatch(String tableName, long t) { 139 getOrCreateTableHistogram(tableName).updatePutBatch(t); 140 } 141 142 @Override 143 public void updateDelete(String tableName, long t) { 144 getOrCreateTableHistogram(tableName).updateDelete(t); 145 } 146 147 @Override 148 public void updateDeleteBatch(String tableName, long t) { 149 getOrCreateTableHistogram(tableName).updateDeleteBatch(t); 150 } 151 152 @Override 153 public void updateGet(String tableName, long t) { 154 getOrCreateTableHistogram(tableName).updateGet(t); 155 } 156 157 @Override 158 public void updateIncrement(String tableName, long t) { 159 getOrCreateTableHistogram(tableName).updateIncrement(t); 160 } 161 162 @Override 163 public void updateAppend(String tableName, long t) { 164 getOrCreateTableHistogram(tableName).updateAppend(t); 165 } 166 167 @Override 168 public void updateScanSize(String tableName, long scanSize) { 169 getOrCreateTableHistogram(tableName).updateScanSize(scanSize); 170 } 171 172 @Override 173 public void updateScanTime(String tableName, long t) { 174 getOrCreateTableHistogram(tableName).updateScanTime(t); 175 } 176 177 @Override 178 public void getMetrics(MetricsCollector metricsCollector, boolean all) { 179 MetricsRecordBuilder mrb = metricsCollector.addRecord(metricsName); 180 // source is registered in supers constructor, sometimes called before the whole initialization. 181 metricsRegistry.snapshot(mrb, all); 182 if (metricsAdapter != null) { 183 // snapshot MetricRegistry as well 184 metricsAdapter.snapshotAllMetrics(registry, mrb); 185 } 186 } 187}