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.assertNotNull;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.Mockito.mock;
25 import static org.mockito.Mockito.when;
26
27 import java.util.ArrayList;
28 import java.util.Arrays;
29 import java.util.HashMap;
30 import java.util.Iterator;
31 import java.util.List;
32 import java.util.Map;
33 import java.util.Map.Entry;
34 import java.util.Queue;
35 import java.util.TreeMap;
36
37 import org.apache.commons.logging.Log;
38 import org.apache.commons.logging.LogFactory;
39 import org.apache.hadoop.conf.Configuration;
40 import org.apache.hadoop.hbase.ClusterStatus;
41 import org.apache.hadoop.hbase.HBaseConfiguration;
42 import org.apache.hadoop.hbase.HRegionInfo;
43 import org.apache.hadoop.hbase.RegionLoad;
44 import org.apache.hadoop.hbase.ServerLoad;
45 import org.apache.hadoop.hbase.ServerName;
46 import org.apache.hadoop.hbase.client.RegionReplicaUtil;
47 import org.apache.hadoop.hbase.master.MockNoopMasterServices;
48 import org.apache.hadoop.hbase.master.RackManager;
49 import org.apache.hadoop.hbase.master.RegionPlan;
50 import org.apache.hadoop.hbase.master.balancer.BaseLoadBalancer.Cluster;
51 import org.apache.hadoop.hbase.master.balancer.StochasticLoadBalancer.ServerLocalityCostFunction;
52 import org.apache.hadoop.hbase.testclassification.FlakeyTests;
53 import org.apache.hadoop.hbase.testclassification.MediumTests;
54 import org.apache.hadoop.hbase.util.Bytes;
55 import org.junit.Ignore;
56 import org.junit.Test;
57 import org.junit.experimental.categories.Category;
58
59 @Category({FlakeyTests.class, MediumTests.class})
60 public class TestStochasticLoadBalancer extends BalancerTestBase {
61 public static final String REGION_KEY = "testRegion";
62 private static final Log LOG = LogFactory.getLog(TestStochasticLoadBalancer.class);
63
64
65 private float[] expectedLocalities = {1.0f, 0.0f, 0.50f, 0.25f, 1.0f};
66
67
68
69
70
71
72
73
74 private int[][][] clusterRegionLocationMocks = new int[][][]{
75
76
77 new int[][]{
78 new int[]{2, 1, 1},
79 new int[]{2, 0, 0, 100},
80 new int[]{0, 100, 0, 0},
81 new int[]{0, 100, 0, 0},
82 new int[]{1, 0, 100, 0},
83 },
84
85
86 new int[][]{
87 new int[]{1, 2, 1},
88 new int[]{0, 0, 0, 100},
89 new int[]{1, 100, 0, 0},
90 new int[]{1, 100, 0, 0},
91 new int[]{2, 0, 100, 0},
92 },
93
94
95 new int[][]{
96 new int[]{1, 2, 1},
97 new int[]{0, 25, 0, 50},
98 new int[]{1, 50, 25, 0},
99 new int[]{1, 50, 25, 0},
100 new int[]{2, 0, 50, 25},
101 },
102
103
104 new int[][]{
105 new int[]{1, 2, 1},
106 new int[]{0, 25, 0, 100},
107 new int[]{1, 100, 25, 0},
108 new int[]{1, 100, 25, 0},
109 new int[]{2, 0, 100, 25},
110 },
111
112
113 new int[][]{
114 new int[]{1, 2, 1},
115 new int[]{0, 75, 75, 75},
116 new int[]{1, 75, 75, 75},
117 new int[]{1, 75, 75, 75},
118 new int[]{2, 75, 75, 75},
119 },
120 };
121
122
123 @Test
124 public void testKeepRegionLoad() throws Exception {
125
126 ServerName sn = ServerName.valueOf("test:8080", 100);
127 int numClusterStatusToAdd = 20000;
128 for (int i = 0; i < numClusterStatusToAdd; i++) {
129 ServerLoad sl = mock(ServerLoad.class);
130
131 RegionLoad rl = mock(RegionLoad.class);
132 when(rl.getStores()).thenReturn(i);
133
134 Map<byte[], RegionLoad> regionLoadMap =
135 new TreeMap<byte[], RegionLoad>(Bytes.BYTES_COMPARATOR);
136 regionLoadMap.put(Bytes.toBytes(REGION_KEY), rl);
137 when(sl.getRegionsLoad()).thenReturn(regionLoadMap);
138
139 ClusterStatus clusterStatus = mock(ClusterStatus.class);
140 when(clusterStatus.getServers()).thenReturn(Arrays.asList(sn));
141 when(clusterStatus.getLoad(sn)).thenReturn(sl);
142
143 loadBalancer.setClusterStatus(clusterStatus);
144 }
145
146 String regionNameAsString = HRegionInfo.getRegionNameAsString(Bytes.toBytes(REGION_KEY));
147 assertTrue(loadBalancer.loads.get(regionNameAsString) != null);
148 assertTrue(loadBalancer.loads.get(regionNameAsString).size() == 15);
149
150 Queue<RegionLoad> loads = loadBalancer.loads.get(regionNameAsString);
151 int i = 0;
152 while(loads.size() > 0) {
153 RegionLoad rl = loads.remove();
154 assertEquals(i + (numClusterStatusToAdd - 15), rl.getStores());
155 i ++;
156 }
157 }
158
159 @Test
160 public void testNeedBalance() {
161 float minCost = conf.getFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 0.05f);
162 conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", 1.0f);
163 loadBalancer.setConf(conf);
164 for (int[] mockCluster : clusterStateMocks) {
165 Map<ServerName, List<HRegionInfo>> servers = mockClusterServers(mockCluster);
166 List<RegionPlan> plans = loadBalancer.balanceCluster(servers);
167 assertNull(plans);
168 }
169
170 conf.setFloat("hbase.master.balancer.stochastic.minCostNeedBalance", minCost);
171 loadBalancer.setConf(conf);
172 }
173
174
175
176
177
178
179
180
181
182 @Test
183 public void testBalanceCluster() throws Exception {
184
185 for (int[] mockCluster : clusterStateMocks) {
186 Map<ServerName, List<HRegionInfo>> servers = mockClusterServers(mockCluster);
187 List<ServerAndLoad> list = convertToList(servers);
188 LOG.info("Mock Cluster : " + printMock(list) + " " + printStats(list));
189 List<RegionPlan> plans = loadBalancer.balanceCluster(servers);
190 List<ServerAndLoad> balancedCluster = reconcile(list, plans, servers);
191 LOG.info("Mock Balance : " + printMock(balancedCluster));
192 assertClusterAsBalanced(balancedCluster);
193 List<RegionPlan> secondPlans = loadBalancer.balanceCluster(servers);
194 assertNull(secondPlans);
195 for (Map.Entry<ServerName, List<HRegionInfo>> entry : servers.entrySet()) {
196 returnRegions(entry.getValue());
197 returnServer(entry.getKey());
198 }
199 }
200 }
201
202 @Test
203 public void testLocalityCost() throws Exception {
204 Configuration conf = HBaseConfiguration.create();
205 MockNoopMasterServices master = new MockNoopMasterServices();
206 StochasticLoadBalancer.CostFunction
207 costFunction = new ServerLocalityCostFunction(conf, master);
208
209 for (int test = 0; test < clusterRegionLocationMocks.length; test++) {
210 int[][] clusterRegionLocations = clusterRegionLocationMocks[test];
211 MockCluster cluster = new MockCluster(clusterRegionLocations);
212 costFunction.init(cluster);
213 double cost = costFunction.cost();
214 double expected = 1 - expectedLocalities[test];
215 assertEquals(expected, cost, 0.001);
216 }
217 }
218
219 @Test
220 public void testMoveCost() throws Exception {
221 Configuration conf = HBaseConfiguration.create();
222 StochasticLoadBalancer.CostFunction
223 costFunction = new StochasticLoadBalancer.MoveCostFunction(conf);
224 for (int[] mockCluster : clusterStateMocks) {
225 BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);
226 costFunction.init(cluster);
227 double cost = costFunction.cost();
228 assertEquals(0.0f, cost, 0.001);
229
230
231 cluster.setNumRegions(200);
232 cluster.setNumMovedRegions(10);
233 cost = costFunction.cost();
234 assertEquals(0.05f, cost, 0.001);
235 cluster.setNumMovedRegions(100);
236 cost = costFunction.cost();
237 assertEquals(0.5f, cost, 0.001);
238 cluster.setNumMovedRegions(200);
239 cost = costFunction.cost();
240 assertEquals(1.0f, cost, 0.001);
241
242
243
244 cluster.setNumRegions(10000);
245 cluster.setNumMovedRegions(250);
246 cost = costFunction.cost();
247 assertEquals(0.1f, cost, 0.001);
248 cluster.setNumMovedRegions(1250);
249 cost = costFunction.cost();
250 assertEquals(0.5f, cost, 0.001);
251 cluster.setNumMovedRegions(2500);
252 cost = costFunction.cost();
253 assertEquals(1.0f, cost, 0.01);
254 }
255 }
256
257 @Test
258 public void testSkewCost() {
259 Configuration conf = HBaseConfiguration.create();
260 StochasticLoadBalancer.CostFunction
261 costFunction = new StochasticLoadBalancer.RegionCountSkewCostFunction(conf);
262 for (int[] mockCluster : clusterStateMocks) {
263 costFunction.init(mockCluster(mockCluster));
264 double cost = costFunction.cost();
265 assertTrue(cost >= 0);
266 assertTrue(cost <= 1.01);
267 }
268
269 costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));
270 assertEquals(0,costFunction.cost(), 0.01);
271 costFunction.init(mockCluster(new int[]{0, 0, 0, 1, 1}));
272 assertEquals(0, costFunction.cost(), 0.01);
273 costFunction.init(mockCluster(new int[]{0, 0, 1, 1, 1}));
274 assertEquals(0, costFunction.cost(), 0.01);
275 costFunction.init(mockCluster(new int[]{0, 1, 1, 1, 1}));
276 assertEquals(0, costFunction.cost(), 0.01);
277 costFunction.init(mockCluster(new int[]{1, 1, 1, 1, 1}));
278 assertEquals(0, costFunction.cost(), 0.01);
279 costFunction.init(mockCluster(new int[]{10000, 0, 0, 0, 0}));
280 assertEquals(1, costFunction.cost(), 0.01);
281 }
282
283 @Test
284 public void testCostAfterUndoAction() {
285 final int runs = 10;
286 loadBalancer.setConf(conf);
287 for (int[] mockCluster : clusterStateMocks) {
288 BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);
289 loadBalancer.initCosts(cluster);
290 for (int i = 0; i != runs; ++i) {
291 final double expectedCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);
292 Cluster.Action action = loadBalancer.nextAction(cluster);
293 cluster.doAction(action);
294 loadBalancer.updateCostsWithAction(cluster, action);
295 Cluster.Action undoAction = action.undoAction();
296 cluster.doAction(undoAction);
297 loadBalancer.updateCostsWithAction(cluster, undoAction);
298 final double actualCost = loadBalancer.computeCost(cluster, Double.MAX_VALUE);
299 assertEquals(expectedCost, actualCost, 0);
300 }
301 }
302 }
303
304 @Test
305 public void testTableSkewCost() {
306 Configuration conf = HBaseConfiguration.create();
307 StochasticLoadBalancer.CostFunction
308 costFunction = new StochasticLoadBalancer.TableSkewCostFunction(conf);
309 for (int[] mockCluster : clusterStateMocks) {
310 BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);
311 costFunction.init(cluster);
312 double cost = costFunction.cost();
313 assertTrue(cost >= 0);
314 assertTrue(cost <= 1.01);
315 }
316 }
317
318 @Test
319 public void testRegionLoadCost() {
320 List<RegionLoad> regionLoads = new ArrayList<>();
321 for (int i = 1; i < 5; i++) {
322 RegionLoad regionLoad = mock(RegionLoad.class);
323 when(regionLoad.getReadRequestsCount()).thenReturn(new Long(i));
324 when(regionLoad.getStorefileSizeMB()).thenReturn(i);
325 regionLoads.add(regionLoad);
326 }
327
328 Configuration conf = HBaseConfiguration.create();
329 StochasticLoadBalancer.ReadRequestCostFunction readCostFunction =
330 new StochasticLoadBalancer.ReadRequestCostFunction(conf);
331 double rateResult = readCostFunction.getRegionLoadCost(regionLoads);
332
333 assertEquals(1, rateResult, 0.01);
334
335 StochasticLoadBalancer.StoreFileCostFunction storeFileCostFunction =
336 new StochasticLoadBalancer.StoreFileCostFunction(conf);
337 double result = storeFileCostFunction.getRegionLoadCost(regionLoads);
338
339 assertEquals(2.5, result, 0.01);
340 }
341
342 @Test
343 public void testCostFromArray() {
344 Configuration conf = HBaseConfiguration.create();
345 StochasticLoadBalancer.CostFromRegionLoadFunction
346 costFunction = new StochasticLoadBalancer.MemstoreSizeCostFunction(conf);
347 costFunction.init(mockCluster(new int[]{0, 0, 0, 0, 1}));
348
349 double[] statOne = new double[100];
350 for (int i =0; i < 100; i++) {
351 statOne[i] = 10;
352 }
353 assertEquals(0, costFunction.costFromArray(statOne), 0.01);
354
355 double[] statTwo= new double[101];
356 for (int i =0; i < 100; i++) {
357 statTwo[i] = 0;
358 }
359 statTwo[100] = 100;
360 assertEquals(1, costFunction.costFromArray(statTwo), 0.01);
361
362 double[] statThree = new double[200];
363 for (int i =0; i < 100; i++) {
364 statThree[i] = (0);
365 statThree[i+100] = 100;
366 }
367 assertEquals(0.5, costFunction.costFromArray(statThree), 0.01);
368 }
369
370 @Test(timeout = 60000)
371 public void testLosingRs() throws Exception {
372 int numNodes = 3;
373 int numRegions = 20;
374 int numRegionsPerServer = 3;
375 int replication = 1;
376 int numTables = 2;
377
378 Map<ServerName, List<HRegionInfo>> serverMap =
379 createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);
380 List<ServerAndLoad> list = convertToList(serverMap);
381
382
383 List<RegionPlan> plans = loadBalancer.balanceCluster(serverMap);
384 assertNotNull(plans);
385
386
387 List<ServerAndLoad> balancedCluster = reconcile(list, plans, serverMap);
388
389 assertClusterAsBalanced(balancedCluster);
390
391 ServerName sn = serverMap.keySet().toArray(new ServerName[serverMap.size()])[0];
392
393 ServerName deadSn = ServerName.valueOf(sn.getHostname(), sn.getPort(), sn.getStartcode() - 100);
394
395 serverMap.put(deadSn, new ArrayList<HRegionInfo>(0));
396
397 plans = loadBalancer.balanceCluster(serverMap);
398 assertNull(plans);
399 }
400
401 @Test
402 public void testReplicaCost() {
403 Configuration conf = HBaseConfiguration.create();
404 StochasticLoadBalancer.CostFunction
405 costFunction = new StochasticLoadBalancer.RegionReplicaHostCostFunction(conf);
406 for (int[] mockCluster : clusterStateMocks) {
407 BaseLoadBalancer.Cluster cluster = mockCluster(mockCluster);
408 costFunction.init(cluster);
409 double cost = costFunction.cost();
410 assertTrue(cost >= 0);
411 assertTrue(cost <= 1.01);
412 }
413 }
414
415 @Test
416 public void testReplicaCostForReplicas() {
417 Configuration conf = HBaseConfiguration.create();
418 StochasticLoadBalancer.CostFunction
419 costFunction = new StochasticLoadBalancer.RegionReplicaHostCostFunction(conf);
420
421 int [] servers = new int[] {3,3,3,3,3};
422 TreeMap<ServerName, List<HRegionInfo>> clusterState = mockClusterServers(servers);
423
424 BaseLoadBalancer.Cluster cluster;
425
426 cluster = new BaseLoadBalancer.Cluster(clusterState, null, null, null);
427 costFunction.init(cluster);
428 double costWithoutReplicas = costFunction.cost();
429 assertEquals(0, costWithoutReplicas, 0);
430
431
432 HRegionInfo replica1 = RegionReplicaUtil.getRegionInfoForReplica(
433 clusterState.firstEntry().getValue().get(0),1);
434 clusterState.lastEntry().getValue().add(replica1);
435
436 cluster = new BaseLoadBalancer.Cluster(clusterState, null, null, null);
437 costFunction.init(cluster);
438 double costWith1ReplicaDifferentServer = costFunction.cost();
439
440 assertEquals(0, costWith1ReplicaDifferentServer, 0);
441
442
443 HRegionInfo replica2 = RegionReplicaUtil.getRegionInfoForReplica(replica1, 2);
444 clusterState.lastEntry().getValue().add(replica2);
445
446 cluster = new BaseLoadBalancer.Cluster(clusterState, null, null, null);
447 costFunction.init(cluster);
448 double costWith1ReplicaSameServer = costFunction.cost();
449
450 assertTrue(costWith1ReplicaDifferentServer < costWith1ReplicaSameServer);
451
452
453
454 HRegionInfo replica3;
455 Iterator<Entry<ServerName, List<HRegionInfo>>> it;
456 Entry<ServerName, List<HRegionInfo>> entry;
457
458 clusterState = mockClusterServers(servers);
459 it = clusterState.entrySet().iterator();
460 entry = it.next();
461 HRegionInfo hri = entry.getValue().get(0);
462 replica1 = RegionReplicaUtil.getRegionInfoForReplica(hri, 1);
463 replica2 = RegionReplicaUtil.getRegionInfoForReplica(hri, 2);
464 replica3 = RegionReplicaUtil.getRegionInfoForReplica(hri, 3);
465 entry.getValue().add(replica1);
466 entry.getValue().add(replica2);
467 it.next().getValue().add(replica3);
468
469 cluster = new BaseLoadBalancer.Cluster(clusterState, null, null, null);
470 costFunction.init(cluster);
471 double costWith3ReplicasSameServer = costFunction.cost();
472
473 clusterState = mockClusterServers(servers);
474 hri = clusterState.firstEntry().getValue().get(0);
475 replica1 = RegionReplicaUtil.getRegionInfoForReplica(hri, 1);
476 replica2 = RegionReplicaUtil.getRegionInfoForReplica(hri, 2);
477 replica3 = RegionReplicaUtil.getRegionInfoForReplica(hri, 3);
478
479 clusterState.firstEntry().getValue().add(replica1);
480 clusterState.lastEntry().getValue().add(replica2);
481 clusterState.lastEntry().getValue().add(replica3);
482
483 cluster = new BaseLoadBalancer.Cluster(clusterState, null, null, null);
484 costFunction.init(cluster);
485 double costWith2ReplicasOnTwoServers = costFunction.cost();
486
487 assertTrue(costWith2ReplicasOnTwoServers < costWith3ReplicasSameServer);
488 }
489
490 @Test
491 public void testNeedsBalanceForColocatedReplicas() {
492
493
494 List<HRegionInfo> regions = randomRegions(1);
495 ServerName s1 = ServerName.valueOf("host1", 1000, 11111);
496 ServerName s2 = ServerName.valueOf("host11", 1000, 11111);
497 Map<ServerName, List<HRegionInfo>> map = new HashMap<ServerName, List<HRegionInfo>>();
498 map.put(s1, regions);
499 regions.add(RegionReplicaUtil.getRegionInfoForReplica(regions.get(0), 1));
500
501 regions = randomRegions(1);
502 map.put(s2, regions);
503 assertTrue(loadBalancer.needsBalance(new Cluster(map, null, null, null)));
504
505
506 map.clear();
507 regions = randomRegions(1);
508 List<HRegionInfo> regionsOnS2 = new ArrayList<HRegionInfo>(1);
509 regionsOnS2.add(RegionReplicaUtil.getRegionInfoForReplica(regions.get(0), 1));
510 map.put(s1, regions);
511 map.put(s2, regionsOnS2);
512
513 map.put(ServerName.valueOf("host2", 1000, 11111), randomRegions(1));
514 assertTrue(loadBalancer.needsBalance(new Cluster(map, null, null,
515 new ForTestRackManagerOne())));
516 }
517
518 @Test (timeout = 60000)
519 public void testSmallCluster() {
520 int numNodes = 10;
521 int numRegions = 1000;
522 int numRegionsPerServer = 40;
523 int replication = 1;
524 int numTables = 10;
525 testWithCluster(numNodes, numRegions, numRegionsPerServer, replication, numTables, true, true);
526 }
527
528 @Test (timeout = 60000)
529 public void testSmallCluster2() {
530 int numNodes = 20;
531 int numRegions = 2000;
532 int numRegionsPerServer = 40;
533 int replication = 1;
534 int numTables = 10;
535 testWithCluster(numNodes, numRegions, numRegionsPerServer, replication, numTables, true, true);
536 }
537
538 @Test (timeout = 60000)
539 public void testSmallCluster3() {
540 int numNodes = 20;
541 int numRegions = 2000;
542 int numRegionsPerServer = 1;
543 int replication = 1;
544 int numTables = 10;
545
546 testWithCluster(numNodes, numRegions, numRegionsPerServer, replication, numTables, false, false);
547 }
548
549 @Test (timeout = 800000)
550 public void testMidCluster() {
551 int numNodes = 100;
552 int numRegions = 10000;
553 int numRegionsPerServer = 60;
554 int replication = 1;
555 int numTables = 40;
556 testWithCluster(numNodes, numRegions, numRegionsPerServer, replication, numTables, true, true);
557 }
558
559 @Test (timeout = 800000)
560 public void testMidCluster2() {
561 int numNodes = 200;
562 int numRegions = 100000;
563 int numRegionsPerServer = 40;
564 int replication = 1;
565 int numTables = 400;
566 testWithCluster(numNodes,
567 numRegions,
568 numRegionsPerServer,
569 replication,
570 numTables,
571 false,
572 false);
573 }
574
575
576 @Test (timeout = 800000)
577 public void testMidCluster3() {
578 int numNodes = 100;
579 int numRegions = 2000;
580 int numRegionsPerServer = 9;
581 int replication = 1;
582 int numTables = 110;
583 testWithCluster(numNodes, numRegions, numRegionsPerServer, replication, numTables, true, true);
584
585 }
586
587 @Test
588 public void testLargeCluster() {
589 int numNodes = 1000;
590 int numRegions = 100000;
591 int numRegionsPerServer = 80;
592 int numTables = 100;
593 int replication = 1;
594 testWithCluster(numNodes, numRegions, numRegionsPerServer, replication, numTables, true, true);
595 }
596
597 @Test (timeout = 800000)
598 public void testRegionReplicasOnSmallCluster() {
599 int numNodes = 10;
600 int numRegions = 1000;
601 int replication = 3;
602 int numRegionsPerServer = 80;
603 int numTables = 10;
604 testWithCluster(numNodes, numRegions, numRegionsPerServer, replication, numTables, true, true);
605 }
606
607 @Ignore @Test (timeout = 800000)
608 public void testRegionReplicationOnMidClusterSameHosts() {
609 conf.setLong(StochasticLoadBalancer.MAX_STEPS_KEY, 2000000L);
610 conf.setLong("hbase.master.balancer.stochastic.maxRunningTime", 90 * 1000);
611 conf.setFloat("hbase.master.balancer.stochastic.maxMovePercent", 1.0f);
612 loadBalancer.setConf(conf);
613 int numHosts = 100;
614 int numRegions = 100 * 100;
615 int replication = 3;
616 int numRegionsPerServer = 5;
617 int numTables = 10;
618 Map<ServerName, List<HRegionInfo>> serverMap =
619 createServerMap(numHosts, numRegions, numRegionsPerServer, replication, numTables);
620 int numNodesPerHost = 4;
621
622
623 Map<ServerName, List<HRegionInfo>> newServerMap = new TreeMap<ServerName, List<HRegionInfo>>(serverMap);
624 for (Map.Entry<ServerName, List<HRegionInfo>> entry : serverMap.entrySet()) {
625 for (int i=1; i < numNodesPerHost; i++) {
626 ServerName s1 = entry.getKey();
627 ServerName s2 = ServerName.valueOf(s1.getHostname(), s1.getPort() + i, 1);
628 newServerMap.put(s2, new ArrayList<HRegionInfo>());
629 }
630 }
631
632 testWithCluster(newServerMap, null, true, true);
633 }
634
635 private static class ForTestRackManager extends RackManager {
636 int numRacks;
637 public ForTestRackManager(int numRacks) {
638 this.numRacks = numRacks;
639 }
640 @Override
641 public String getRack(ServerName server) {
642 return "rack_" + (server.hashCode() % numRacks);
643 }
644 }
645
646 private static class ForTestRackManagerOne extends RackManager {
647 @Override
648 public String getRack(ServerName server) {
649 return server.getHostname().endsWith("1") ? "rack1" : "rack2";
650 }
651 }
652
653 @Test (timeout = 800000)
654 public void testRegionReplicationOnMidClusterWithRacks() {
655 conf.setLong(StochasticLoadBalancer.MAX_STEPS_KEY, 10000000L);
656 conf.setFloat("hbase.master.balancer.stochastic.maxMovePercent", 1.0f);
657 conf.setLong("hbase.master.balancer.stochastic.maxRunningTime", 120 * 1000);
658 loadBalancer.setConf(conf);
659 int numNodes = 30;
660 int numRegions = numNodes * 30;
661 int replication = 3;
662 int numRegionsPerServer = 28;
663 int numTables = 10;
664 int numRacks = 4;
665 Map<ServerName, List<HRegionInfo>> serverMap =
666 createServerMap(numNodes, numRegions, numRegionsPerServer, replication, numTables);
667 RackManager rm = new ForTestRackManager(numRacks);
668
669 testWithCluster(serverMap, rm, false, true);
670 }
671
672
673 private class MockCluster extends BaseLoadBalancer.Cluster {
674
675 private int[][] localities = null;
676
677 public MockCluster(int[][] regions) {
678
679
680 super(mockClusterServers(regions[0], 1), null, null, null);
681
682 localities = new int[regions.length - 1][];
683 for (int i = 1; i < regions.length; i++) {
684 int regionIndex = i - 1;
685 localities[regionIndex] = new int[regions[i].length - 1];
686 regionIndexToServerIndex[regionIndex] = regions[i][0];
687 for (int j = 1; j < regions[i].length; j++) {
688 int serverIndex = j - 1;
689 localities[regionIndex][serverIndex] = regions[i][j] > 100 ? regions[i][j] % 100 : regions[i][j];
690 }
691 }
692 }
693
694 @Override
695 float getLocalityOfRegion(int region, int server) {
696
697 return localities[region][server] / 100.0f;
698 }
699
700 @Override
701 public int getRegionSizeMB(int region) {
702 return 1;
703 }
704
705 }
706
707 }