1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase;
19
20
21 import java.io.IOException;
22 import java.util.List;
23
24 import junit.framework.Assert;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.fs.FileSystem;
29 import org.apache.hadoop.hbase.client.HBaseAdmin;
30 import org.apache.hadoop.hbase.master.HMaster;
31 import org.apache.hadoop.hbase.regionserver.HRegionServer;
32 import org.apache.hadoop.hbase.util.Bytes;
33 import org.apache.hadoop.hbase.util.FSUtils;
34 import org.apache.hadoop.hbase.util.FSTableDescriptors;
35 import org.apache.hadoop.hbase.util.Threads;
36 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
37 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
38 import org.apache.zookeeper.KeeperException;
39 import org.junit.AfterClass;
40 import org.junit.BeforeClass;
41 import org.junit.Test;
42
43
44
45
46
47 public class TestDrainingServer {
48 private static final Log LOG = LogFactory.getLog(TestDrainingServer.class);
49 private static final HBaseTestingUtility TEST_UTIL =
50 new HBaseTestingUtility();
51 private static final byte [] TABLENAME = Bytes.toBytes("t");
52 private static final byte [] FAMILY = Bytes.toBytes("f");
53 private static final int COUNT_OF_REGIONS = HBaseTestingUtility.KEYS.length;
54
55
56
57
58 @BeforeClass
59 public static void setUpBeforeClass() throws Exception {
60 TEST_UTIL.startMiniCluster(5);
61 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
62 htd.addFamily(new HColumnDescriptor(FAMILY));
63 TEST_UTIL.createMultiRegionsInMeta(TEST_UTIL.getConfiguration(), htd,
64 HBaseTestingUtility.KEYS);
65
66 FileSystem fs = FileSystem.get(TEST_UTIL.getConfiguration());
67 FSTableDescriptors.
68 createTableDescriptor(fs, FSUtils.getRootDir(TEST_UTIL.getConfiguration()), htd);
69
70 HBaseAdmin admin = new HBaseAdmin(TEST_UTIL.getConfiguration());
71 admin.disableTable(TABLENAME);
72 admin.enableTable(TABLENAME);
73
74 MiniHBaseCluster cluster = TEST_UTIL.getMiniHBaseCluster();
75 for (int i = 0; i < cluster.getRegionServerThreads().size(); i++) {
76 HRegionServer hrs = cluster.getRegionServer(i);
77 Assert.assertFalse(hrs.getOnlineRegions().isEmpty());
78 }
79 }
80
81 private static HRegionServer setDrainingServer(final HRegionServer hrs)
82 throws KeeperException {
83 LOG.info("Making " + hrs.getServerName() + " the draining server; " +
84 "it has " + hrs.getNumberOfOnlineRegions() + " online regions");
85 ZooKeeperWatcher zkw = hrs.getZooKeeper();
86 String hrsDrainingZnode =
87 ZKUtil.joinZNode(zkw.drainingZNode, hrs.getServerName().toString());
88 ZKUtil.createWithParents(zkw, hrsDrainingZnode);
89 return hrs;
90 }
91
92 private static HRegionServer unsetDrainingServer(final HRegionServer hrs)
93 throws KeeperException {
94 ZooKeeperWatcher zkw = hrs.getZooKeeper();
95 String hrsDrainingZnode =
96 ZKUtil.joinZNode(zkw.drainingZNode, hrs.getServerName().toString());
97 ZKUtil.deleteNode(zkw, hrsDrainingZnode);
98 return hrs;
99 }
100
101 @AfterClass
102 public static void tearDownAfterClass() throws Exception {
103 TEST_UTIL.shutdownMiniCluster();
104 }
105
106
107
108
109
110
111
112 @Test
113 public void testDrainingServerOffloading()
114 throws IOException, KeeperException {
115
116 HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
117 HRegionInfo hriToMoveBack = null;
118
119 HRegionServer drainingServer =
120 setDrainingServer(TEST_UTIL.getMiniHBaseCluster().getRegionServer(0));
121 try {
122 final int regionsOnDrainingServer =
123 drainingServer.getNumberOfOnlineRegions();
124 Assert.assertTrue(regionsOnDrainingServer > 0);
125 List<HRegionInfo> hris = drainingServer.getOnlineRegions();
126 for (HRegionInfo hri : hris) {
127
128
129 master.move(hri.getEncodedNameAsBytes(), null);
130
131 hriToMoveBack = hri;
132 }
133
134 waitForAllRegionsOnline();
135 Assert.assertEquals(0, drainingServer.getNumberOfOnlineRegions());
136 } finally {
137 unsetDrainingServer(drainingServer);
138 }
139
140
141 master.move(hriToMoveBack.getEncodedNameAsBytes(),
142 Bytes.toBytes(drainingServer.getServerName().toString()));
143
144 waitForAllRegionsOnline();
145 Assert.assertEquals(1, drainingServer.getNumberOfOnlineRegions());
146 }
147
148
149
150
151
152
153
154 @Test (timeout=30000)
155 public void testDrainingServerWithAbort() throws KeeperException, IOException {
156
157 HRegionServer drainingServer =
158 setDrainingServer(TEST_UTIL.getMiniHBaseCluster().getRegionServer(0));
159 try {
160 final int regionsOnDrainingServer =
161 drainingServer.getNumberOfOnlineRegions();
162 Assert.assertTrue(regionsOnDrainingServer > 0);
163
164 int aborted = 0;
165 final int numberToAbort = 2;
166 for (int i = 1; i < TEST_UTIL.getMiniHBaseCluster().countServedRegions(); i++) {
167 HRegionServer hrs = TEST_UTIL.getMiniHBaseCluster().getRegionServer(i);
168 if (hrs.getServerName().equals(drainingServer.getServerName())) continue;
169 hrs.abort("Aborting");
170 aborted++;
171 if (aborted >= numberToAbort) break;
172 }
173
174 waitForAllRegionsOnline();
175
176 Assert.assertEquals(regionsOnDrainingServer,
177 drainingServer.getNumberOfOnlineRegions());
178 } finally {
179 unsetDrainingServer(drainingServer);
180 }
181 }
182
183 private void waitForAllRegionsOnline() {
184 while (TEST_UTIL.getMiniHBaseCluster().getMaster().
185 getAssignmentManager().isRegionsInTransition()) {
186 Threads.sleep(10);
187 }
188
189 while (!isAllRegionsOnline()) {
190 Threads.sleep(10);
191 }
192 }
193
194 private boolean isAllRegionsOnline() {
195 return TEST_UTIL.getMiniHBaseCluster().countServedRegions() ==
196 (COUNT_OF_REGIONS + 2
197 }
198 }