HDFS-9001. DFSUtil.getNsServiceRpcUris() can return too many entries in a non-HA, non-federated cluster. Contributed by Daniel Templeton.

This commit is contained in:
Aaron T. Myers 2015-09-29 18:19:31 -07:00
parent 39285e6a19
commit 071733dc69
3 changed files with 130 additions and 54 deletions

View File

@ -1468,6 +1468,9 @@ Release 2.8.0 - UNRELEASED
HDFS-9174. Fix findbugs warnings in FSOutputSummer.tracer and HDFS-9174. Fix findbugs warnings in FSOutputSummer.tracer and
DirectoryScanner$ReportCompiler.currentThread. (Yi Liu via wheat9) DirectoryScanner$ReportCompiler.currentThread. (Yi Liu via wheat9)
HDFS-9001. DFSUtil.getNsServiceRpcUris() can return too many entries in a
non-HA, non-federated cluster. (Daniel Templeton via atm)
Release 2.7.2 - UNRELEASED Release 2.7.2 - UNRELEASED
INCOMPATIBLE CHANGES INCOMPATIBLE CHANGES

View File

@ -733,8 +733,15 @@ public class DFSUtil {
} }
} }
// Add the default URI if it is an HDFS URI. // Add the default URI if it is an HDFS URI and we haven't come up with a
// valid non-nameservice NN address yet. Consider the servicerpc-address
// and rpc-address to be the "unnamed" nameservice. defaultFS is our
// fallback when rpc-address isn't given. We therefore only want to add
// the defaultFS when neither the servicerpc-address (which is preferred)
// nor the rpc-address (which overrides defaultFS) is given.
if (!uriFound) {
URI defaultUri = FileSystem.getDefaultUri(conf); URI defaultUri = FileSystem.getDefaultUri(conf);
// checks if defaultUri is ip:port format // checks if defaultUri is ip:port format
// and convert it to hostname:port format // and convert it to hostname:port format
if (defaultUri != null && (defaultUri.getPort() != -1)) { if (defaultUri != null && (defaultUri.getPort() != -1)) {
@ -742,11 +749,13 @@ public class DFSUtil {
NetUtils.createSocketAddr(defaultUri.getHost(), NetUtils.createSocketAddr(defaultUri.getHost(),
defaultUri.getPort())); defaultUri.getPort()));
} }
if (defaultUri != null && if (defaultUri != null &&
HdfsConstants.HDFS_URI_SCHEME.equals(defaultUri.getScheme()) && HdfsConstants.HDFS_URI_SCHEME.equals(defaultUri.getScheme()) &&
!nonPreferredUris.contains(defaultUri)) { !nonPreferredUris.contains(defaultUri)) {
ret.add(defaultUri); ret.add(defaultUri);
} }
}
return ret; return ret;
} }

View File

