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.master.balancer; 019 020import static org.junit.Assert.assertNotNull; 021import static org.junit.Assert.assertNull; 022 023import java.util.List; 024import java.util.Map; 025import org.apache.hadoop.hbase.HBaseConfiguration; 026import org.apache.hadoop.hbase.ServerName; 027import org.apache.hadoop.hbase.TableName; 028import org.apache.hadoop.hbase.client.RegionInfo; 029import org.apache.hadoop.hbase.master.RackManager; 030import org.apache.hadoop.hbase.master.RegionPlan; 031import org.apache.hadoop.net.DNSToSwitchMapping; 032import org.junit.BeforeClass; 033import org.slf4j.Logger; 034import org.slf4j.LoggerFactory; 035 036public class StochasticBalancerTestBase extends BalancerTestBase { 037 038 private static final Logger LOG = LoggerFactory.getLogger(StochasticBalancerTestBase.class); 039 040 protected static StochasticLoadBalancer loadBalancer; 041 042 protected static DummyMetricsStochasticBalancer dummyMetricsStochasticBalancer = 043 new DummyMetricsStochasticBalancer(); 044 045 @BeforeClass 046 public static void beforeAllTests() throws Exception { 047 conf = HBaseConfiguration.create(); 048 conf.setClass("hbase.util.ip.to.rack.determiner", MockMapping.class, DNSToSwitchMapping.class); 049 conf.setFloat("hbase.master.balancer.stochastic.localityCost", 0); 050 conf.setBoolean("hbase.master.balancer.stochastic.runMaxSteps", true); 051 loadBalancer = new StochasticLoadBalancer(dummyMetricsStochasticBalancer); 052 loadBalancer.setClusterInfoProvider(new DummyClusterInfoProvider(conf)); 053 loadBalancer.initialize(); 054 } 055 056 protected void testWithCluster(int numNodes, int numRegions, int numRegionsPerServer, 057 int replication, int numTables, boolean assertFullyBalanced, 058 boolean assertFullyBalancedForReplicas) { 059 Map<ServerName, List<RegionInfo>> serverMap = 060 createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables); 061 testWithCluster(serverMap, null, assertFullyBalanced, assertFullyBalancedForReplicas); 062 } 063 064 protected void testWithClusterWithIteration(int numNodes, int numRegions, int numRegionsPerServer, 065 int replication, int numTables, boolean assertFullyBalanced, 066 boolean assertFullyBalancedForReplicas) { 067 Map<ServerName, List<RegionInfo>> serverMap = 068 createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables); 069 testWithClusterWithIteration(serverMap, null, assertFullyBalanced, 070 assertFullyBalancedForReplicas); 071 } 072 073 protected void testWithCluster(Map<ServerName, List<RegionInfo>> serverMap, 074 RackManager rackManager, boolean assertFullyBalanced, boolean assertFullyBalancedForReplicas) { 075 List<ServerAndLoad> list = convertToList(serverMap); 076 LOG.info("Mock Cluster : " + printMock(list) + " " + printStats(list)); 077 078 loadBalancer.setRackManager(rackManager); 079 // Run the balancer. 080 Map<TableName, Map<ServerName, List<RegionInfo>>> LoadOfAllTable = 081 (Map) mockClusterServersWithTables(serverMap); 082 List<RegionPlan> plans = loadBalancer.balanceCluster(LoadOfAllTable); 083 assertNotNull("Initial cluster balance should produce plans.", plans); 084 085 // Check to see that this actually got to a stable place. 086 if (assertFullyBalanced || assertFullyBalancedForReplicas) { 087 // Apply the plan to the mock cluster. 088 List<ServerAndLoad> balancedCluster = reconcile(list, plans, serverMap); 089 090 // Print out the cluster loads to make debugging easier. 091 LOG.info("Mock after Balance : " + printMock(balancedCluster)); 092 093 if (assertFullyBalanced) { 094 assertClusterAsBalanced(balancedCluster); 095 LoadOfAllTable = (Map) mockClusterServersWithTables(serverMap); 096 List<RegionPlan> secondPlans = loadBalancer.balanceCluster(LoadOfAllTable); 097 assertNull("Given a requirement to be fully balanced, second attempt at plans should " 098 + "produce none.", secondPlans); 099 } 100 101 if (assertFullyBalancedForReplicas) { 102 assertRegionReplicaPlacement(serverMap, rackManager); 103 } 104 } 105 } 106 107 protected void testWithClusterWithIteration(Map<ServerName, List<RegionInfo>> serverMap, 108 RackManager rackManager, boolean assertFullyBalanced, boolean assertFullyBalancedForReplicas) { 109 List<ServerAndLoad> list = convertToList(serverMap); 110 LOG.info("Mock Cluster : " + printMock(list) + " " + printStats(list)); 111 112 loadBalancer.setRackManager(rackManager); 113 // Run the balancer. 114 Map<TableName, Map<ServerName, List<RegionInfo>>> LoadOfAllTable = 115 (Map) mockClusterServersWithTables(serverMap); 116 List<RegionPlan> plans = loadBalancer.balanceCluster(LoadOfAllTable); 117 assertNotNull("Initial cluster balance should produce plans.", plans); 118 119 List<ServerAndLoad> balancedCluster = null; 120 // Run through iteration until done. Otherwise will be killed as test time out 121 while (plans != null && (assertFullyBalanced || assertFullyBalancedForReplicas)) { 122 // Apply the plan to the mock cluster. 123 balancedCluster = reconcile(list, plans, serverMap); 124 125 // Print out the cluster loads to make debugging easier. 126 LOG.info("Mock after balance: " + printMock(balancedCluster)); 127 128 LoadOfAllTable = (Map) mockClusterServersWithTables(serverMap); 129 plans = loadBalancer.balanceCluster(LoadOfAllTable); 130 } 131 132 // Print out the cluster loads to make debugging easier. 133 LOG.info("Mock Final balance: " + printMock(balancedCluster)); 134 135 if (assertFullyBalanced) { 136 assertNull("Given a requirement to be fully balanced, second attempt at plans should " 137 + "produce none.", plans); 138 } 139 if (assertFullyBalancedForReplicas) { 140 assertRegionReplicaPlacement(serverMap, rackManager); 141 } 142 } 143}