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.HBaseTestingUtility;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.client.HTable;
37 import org.apache.hadoop.hbase.testclassification.MediumTests;
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.createMultiRegionTable(TABLE_NAME, COLUMN_FAMILY);
75 TEST_UTIL.waitUntilAllRegionsAssigned(TABLE_NAME);
76 }
77
78 @AfterClass
79 public static void tearDownAfterClass() throws Exception {
80
81 if (table != null) {
82 table.close();
83 }
84 if (createWithFavoredNode == null) {
85 return;
86 }
87 TEST_UTIL.shutdownMiniCluster();
88 }
89
90 @Test
91 public void testFavoredNodes() throws Exception {
92 Assume.assumeTrue(createWithFavoredNode != null);
93
94 InetSocketAddress[] nodes = new InetSocketAddress[REGION_SERVERS];
95 List<DataNode> datanodes = TEST_UTIL.getDFSCluster().getDataNodes();
96 Method selfAddress;
97 try {
98 selfAddress = DataNode.class.getMethod("getSelfAddr");
99 } catch (NoSuchMethodException ne) {
100 selfAddress = DataNode.class.getMethod("getXferAddress");
101 }
102 for (int i = 0; i < REGION_SERVERS; i++) {
103 nodes[i] = (InetSocketAddress)selfAddress.invoke(datanodes.get(i));
104 }
105
106 String[] nodeNames = new String[REGION_SERVERS];
107 for (int i = 0; i < REGION_SERVERS; i++) {
108 nodeNames[i] = nodes[i].getAddress().getHostAddress() + ":" +
109 nodes[i].getPort();
110 }
111
112
113
114 for (int i = 0; i < REGION_SERVERS; i++) {
115 HRegionServer server = TEST_UTIL.getHBaseCluster().getRegionServer(i);
116 List<Region> regions = server.getOnlineRegions(TABLE_NAME);
117 for (Region region : regions) {
118 List<org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName>favoredNodes =
119 new ArrayList<org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName>(3);
120 String encodedRegionName = region.getRegionInfo().getEncodedName();
121 for (int j = 0; j < FAVORED_NODES_NUM; j++) {
122 org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName.Builder b =
123 org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.ServerName.newBuilder();
124 b.setHostName(nodes[(i + j) % REGION_SERVERS].getAddress().getHostAddress());
125 b.setPort(nodes[(i + j) % REGION_SERVERS].getPort());
126 b.setStartCode(-1);
127 favoredNodes.add(b.build());
128 }
129 server.updateRegionFavoredNodesMapping(encodedRegionName, favoredNodes);
130 }
131 }
132
133
134
135 for (int i = 0; i < FLUSHES; i++) {
136 TEST_UTIL.loadTable(table, COLUMN_FAMILY, false);
137 TEST_UTIL.flush();
138 }
139
140
141
142 for (int i = 0; i < REGION_SERVERS; i++) {
143 HRegionServer server = TEST_UTIL.getHBaseCluster().getRegionServer(i);
144 List<Region> regions = server.getOnlineRegions(TABLE_NAME);
145 for (Region region : regions) {
146 List<String> files = region.getStoreFileList(new byte[][]{COLUMN_FAMILY});
147 for (String file : files) {
148 FileStatus status = TEST_UTIL.getDFSCluster().getFileSystem().
149 getFileStatus(new Path(new URI(file).getPath()));
150 BlockLocation[] lbks =
151 ((DistributedFileSystem)TEST_UTIL.getDFSCluster().getFileSystem())
152 .getFileBlockLocations(status, 0, Long.MAX_VALUE);
153 for (BlockLocation lbk : lbks) {
154 locations:
155 for (String info : lbk.getNames()) {
156 for (int j = 0; j < FAVORED_NODES_NUM; j++) {
157 if (info.equals(nodeNames[(i + j) % REGION_SERVERS])) {
158 continue locations;
159 }
160 }
161
162 fail("Block location " + info + " not a favored node");
163 }
164 }
165 }
166 }
167 }
168 }
169 }