1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.regionserver;
21
22 import static org.junit.Assert.fail;
23
24 import java.lang.reflect.Method;
25 import java.net.InetSocketAddress;
26 import java.net.URI;
27 import java.util.ArrayList;
28 import java.util.List;
29
30 import org.apache.hadoop.fs.BlockLocation;
31 import org.apache.hadoop.fs.FileStatus;
32 import org.apache.hadoop.fs.Path;
33 import org.apache.hadoop.fs.permission.FsPermission;
34 import org.apache.hadoop.hbase.TableName;
35 import org.apache.hadoop.hbase.HBaseTestingUtility;
36 import org.apache.hadoop.hbase.testclassification.MediumTests;
37 import org.apache.hadoop.hbase.client.HTable;
38 import org.apache.hadoop.hbase.util.Bytes;
39 import org.apache.hadoop.hdfs.DistributedFileSystem;
40 import org.apache.hadoop.hdfs.server.datanode.DataNode;
41 import org.apache.hadoop.util.Progressable;
42 import org.junit.AfterClass;
43 import org.junit.Assume;
44 import org.junit.BeforeClass;
45 import org.junit.Test;
46 import org.junit.experimental.categories.Category;
47
48
49
50
51 @Category(MediumTests.class)
52 public class TestRegionFavoredNodes {
53
54 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
55 private static HTable table;
56 private static final TableName TABLE_NAME =
57 TableName.valueOf("table");
58 private static final byte[] COLUMN_FAMILY = Bytes.toBytes("family");
59 private static final int FAVORED_NODES_NUM = 3;
60 private static final int REGION_SERVERS = 6;
61 private static final int FLUSHES = 3;
62 private static Method createWithFavoredNode = null;
63
64 @BeforeClass
65 public static void setUpBeforeClass() throws Exception {
66 try {
67 createWithFavoredNode = DistributedFileSystem.class.getDeclaredMethod("create", Path.class,
68 FsPermission.class, boolean.class, int.class, short.class, long.class,
69 Progressable.class, InetSocketAddress[].class);
70 } catch (NoSuchMethodException nm) {
71 return;
72 }
73 TEST_UTIL.startMiniCluster(REGION_SERVERS);
74 table = TEST_UTIL.createTable(TABLE_NAME, COLUMN_FAMILY);
75 TEST_UTIL.createMultiRegions(table, COLUMN_FAMILY);
76 TEST_UTIL.waitUntilAllRegionsAssigned(TABLE_NAME);
77 }
78
79 @AfterClass
80 public static void tearDownAfterClass() throws Exception {
81
82 if (table != null) {
83 table.close();
84 }
85 if (createWithFavoredNode == null) {
86 return;
87 }
88 TEST_UTIL.shutdownMiniCluster();
89 }
90
91 @Test
92 public void testFavoredNodes() throws Exception {
93 Assume.assumeTrue(createWithFavoredNode != null);
94
95 InetSocketAddress[] nodes = new InetSocketAddress[REGION_SERVERS];
96 List<DataNode> datanodes = TEST_UTIL.getDFSCluster().getDataNodes();
97 Method selfAddress;
98 try {
99 selfAddress = DataNode.class.getMethod("getSelfAddr");
100 } catch (NoSuchMethodException ne) {
101 selfAddress = DataNode.class.getMethod("getXferAddress");
102 }
103 for (int i = 0; i < REGION_SERVERS; i++) {
104 nodes[i] = (InetSocketAddress)selfAddress.invoke(datanodes.get(i));
105 }
106
107 String[] nodeNames = new String[REGION_SERVERS];
108 for (int i = 0; i < REGION_SERVERS; i++) {
109 nodeNames[i] = nodes[i].getAddress().getHostAddress() + ":" +
110 nodes[i].getPort();
111 }
112
113
114
115 for (int i = 0; i < REGION_SERVERS; i++) {
116 HRegionServer server = TEST_UTIL.getHBaseCluster().getRegionServer(i);
117 List<HRegion> regions = server.getOnlineRegions(TABLE_NAME);
118 for (HRegion region : regions) {
119 List<org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName>favoredNodes =
120 new ArrayList<org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName>(3);
121 String encodedRegionName = region.getRegionInfo().getEncodedName();
122 for (int j = 0; j < FAVORED_NODES_NUM; j++) {
123 org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName.Builder b =
124 org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName.newBuilder();
125 b.setHostName(nodes[(i + j) % REGION_SERVERS].getAddress().getHostAddress());
126 b.setPort(nodes[(i + j) % REGION_SERVERS].getPort());
127 b.setStartCode(-1);
128 favoredNodes.add(b.build());
129 }
130 server.updateRegionFavoredNodesMapping(encodedRegionName, favoredNodes);
131 }
132 }
133
134
135
136 for (int i = 0; i < FLUSHES; i++) {
137 TEST_UTIL.loadTable(table, COLUMN_FAMILY, false);
138 TEST_UTIL.flush();
139 }
140
141
142
143 for (int i = 0; i < REGION_SERVERS; i++) {
144 HRegionServer server = TEST_UTIL.getHBaseCluster().getRegionServer(i);
145 List<HRegion> regions = server.getOnlineRegions(TABLE_NAME);
146 for (HRegion region : regions) {
147 List<String> files = region.getStoreFileList(new byte[][]{COLUMN_FAMILY});
148 for (String file : files) {
149 FileStatus status = TEST_UTIL.getDFSCluster().getFileSystem().
150 getFileStatus(new Path(new URI(file).getPath()));
151 BlockLocation[] lbks =
152 ((DistributedFileSystem)TEST_UTIL.getDFSCluster().getFileSystem())
153 .getFileBlockLocations(status, 0, Long.MAX_VALUE);
154 for (BlockLocation lbk : lbks) {
155 locations:
156 for (String info : lbk.getNames()) {
157 for (int j = 0; j < FAVORED_NODES_NUM; j++) {
158 if (info.equals(nodeNames[(i + j) % REGION_SERVERS])) {
159 continue locations;
160 }
161 }
162
163 fail("Block location " + info + " not a favored node");
164 }
165 }
166 }
167 }
168 }
169 }
170 }