1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver;
19
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNull;
23 import static org.junit.Assert.assertTrue;
24
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.List;
28
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.hbase.TableName;
31 import org.apache.hadoop.hbase.HBaseConfiguration;
32 import org.apache.hadoop.hbase.HConstants;
33 import org.apache.hadoop.hbase.HRegionInfo;
34 import org.apache.hadoop.hbase.HTableDescriptor;
35 import org.apache.hadoop.hbase.testclassification.SmallTests;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
38 import org.junit.Before;
39 import org.junit.Test;
40 import org.junit.experimental.categories.Category;
41 import org.mockito.Mockito;
42
43 @Category(SmallTests.class)
44 public class TestRegionSplitPolicy {
45
46 private Configuration conf;
47 private HTableDescriptor htd;
48 private HRegion mockRegion;
49 private List<Store> stores;
50 private static final TableName TABLENAME = TableName.valueOf("t");
51
52 @Before
53 public void setupMocks() {
54 conf = HBaseConfiguration.create();
55 HRegionInfo hri = new HRegionInfo(TABLENAME);
56 htd = new HTableDescriptor(TABLENAME);
57 mockRegion = Mockito.mock(HRegion.class);
58 Mockito.doReturn(htd).when(mockRegion).getTableDesc();
59 Mockito.doReturn(hri).when(mockRegion).getRegionInfo();
60 stores = new ArrayList<Store>();
61 Mockito.doReturn(stores).when(mockRegion).getStores();
62 }
63
64 @Test
65 public void testForceSplitRegionWithReference() throws IOException {
66 htd.setMaxFileSize(1024L);
67
68 HStore mockStore = Mockito.mock(HStore.class);
69 Mockito.doReturn(2000L).when(mockStore).getSize();
70
71
72 Mockito.doReturn(false).when(mockStore).canSplit();
73 stores.add(mockStore);
74
75 conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
76 ConstantSizeRegionSplitPolicy.class.getName());
77 ConstantSizeRegionSplitPolicy policy =
78 (ConstantSizeRegionSplitPolicy)RegionSplitPolicy.create(mockRegion, conf);
79 assertFalse(policy.shouldSplit());
80 Mockito.doReturn(true).when(mockRegion).shouldForceSplit();
81 assertFalse(policy.shouldSplit());
82
83 Mockito.doReturn(false).when(mockRegion).shouldForceSplit();
84 conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
85 IncreasingToUpperBoundRegionSplitPolicy.class.getName());
86 policy = (IncreasingToUpperBoundRegionSplitPolicy) RegionSplitPolicy.create(mockRegion, conf);
87 assertFalse(policy.shouldSplit());
88 Mockito.doReturn(true).when(mockRegion).shouldForceSplit();
89 assertFalse(policy.shouldSplit());
90 }
91
92 @Test
93 public void testIncreasingToUpperBoundRegionSplitPolicy() throws IOException {
94
95 conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
96 IncreasingToUpperBoundRegionSplitPolicy.class.getName());
97
98
99 RegionServerServices rss = Mockito.mock(RegionServerServices.class);
100 final List<Region> regions = new ArrayList<Region>();
101 Mockito.when(rss.getOnlineRegions(TABLENAME)).thenReturn(regions);
102 Mockito.when(mockRegion.getRegionServerServices()).thenReturn(rss);
103
104 long maxSplitSize = 1024L;
105 htd.setMaxFileSize(maxSplitSize);
106
107
108 long flushSize = maxSplitSize/8;
109 conf.setLong(HConstants.HREGION_MEMSTORE_FLUSH_SIZE, flushSize);
110 htd.setMemStoreFlushSize(flushSize);
111
112
113
114 IncreasingToUpperBoundRegionSplitPolicy policy =
115 (IncreasingToUpperBoundRegionSplitPolicy)RegionSplitPolicy.create(mockRegion, conf);
116 doConstantSizePolicyTests(policy);
117
118
119
120
121 HStore mockStore = Mockito.mock(HStore.class);
122 Mockito.doReturn(2000L).when(mockStore).getSize();
123 Mockito.doReturn(true).when(mockStore).canSplit();
124 stores.add(mockStore);
125
126 assertTrue(policy.shouldSplit());
127
128
129
130 regions.add(mockRegion);
131 Mockito.doReturn(flushSize).when(mockStore).getSize();
132
133 assertFalse(policy.shouldSplit());
134
135 Mockito.doReturn(flushSize*2 + 1).when(mockStore).getSize();
136 assertTrue(policy.shouldSplit());
137
138
139 regions.add(mockRegion);
140 assertFalse(policy.shouldSplit());
141
142 Mockito.doReturn((long)(maxSplitSize * 1.25 + 1)).when(mockStore).getSize();
143 assertTrue(policy.shouldSplit());
144
145
146 assertWithinJitter(maxSplitSize, policy.getSizeToCheck(1000));
147
148 assertWithinJitter(maxSplitSize, policy.getSizeToCheck(0));
149 }
150
151 @Test
152 public void testBusyRegionSplitPolicy() throws Exception {
153 conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
154 BusyRegionSplitPolicy.class.getName());
155 conf.setLong("hbase.busy.policy.minAge", 1000000L);
156 conf.setFloat("hbase.busy.policy.blockedRequests", 0.1f);
157
158 RegionServerServices rss = Mockito.mock(RegionServerServices.class);
159 final List<Region> regions = new ArrayList<Region>();
160 Mockito.when(rss.getOnlineRegions(TABLENAME)).thenReturn(regions);
161 Mockito.when(mockRegion.getRegionServerServices()).thenReturn(rss);
162 Mockito.when(mockRegion.getBlockedRequestsCount()).thenReturn(0L);
163 Mockito.when(mockRegion.getWriteRequestsCount()).thenReturn(0L);
164
165
166 BusyRegionSplitPolicy policy =
167 (BusyRegionSplitPolicy)RegionSplitPolicy.create(mockRegion, conf);
168
169 Mockito.when(mockRegion.getBlockedRequestsCount()).thenReturn(10L);
170 Mockito.when(mockRegion.getWriteRequestsCount()).thenReturn(10L);
171
172 assertFalse(policy.shouldSplit());
173
174
175
176 conf.setLong("hbase.busy.policy.minAge", 0L);
177
178 conf.setLong("hbase.busy.policy.aggWindow", 500L);
179 policy =
180 (BusyRegionSplitPolicy)RegionSplitPolicy.create(mockRegion, conf);
181 long start = EnvironmentEdgeManager.currentTime();
182 Mockito.when(mockRegion.getBlockedRequestsCount()).thenReturn(10L);
183 Mockito.when(mockRegion.getWriteRequestsCount()).thenReturn(20L);
184 Thread.sleep(300);
185 assertFalse(policy.shouldSplit());
186 Mockito.when(mockRegion.getBlockedRequestsCount()).thenReturn(12L);
187 Mockito.when(mockRegion.getWriteRequestsCount()).thenReturn(30L);
188 Thread.sleep(2);
189
190
191
192 if (EnvironmentEdgeManager.currentTime() - start < 500) {
193 assertFalse(policy.shouldSplit());
194 }
195 Mockito.when(mockRegion.getBlockedRequestsCount()).thenReturn(14L);
196 Mockito.when(mockRegion.getWriteRequestsCount()).thenReturn(40L);
197 Thread.sleep(200);
198 assertTrue(policy.shouldSplit());
199 }
200
201 private void assertWithinJitter(long maxSplitSize, long sizeToCheck) {
202 assertTrue("Size greater than lower bound of jitter",
203 (long)(maxSplitSize * 0.75) <= sizeToCheck);
204 assertTrue("Size less than upper bound of jitter",
205 (long)(maxSplitSize * 1.25) >= sizeToCheck);
206 }
207
208 @Test
209 public void testCreateDefault() throws IOException {
210 conf.setLong(HConstants.HREGION_MAX_FILESIZE, 1234L);
211
212
213
214 ConstantSizeRegionSplitPolicy policy =
215 (ConstantSizeRegionSplitPolicy)RegionSplitPolicy.create(
216 mockRegion, conf);
217 assertWithinJitter(1234L, policy.getDesiredMaxFileSize());
218
219
220 htd.setMaxFileSize(9999L);
221 policy = (ConstantSizeRegionSplitPolicy)RegionSplitPolicy.create(
222 mockRegion, conf);
223 assertWithinJitter(9999L, policy.getDesiredMaxFileSize());
224 }
225
226
227
228
229 @Test
230 public void testCustomPolicy() throws IOException {
231 HTableDescriptor myHtd = new HTableDescriptor();
232 myHtd.setValue(HTableDescriptor.SPLIT_POLICY,
233 KeyPrefixRegionSplitPolicy.class.getName());
234 myHtd.setValue(KeyPrefixRegionSplitPolicy.PREFIX_LENGTH_KEY, String.valueOf(2));
235
236 HRegion myMockRegion = Mockito.mock(HRegion.class);
237 Mockito.doReturn(myHtd).when(myMockRegion).getTableDesc();
238 Mockito.doReturn(stores).when(myMockRegion).getStores();
239
240 HStore mockStore = Mockito.mock(HStore.class);
241 Mockito.doReturn(2000L).when(mockStore).getSize();
242 Mockito.doReturn(true).when(mockStore).canSplit();
243 Mockito.doReturn(Bytes.toBytes("abcd")).when(mockStore).getSplitPoint();
244 stores.add(mockStore);
245
246 KeyPrefixRegionSplitPolicy policy = (KeyPrefixRegionSplitPolicy) RegionSplitPolicy
247 .create(myMockRegion, conf);
248
249 assertEquals("ab", Bytes.toString(policy.getSplitPoint()));
250
251 Mockito.doReturn(true).when(myMockRegion).shouldForceSplit();
252 Mockito.doReturn(Bytes.toBytes("efgh")).when(myMockRegion)
253 .getExplicitSplitPoint();
254
255 policy = (KeyPrefixRegionSplitPolicy) RegionSplitPolicy
256 .create(myMockRegion, conf);
257
258 assertEquals("ef", Bytes.toString(policy.getSplitPoint()));
259 }
260
261 @Test
262 public void testConstantSizePolicy() throws IOException {
263 htd.setMaxFileSize(1024L);
264 ConstantSizeRegionSplitPolicy policy =
265 (ConstantSizeRegionSplitPolicy)RegionSplitPolicy.create(mockRegion, conf);
266 doConstantSizePolicyTests(policy);
267 }
268
269
270
271
272
273 private void doConstantSizePolicyTests(final ConstantSizeRegionSplitPolicy policy) {
274
275 assertFalse(policy.shouldSplit());
276
277
278 HStore mockStore = Mockito.mock(HStore.class);
279 Mockito.doReturn(2000L).when(mockStore).getSize();
280 Mockito.doReturn(true).when(mockStore).canSplit();
281 stores.add(mockStore);
282
283 assertTrue(policy.shouldSplit());
284
285
286
287 Mockito.doReturn(false).when(mockStore).canSplit();
288 assertFalse(policy.shouldSplit());
289
290
291 Mockito.doReturn(true).when(mockStore).canSplit();
292
293
294 Mockito.doReturn(true).when(mockRegion).shouldForceSplit();
295 Mockito.doReturn(100L).when(mockStore).getSize();
296 assertTrue(policy.shouldSplit());
297
298
299 Mockito.doReturn(false).when(mockRegion).shouldForceSplit();
300 assertFalse(policy.shouldSplit());
301
302
303 stores.clear();
304 }
305
306 @Test
307 public void testGetSplitPoint() throws IOException {
308 ConstantSizeRegionSplitPolicy policy =
309 (ConstantSizeRegionSplitPolicy)RegionSplitPolicy.create(mockRegion, conf);
310
311
312 assertFalse(policy.shouldSplit());
313 assertNull(policy.getSplitPoint());
314
315
316 HStore mockStore = Mockito.mock(HStore.class);
317 Mockito.doReturn(2000L).when(mockStore).getSize();
318 Mockito.doReturn(true).when(mockStore).canSplit();
319 Mockito.doReturn(Bytes.toBytes("store 1 split"))
320 .when(mockStore).getSplitPoint();
321 stores.add(mockStore);
322
323 assertEquals("store 1 split",
324 Bytes.toString(policy.getSplitPoint()));
325
326
327 HStore mockStore2 = Mockito.mock(HStore.class);
328 Mockito.doReturn(4000L).when(mockStore2).getSize();
329 Mockito.doReturn(true).when(mockStore2).canSplit();
330 Mockito.doReturn(Bytes.toBytes("store 2 split"))
331 .when(mockStore2).getSplitPoint();
332 stores.add(mockStore2);
333
334 assertEquals("store 2 split",
335 Bytes.toString(policy.getSplitPoint()));
336 }
337
338 @Test
339 public void testDelimitedKeyPrefixRegionSplitPolicy() throws IOException {
340 HTableDescriptor myHtd = new HTableDescriptor();
341 myHtd.setValue(HTableDescriptor.SPLIT_POLICY,
342 DelimitedKeyPrefixRegionSplitPolicy.class.getName());
343 myHtd.setValue(DelimitedKeyPrefixRegionSplitPolicy.DELIMITER_KEY, ",");
344
345 HRegion myMockRegion = Mockito.mock(HRegion.class);
346 Mockito.doReturn(myHtd).when(myMockRegion).getTableDesc();
347 Mockito.doReturn(stores).when(myMockRegion).getStores();
348
349 HStore mockStore = Mockito.mock(HStore.class);
350 Mockito.doReturn(2000L).when(mockStore).getSize();
351 Mockito.doReturn(true).when(mockStore).canSplit();
352 Mockito.doReturn(Bytes.toBytes("ab,cd")).when(mockStore).getSplitPoint();
353 stores.add(mockStore);
354
355 DelimitedKeyPrefixRegionSplitPolicy policy = (DelimitedKeyPrefixRegionSplitPolicy) RegionSplitPolicy
356 .create(myMockRegion, conf);
357
358 assertEquals("ab", Bytes.toString(policy.getSplitPoint()));
359
360 Mockito.doReturn(true).when(myMockRegion).shouldForceSplit();
361 Mockito.doReturn(Bytes.toBytes("efg,h")).when(myMockRegion)
362 .getExplicitSplitPoint();
363
364 policy = (DelimitedKeyPrefixRegionSplitPolicy) RegionSplitPolicy
365 .create(myMockRegion, conf);
366
367 assertEquals("efg", Bytes.toString(policy.getSplitPoint()));
368
369 Mockito.doReturn(Bytes.toBytes("ijk")).when(myMockRegion)
370 .getExplicitSplitPoint();
371 assertEquals("ijk", Bytes.toString(policy.getSplitPoint()));
372 }
373
374 @Test
375 public void testConstantSizePolicyWithJitter() throws IOException {
376 conf.set(HConstants.HBASE_REGION_SPLIT_POLICY_KEY,
377 ConstantSizeRegionSplitPolicy.class.getName());
378 htd.setMaxFileSize(Long.MAX_VALUE);
379 boolean positiveJitter = false;
380 ConstantSizeRegionSplitPolicy policy = null;
381 while (!positiveJitter) {
382 policy = (ConstantSizeRegionSplitPolicy) RegionSplitPolicy.create(mockRegion, conf);
383 positiveJitter = policy.positiveJitterRate();
384 }
385
386 HStore mockStore = Mockito.mock(HStore.class);
387 Mockito.doReturn(2000L).when(mockStore).getSize();
388 Mockito.doReturn(true).when(mockStore).canSplit();
389 stores.add(mockStore);
390
391 assertFalse(policy.shouldSplit());
392 }
393
394 }