1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master.balancer;
20
21 import java.util.LinkedHashMap;
22 import java.util.Map;
23 import java.util.concurrent.ConcurrentHashMap;
24
25 import org.apache.hadoop.hbase.classification.InterfaceAudience;
26 import org.apache.hadoop.metrics2.MetricsCollector;
27 import org.apache.hadoop.metrics2.MetricsRecordBuilder;
28 import org.apache.hadoop.metrics2.lib.Interns;
29
30 @InterfaceAudience.Private
31 public class MetricsStochasticBalancerSourceImpl extends MetricsBalancerSourceImpl implements
32 MetricsStochasticBalancerSource {
33 private static final String TABLE_FUNCTION_SEP = "_";
34
35
36 private static final float MRU_LOAD_FACTOR = 0.75f;
37 private int metricsSize = 1000;
38 private int mruCap = calcMruCap(metricsSize);
39
40 private Map<String, Map<String, Double>> stochasticCosts =
41 new LinkedHashMap<String, Map<String, Double>>(mruCap, MRU_LOAD_FACTOR, true) {
42 private static final long serialVersionUID = 8204713453436906599L;
43
44 @Override
45 protected boolean removeEldestEntry(Map.Entry<String, Map<String, Double>> eldest) {
46 return size() > mruCap;
47 }
48 };
49 private Map<String, String> costFunctionDescs = new ConcurrentHashMap<String, String>();
50
51
52
53
54 private static int calcMruCap(int metricsSize) {
55 return (int) Math.ceil(metricsSize / MRU_LOAD_FACTOR) + 1;
56 }
57
58 @Override
59 public void updateMetricsSize(int size) {
60 if (size > 0) {
61 metricsSize = size;
62 mruCap = calcMruCap(size);
63 }
64 }
65
66
67
68
69 public void updateStochasticCost(String tableName, String costFunctionName, String functionDesc,
70 Double cost) {
71 if (tableName == null || costFunctionName == null || cost == null) {
72 return;
73 }
74
75 if (functionDesc != null) {
76 costFunctionDescs.put(costFunctionName, functionDesc);
77 }
78
79 synchronized (stochasticCosts) {
80 Map<String, Double> costs = stochasticCosts.get(tableName);
81 if (costs == null) {
82 costs = new ConcurrentHashMap<String, Double>();
83 }
84
85 costs.put(costFunctionName, cost);
86 stochasticCosts.put(tableName, costs);
87 }
88 }
89
90 @Override
91 public void getMetrics(MetricsCollector metricsCollector, boolean all) {
92 MetricsRecordBuilder metricsRecordBuilder = metricsCollector.addRecord(metricsName);
93
94 if (stochasticCosts != null) {
95 synchronized (stochasticCosts) {
96 for (Map.Entry<String, Map<String, Double>> tableEntry : stochasticCosts.entrySet()) {
97 for (Map.Entry<String, Double> costEntry : tableEntry.getValue().entrySet()) {
98 String attrName = tableEntry.getKey() + TABLE_FUNCTION_SEP + costEntry.getKey();
99 Double cost = costEntry.getValue();
100 String functionDesc = costFunctionDescs.get(costEntry.getKey());
101 if (functionDesc == null) functionDesc = costEntry.getKey();
102 metricsRecordBuilder.addGauge(Interns.info(attrName, functionDesc), cost);
103 }
104 }
105 }
106 }
107 metricsRegistry.snapshot(metricsRecordBuilder, all);
108 }
109
110 }