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.List;
22  import java.util.Map;
23  
24  import org.apache.hadoop.hbase.HConstants;
25  import org.apache.hadoop.hbase.HRegionInfo;
26  import org.apache.hadoop.hbase.ServerName;
27  import org.apache.hadoop.hbase.client.LogEntry;
28  import org.apache.hadoop.hbase.master.RegionPlan;
29  import org.apache.hadoop.hbase.namequeues.BalancerDecisionDetails;
30  import org.apache.hadoop.hbase.namequeues.request.NamedQueueGetRequest;
31  import org.apache.hadoop.hbase.namequeues.response.NamedQueueGetResponse;
32  import org.apache.hadoop.hbase.protobuf.ProtobufUtil;
33  import org.apache.hadoop.hbase.protobuf.generated.MasterProtos;
34  import org.apache.hadoop.hbase.protobuf.generated.RecentLogs;
35  import org.apache.hadoop.hbase.testclassification.MasterTests;
36  import org.apache.hadoop.hbase.testclassification.MediumTests;
37  import org.junit.Assert;
38  import org.junit.Test;
39  import org.junit.experimental.categories.Category;
40  
41  /**
42   * Test BalancerDecision ring buffer using namedQueue interface
43   */
44  @Category({ MasterTests.class, MediumTests.class })
45  public class TestBalancerDecision extends BalancerTestBase {
46  
47    @Test
48    public void testBalancerDecisions() {
49      conf.setBoolean("hbase.master.balancer.decision.buffer.enabled", true);
50      loadBalancer.setConf(conf);
51      float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);
52      conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);
53      try {
54        // Test with/without per table balancer.
55        boolean[] perTableBalancerConfigs = {true, false};
56        for (boolean isByTable : perTableBalancerConfigs) {
57          conf.setBoolean(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE, isByTable);
58          loadBalancer.setConf(conf);
59          for (int[] mockCluster : clusterStateMocks) {
60            Map<ServerName, List<HRegionInfo>> servers = mockClusterServers(mockCluster);
61            List<RegionPlan> plans = loadBalancer.balanceCluster(servers);
62            boolean emptyPlans = plans == null || plans.isEmpty();
63            Assert.assertTrue(emptyPlans || needsBalanceIdleRegion(mockCluster));
64          }
65        }
66        final NamedQueueGetRequest namedQueueGetRequest = new NamedQueueGetRequest();
67        namedQueueGetRequest.setNamedQueueEvent(BalancerDecisionDetails.BALANCER_DECISION_EVENT);
68        namedQueueGetRequest
69          .setBalancerDecisionsRequest(MasterProtos.BalancerDecisionsRequest.getDefaultInstance());
70        NamedQueueGetResponse namedQueueGetResponse =
71          loadBalancer.namedQueueRecorder.getNamedQueueRecords(namedQueueGetRequest);
72        List<RecentLogs.BalancerDecision> balancerDecisions =
73          namedQueueGetResponse.getBalancerDecisions();
74        MasterProtos.BalancerDecisionsResponse response =
75          MasterProtos.BalancerDecisionsResponse.newBuilder()
76            .addAllBalancerDecision(balancerDecisions)
77            .build();
78        List<LogEntry> balancerDecisionRecords =
79          ProtobufUtil.getBalancerDecisionEntries(response);
80        Assert.assertTrue(balancerDecisionRecords.size() > 160);
81      } finally {
82        // reset config
83        conf.unset(HConstants.HBASE_MASTER_LOADBALANCE_BYTABLE);
84        conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", minCost);
85        loadBalancer.setConf(conf);
86      }
87    }
88  
89    private boolean needsBalanceIdleRegion(int[] clusters) {
90      boolean b1 = false;
91      boolean b2 = false;
92      for (int cluster : clusters) {
93        if (cluster > 1) {
94          b1 = true;
95        } else {
96          b2 = true;
97        }
98      }
99      return b1 && b2;
100   }
101 
102 }