View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
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    // Most Recently Used(MRU) cache
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     * Calculates the mru cache capacity from the metrics size
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     * Reports stochastic load balancer costs to JMX
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 }