1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.master.balancer;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertTrue;
22 import static org.mockito.Mockito.mock;
23 import static org.mockito.Mockito.when;
24
25 import java.util.HashMap;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.TreeMap;
31
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.ClusterStatus;
34 import org.apache.hadoop.hbase.HBaseConfiguration;
35 import org.apache.hadoop.hbase.HBaseIOException;
36 import org.apache.hadoop.hbase.HRegionInfo;
37 import org.apache.hadoop.hbase.RegionLoad;
38 import org.apache.hadoop.hbase.ServerLoad;
39 import org.apache.hadoop.hbase.ServerName;
40 import org.apache.hadoop.hbase.master.RegionPlan;
41 import org.apache.hadoop.hbase.rsgroup.RSGroupBasedLoadBalancer;
42 import org.apache.hadoop.hbase.rsgroup.RSGroupInfo;
43 import org.apache.hadoop.hbase.testclassification.SmallTests;
44 import org.apache.hadoop.hbase.util.Bytes;
45 import org.junit.BeforeClass;
46 import org.junit.Test;
47 import org.junit.experimental.categories.Category;
48 import org.mockito.Mockito;
49 import org.mockito.invocation.InvocationOnMock;
50 import org.mockito.stubbing.Answer;
51
52
53
54
55 @Category(SmallTests.class)
56 public class TestRSGroupBasedLoadBalancerWithStochasticLoadBalancerAsInternal
57 extends RSGroupableBalancerTestBase {
58 private static RSGroupBasedLoadBalancer loadBalancer;
59
60 @BeforeClass
61 public static void beforeAllTests() throws Exception {
62 groups = new String[] { RSGroupInfo.DEFAULT_GROUP };
63 servers = generateServers(3);
64 groupMap = constructGroupInfo(servers, groups);
65 tableDescs = constructTableDesc(false);
66 Configuration conf = HBaseConfiguration.create();
67 conf.set("hbase.regions.slop", "0");
68 conf.setFloat("hbase.master.balancer.stochastic.readRequestCost", 10000f);
69 conf.set("hbase.rsgroup.grouploadbalancer.class",
70 StochasticLoadBalancer.class.getCanonicalName());
71 loadBalancer = new RSGroupBasedLoadBalancer(getMockedGroupInfoManager());
72 loadBalancer.setMasterServices(getMockedMaster());
73 loadBalancer.setConf(conf);
74 loadBalancer.initialize();
75 }
76
77 private ServerLoad mockServerLoadWithReadRequests(ServerName server,
78 List<HRegionInfo> regionsOnServer, long readRequestCount) {
79 ServerLoad serverMetrics = mock(ServerLoad.class);
80 Map<byte[], RegionLoad> regionLoadMap = new TreeMap<>(Bytes.BYTES_COMPARATOR);
81 for(HRegionInfo info : regionsOnServer){
82 RegionLoad rl = mock(RegionLoad.class);
83 when(rl.getReadRequestsCount()).thenReturn(readRequestCount);
84 when(rl.getWriteRequestsCount()).thenReturn(0L);
85 when(rl.getMemStoreSizeMB()).thenReturn(0);
86 when(rl.getStorefileSizeMB()).thenReturn(0);
87 regionLoadMap.put(info.getRegionName(), rl);
88 }
89 when(serverMetrics.getRegionsLoad()).thenReturn(regionLoadMap);
90 return serverMetrics;
91 }
92
93
94
95
96 @Test
97 public void testBalanceCluster() throws HBaseIOException {
98
99 Map<ServerName, List<HRegionInfo>> clusterState = new HashMap<ServerName, List<HRegionInfo>>();
100 ServerName serverA = servers.get(0);
101 ServerName serverB = servers.get(1);
102 ServerName serverC = servers.get(2);
103 List<HRegionInfo> regionsOnServerA = randomRegions(3);
104 List<HRegionInfo> regionsOnServerB = randomRegions(3);
105 List<HRegionInfo> regionsOnServerC = randomRegions(3);
106 clusterState.put(serverA, regionsOnServerA);
107 clusterState.put(serverB, regionsOnServerB);
108 clusterState.put(serverC, regionsOnServerC);
109
110 final Map<ServerName, ServerLoad> serverMetricsMap = new TreeMap<>();
111 serverMetricsMap.put(serverA, mockServerLoadWithReadRequests(serverA, regionsOnServerA, 0));
112 serverMetricsMap.put(serverB, mockServerLoadWithReadRequests(serverB, regionsOnServerB, 0));
113 serverMetricsMap.put(serverC, mockServerLoadWithReadRequests(serverC, regionsOnServerC, 0));
114 ClusterStatus clusterStatus = mock(ClusterStatus.class);
115 when(clusterStatus.getServers()).thenReturn(serverMetricsMap.keySet());
116 when(clusterStatus.getLoad(Mockito.any(ServerName.class)))
117 .thenAnswer(new Answer<ServerLoad>() {
118 @Override
119 public ServerLoad answer(InvocationOnMock invocation) throws Throwable {
120 return serverMetricsMap.get(invocation.getArguments()[0]);
121 }
122 });
123 loadBalancer.setClusterStatus(clusterStatus);
124
125
126
127
128
129
130
131 final Map<ServerName, ServerLoad> serverMetricsMap2 = new TreeMap<>();
132 serverMetricsMap2.put(serverA, mockServerLoadWithReadRequests(serverA,
133 regionsOnServerA, 1000));
134 serverMetricsMap2.put(serverB, mockServerLoadWithReadRequests(serverB, regionsOnServerB, 0));
135 serverMetricsMap2.put(serverC, mockServerLoadWithReadRequests(serverC, regionsOnServerC, 0));
136 clusterStatus = mock(ClusterStatus.class);
137 when(clusterStatus.getServers()).thenReturn(serverMetricsMap2.keySet());
138 when(clusterStatus.getLoad(Mockito.any(ServerName.class)))
139 .thenAnswer(new Answer<ServerLoad>() {
140 @Override
141 public ServerLoad answer(InvocationOnMock invocation) throws Throwable {
142 return serverMetricsMap2.get(invocation.getArguments()[0]);
143 }
144 });
145 loadBalancer.setClusterStatus(clusterStatus);
146
147 List<RegionPlan> plans = loadBalancer.balanceCluster(clusterState);
148 Set<HRegionInfo> regionsMoveFromServerA = new HashSet<>();
149 Set<ServerName> targetServers = new HashSet<>();
150 for(RegionPlan plan : plans) {
151 if(plan.getSource().equals(serverA)) {
152 regionsMoveFromServerA.add(plan.getRegionInfo());
153 targetServers.add(plan.getDestination());
154 }
155 }
156
157 assertEquals(2, regionsMoveFromServerA.size());
158 assertEquals(2, targetServers.size());
159 assertTrue(regionsOnServerA.containsAll(regionsMoveFromServerA));
160 }
161 }