@ -616,6 +616,11 @@ public class TestDFSUtil {
DFSUtil.substituteForWildcardAddress("127.0.0.1:12345", "foo")); DFSUtil.substituteForWildcardAddress("127.0.0.1:12345", "foo"));
} }
/**
* Test how name service URIs are handled with a variety of configuration
* settings
* @throws Exception
*/
@Test @Test
public void testGetNNUris() throws Exception { public void testGetNNUris() throws Exception {
HdfsConfiguration conf = new HdfsConfiguration(); HdfsConfiguration conf = new HdfsConfiguration();
@ -627,67 +632,126 @@ public class TestDFSUtil {
final String NN1_SRVC_ADDR = "nn.example.com:8021"; final String NN1_SRVC_ADDR = "nn.example.com:8021";
final String NN2_ADDR = "nn2.example.com:8020"; final String NN2_ADDR = "nn2.example.com:8020";
conf.set(DFS_NAMESERVICES, "ns1");
conf.set(DFSUtil.addKeySuffixes(
DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, "ns1"), NS1_NN1_ADDR);
conf.set(DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, "hdfs://" + NN2_ADDR);
conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://" + NN1_ADDR);
Collection<URI> uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals("Incorrect number of URIs returned", 2, uris.size());
assertTrue("Missing URI for name service ns1",
uris.contains(new URI("hdfs://" + NS1_NN1_ADDR)));
assertTrue("Missing URI for service address",
uris.contains(new URI("hdfs://" + NN2_ADDR)));
conf = new HdfsConfiguration();
conf.set(DFS_NAMESERVICES, "ns1,ns2"); conf.set(DFS_NAMESERVICES, "ns1,ns2");
conf.set(DFSUtil.addKeySuffixes(DFS_HA_NAMENODES_KEY_PREFIX, "ns1"),"nn1,nn2"); conf.set(DFSUtil.addKeySuffixes(DFS_HA_NAMENODES_KEY_PREFIX, "ns1"),
"nn1,nn2");
conf.set(DFSUtil.addKeySuffixes( conf.set(DFSUtil.addKeySuffixes(
DFS_NAMENODE_RPC_ADDRESS_KEY, "ns1", "nn1"), NS1_NN1_ADDR); DFS_NAMENODE_RPC_ADDRESS_KEY, "ns1", "nn1"), NS1_NN1_ADDR);
conf.set(DFSUtil.addKeySuffixes( conf.set(DFSUtil.addKeySuffixes(
DFS_NAMENODE_RPC_ADDRESS_KEY, "ns1", "nn2"), NS1_NN2_ADDR); DFS_NAMENODE_RPC_ADDRESS_KEY, "ns1", "nn2"), NS1_NN2_ADDR);
conf.set(DFSUtil.addKeySuffixes(DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, "ns2"), conf.set(DFSUtil.addKeySuffixes(
NS2_NN_ADDR); DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, "ns2"), NS2_NN_ADDR);
conf.set(DFS_NAMENODE_RPC_ADDRESS_KEY, "hdfs://" + NN1_ADDR); conf.set(DFS_NAMENODE_RPC_ADDRESS_KEY, "hdfs://" + NN1_ADDR);
conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://" + NN2_ADDR); conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://" + NN2_ADDR);
Collection<URI> uris = DFSUtil.getNameServiceUris(conf, uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY); DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals(4, uris.size()); assertEquals("Incorrect number of URIs returned", 3, uris.size());
assertTrue(uris.contains(new URI("hdfs://ns1"))); assertTrue("Missing URI for name service ns1",
assertTrue(uris.contains(new URI("hdfs://" + NS2_NN_ADDR))); uris.contains(new URI("hdfs://ns1")));
assertTrue(uris.contains(new URI("hdfs://" + NN1_ADDR))); assertTrue("Missing URI for name service ns2",
assertTrue(uris.contains(new URI("hdfs://" + NN2_ADDR))); uris.contains(new URI("hdfs://" + NS2_NN_ADDR)));
assertTrue("Missing URI for RPC address",
uris.contains(new URI("hdfs://" + NN1_ADDR)));
// Make sure that non-HDFS URIs in fs.defaultFS don't get included. // Make sure that non-HDFS URIs in fs.defaultFS don't get included.
conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY,
"viewfs://vfs-name.example.com"); "viewfs://vfs-name.example.com");
uris = DFSUtil.getNameServiceUris(conf, DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_RPC_ADDRESS_KEY); DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals(3, uris.size()); assertEquals("Incorrect number of URIs returned", 3, uris.size());
assertTrue(uris.contains(new URI("hdfs://ns1"))); assertTrue("Missing URI for name service ns1",
assertTrue(uris.contains(new URI("hdfs://" + NS2_NN_ADDR))); uris.contains(new URI("hdfs://ns1")));
assertTrue(uris.contains(new URI("hdfs://" + NN1_ADDR))); assertTrue("Missing URI for name service ns2",
uris.contains(new URI("hdfs://" + NS2_NN_ADDR)));
assertTrue("Missing URI for RPC address",
uris.contains(new URI("hdfs://" + NN1_ADDR)));
// Make sure that an HA URI being the default URI doesn't result in multiple // Make sure that an HA URI being the default URI doesn't result in multiple
// entries being returned. // entries being returned.
conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://ns1"); conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://ns1");
uris = DFSUtil.getNameServiceUris(conf, DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_RPC_ADDRESS_KEY); DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals(3, uris.size()); assertEquals("Incorrect number of URIs returned", 3, uris.size());
assertTrue(uris.contains(new URI("hdfs://ns1"))); assertTrue("Missing URI for name service ns1",
assertTrue(uris.contains(new URI("hdfs://" + NS2_NN_ADDR))); uris.contains(new URI("hdfs://ns1")));
assertTrue(uris.contains(new URI("hdfs://" + NN1_ADDR))); assertTrue("Missing URI for name service ns2",
uris.contains(new URI("hdfs://" + NS2_NN_ADDR)));
assertTrue("Missing URI for RPC address",
uris.contains(new URI("hdfs://" + NN1_ADDR)));
// Check that the default URI is returned if there's nothing else to return.
conf = new HdfsConfiguration();
conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://" + NN1_ADDR);
uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals("Incorrect number of URIs returned", 1, uris.size());
assertTrue("Missing URI for RPC address (defaultFS)",
uris.contains(new URI("hdfs://" + NN1_ADDR)));
// Check that the RPC address is the only address returned when the RPC
// and the default FS is given.
conf.set(DFS_NAMENODE_RPC_ADDRESS_KEY, NN2_ADDR);
uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals("Incorrect number of URIs returned", 1, uris.size());
assertTrue("Missing URI for RPC address",
uris.contains(new URI("hdfs://" + NN2_ADDR)));
// Make sure that when a service RPC address is used that is distinct from // Make sure that when a service RPC address is used that is distinct from
// the client RPC address, and that client RPC address is also used as the // the client RPC address, and that client RPC address is also used as the
// default URI, that the client URI does not end up in the set of URIs // default URI, that the client URI does not end up in the set of URIs
// returned. // returned.
conf.set(DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, NN1_ADDR);
uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals("Incorrect number of URIs returned", 1, uris.size());
assertTrue("Missing URI for service ns1",
uris.contains(new URI("hdfs://" + NN1_ADDR)));
// Check that when the default FS and service address are given, but
// the RPC address isn't, that only the service address is returned.
conf = new HdfsConfiguration(); conf = new HdfsConfiguration();
conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://" + NN1_ADDR); conf.set(CommonConfigurationKeys.FS_DEFAULT_NAME_KEY, "hdfs://" + NN1_ADDR);
conf.set(DFS_NAMENODE_RPC_ADDRESS_KEY, NN1_ADDR);
conf.set(DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, NN1_SRVC_ADDR); conf.set(DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, NN1_SRVC_ADDR);
uris = DFSUtil.getNameServiceUris(conf, DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, uris = DFSUtil.getNameServiceUris(conf,
DFS_NAMENODE_RPC_ADDRESS_KEY); DFS_NAMENODE_SERVICE_RPC_ADDRESS_KEY, DFS_NAMENODE_RPC_ADDRESS_KEY);
assertEquals(1, uris.size()); assertEquals("Incorrect number of URIs returned", 1, uris.size());
assertTrue(uris.contains(new URI("hdfs://" + NN1_SRVC_ADDR))); assertTrue("Missing URI for service address",
uris.contains(new URI("hdfs://" + NN1_SRVC_ADDR)));
} }
@Test (timeout=15000) @Test (timeout=15000)