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
23 import java.util.ArrayList;
24 import java.util.List;
25 import java.util.Map;
26 import java.util.Set;
27 import java.util.TreeMap;
28 import java.util.TreeSet;
29
30 import org.apache.commons.logging.Log;
31 import org.apache.commons.logging.LogFactory;
32 import org.apache.hadoop.conf.Configuration;
33 import org.apache.hadoop.hbase.HBaseConfiguration;
34 import org.apache.hadoop.hbase.HRegionInfo;
35 import org.apache.hadoop.hbase.MediumTests;
36 import org.apache.hadoop.hbase.ServerName;
37 import org.apache.hadoop.hbase.master.LoadBalancer;
38 import org.apache.hadoop.hbase.master.RegionPlan;
39 import org.junit.BeforeClass;
40 import org.junit.Test;
41 import org.junit.experimental.categories.Category;
42
43 @Category(MediumTests.class)
44 public class TestBaseLoadBalancer extends BalancerTestBase {
45
46 private static LoadBalancer loadBalancer;
47 private static final Log LOG = LogFactory.getLog(TestStochasticLoadBalancer.class);
48
49 int[][] regionsAndServersMocks = new int[][] {
50
51 new int[] { 0, 0 }, new int[] { 0, 1 }, new int[] { 1, 1 }, new int[] { 2, 1 },
52 new int[] { 10, 1 }, new int[] { 1, 2 }, new int[] { 2, 2 }, new int[] { 3, 2 },
53 new int[] { 1, 3 }, new int[] { 2, 3 }, new int[] { 3, 3 }, new int[] { 25, 3 },
54 new int[] { 2, 10 }, new int[] { 2, 100 }, new int[] { 12, 10 }, new int[] { 12, 100 }, };
55
56 @BeforeClass
57 public static void beforeAllTests() throws Exception {
58 Configuration conf = HBaseConfiguration.create();
59 loadBalancer = new MockBalancer();
60 loadBalancer.setConf(conf);
61 }
62
63 public static class MockBalancer extends BaseLoadBalancer {
64
65 @Override
66 public List<RegionPlan> balanceCluster(Map<ServerName, List<HRegionInfo>> clusterState) {
67 return null;
68 }
69
70 }
71
72
73
74
75
76
77
78
79 @Test
80 public void testImmediateAssignment() throws Exception {
81 for (int[] mock : regionsAndServersMocks) {
82 LOG.debug("testImmediateAssignment with " + mock[0] + " regions and " + mock[1] + " servers");
83 List<HRegionInfo> regions = randomRegions(mock[0]);
84 List<ServerAndLoad> servers = randomServers(mock[1], 0);
85 List<ServerName> list = getListOfServerNames(servers);
86 Map<HRegionInfo, ServerName> assignments = loadBalancer.immediateAssignment(regions, list);
87 assertImmediateAssignment(regions, list, assignments);
88 returnRegions(regions);
89 returnServers(list);
90 }
91 }
92
93
94
95
96
97
98
99 private void assertImmediateAssignment(List<HRegionInfo> regions, List<ServerName> servers,
100 Map<HRegionInfo, ServerName> assignments) {
101 for (HRegionInfo region : regions) {
102 assertTrue(assignments.containsKey(region));
103 }
104 }
105
106
107
108
109
110
111
112
113
114 @Test
115 public void testBulkAssignment() throws Exception {
116 for (int[] mock : regionsAndServersMocks) {
117 LOG.debug("testBulkAssignment with " + mock[0] + " regions and " + mock[1] + " servers");
118 List<HRegionInfo> regions = randomRegions(mock[0]);
119 List<ServerAndLoad> servers = randomServers(mock[1], 0);
120 List<ServerName> list = getListOfServerNames(servers);
121 Map<ServerName, List<HRegionInfo>> assignments =
122 loadBalancer.roundRobinAssignment(regions, list);
123 float average = (float) regions.size() / servers.size();
124 int min = (int) Math.floor(average);
125 int max = (int) Math.ceil(average);
126 if (assignments != null && !assignments.isEmpty()) {
127 for (List<HRegionInfo> regionList : assignments.values()) {
128 assertTrue(regionList.size() == min || regionList.size() == max);
129 }
130 }
131 returnRegions(regions);
132 returnServers(list);
133 }
134 }
135
136
137
138
139
140
141 @Test
142 public void testRetainAssignment() throws Exception {
143
144 List<ServerAndLoad> servers = randomServers(10, 10);
145 List<HRegionInfo> regions = randomRegions(100);
146 Map<HRegionInfo, ServerName> existing = new TreeMap<HRegionInfo, ServerName>();
147 for (int i = 0; i < regions.size(); i++) {
148 ServerName sn = servers.get(i % servers.size()).getServerName();
149
150
151 ServerName snWithOldStartCode =
152 ServerName.valueOf(sn.getHostname(), sn.getPort(), sn.getStartcode() - 10);
153 existing.put(regions.get(i), snWithOldStartCode);
154 }
155 List<ServerName> listOfServerNames = getListOfServerNames(servers);
156 Map<ServerName, List<HRegionInfo>> assignment =
157 loadBalancer.retainAssignment(existing, listOfServerNames);
158 assertRetainedAssignment(existing, listOfServerNames, assignment);
159
160
161 List<ServerAndLoad> servers2 = new ArrayList<ServerAndLoad>(servers);
162 servers2.add(randomServer(10));
163 servers2.add(randomServer(10));
164 listOfServerNames = getListOfServerNames(servers2);
165 assignment = loadBalancer.retainAssignment(existing, listOfServerNames);
166 assertRetainedAssignment(existing, listOfServerNames, assignment);
167
168
169 List<ServerAndLoad> servers3 = new ArrayList<ServerAndLoad>(servers);
170 servers3.remove(0);
171 servers3.remove(0);
172 listOfServerNames = getListOfServerNames(servers3);
173 assignment = loadBalancer.retainAssignment(existing, listOfServerNames);
174 assertRetainedAssignment(existing, listOfServerNames, assignment);
175 }
176
177 private List<ServerName> getListOfServerNames(final List<ServerAndLoad> sals) {
178 List<ServerName> list = new ArrayList<ServerName>();
179 for (ServerAndLoad e : sals) {
180 list.add(e.getServerName());
181 }
182 return list;
183 }
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198 private void assertRetainedAssignment(Map<HRegionInfo, ServerName> existing,
199 List<ServerName> servers, Map<ServerName, List<HRegionInfo>> assignment) {
200
201 Set<ServerName> onlineServerSet = new TreeSet<ServerName>(servers);
202 Set<HRegionInfo> assignedRegions = new TreeSet<HRegionInfo>();
203 for (Map.Entry<ServerName, List<HRegionInfo>> a : assignment.entrySet()) {
204 assertTrue("Region assigned to server that was not listed as online",
205 onlineServerSet.contains(a.getKey()));
206 for (HRegionInfo r : a.getValue())
207 assignedRegions.add(r);
208 }
209 assertEquals(existing.size(), assignedRegions.size());
210
211
212 Set<String> onlineHostNames = new TreeSet<String>();
213 for (ServerName s : servers) {
214 onlineHostNames.add(s.getHostname());
215 }
216
217 for (Map.Entry<ServerName, List<HRegionInfo>> a : assignment.entrySet()) {
218 ServerName assignedTo = a.getKey();
219 for (HRegionInfo r : a.getValue()) {
220 ServerName address = existing.get(r);
221 if (address != null && onlineHostNames.contains(address.getHostname())) {
222
223
224
225 assertEquals(address.getHostname(), assignedTo.getHostname());
226 }
227 }
228 }
229 }
230
231 }