ソースを参照

HDFS-9364. Unnecessary DNS resolution attempts when creating NameNodeProxies. Contributed by Xiao Chen.

Change-Id: I9e42f724f27924cf73891425a832de37ce014a1e
Zhe Zhang 9 年 前
コミット
edd4b2d458

+ 21 - 1
hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/DFSUtilClient.java

@@ -614,7 +614,7 @@ public class DFSUtilClient {
 
   public static InetSocketAddress getNNAddress(Configuration conf) {
     URI filesystemURI = FileSystem.getDefaultUri(conf);
-    return getNNAddress(filesystemURI);
+    return getNNAddressCheckLogical(conf, filesystemURI);
   }
 
   /**
@@ -637,6 +637,26 @@ public class DFSUtilClient {
     return getNNAddress(authority);
   }
 
+  /**
+   * Get the NN address from the URI. If the uri is logical, default address is
+   * returned. Otherwise return the DNS-resolved address of the URI.
+   *
+   * @param conf configuration
+   * @param filesystemURI URI of the file system
+   * @return address of file system
+   */
+  public static InetSocketAddress getNNAddressCheckLogical(Configuration conf,
+      URI filesystemURI) {
+    InetSocketAddress retAddr;
+    if (HAUtilClient.isLogicalUri(conf, filesystemURI)) {
+      retAddr = InetSocketAddress.createUnresolved(filesystemURI.getAuthority(),
+          HdfsClientConfigKeys.DFS_NAMENODE_RPC_PORT_DEFAULT);
+    } else {
+      retAddr = getNNAddress(filesystemURI);
+    }
+    return retAddr;
+  }
+
   public static URI getNNUri(InetSocketAddress namenode) {
     int port = namenode.getPort();
     String portString =

+ 1 - 1
hadoop-hdfs-project/hadoop-hdfs-client/src/main/java/org/apache/hadoop/hdfs/NameNodeProxiesClient.java

@@ -320,7 +320,7 @@ public class NameNodeProxiesClient {
           DFSUtilClient.getNNAddress(nameNodeUri));
     }
     return new ProxyAndInfo<>(proxy, dtService,
-        DFSUtilClient.getNNAddress(nameNodeUri));
+        DFSUtilClient.getNNAddressCheckLogical(conf, nameNodeUri));
   }
 
   public static ClientProtocol createNonHAProxyWithClientProtocol(

+ 3 - 0
hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt

@@ -1433,6 +1433,9 @@ Release 2.8.0 - UNRELEASED
     HDFS-9401. Fix findbugs warnings in BlockRecoveryWorker.
     (Brahma Reddy Battula via waltersu4549)
 
+    HDFS-9364. Unnecessary DNS resolution attempts when creating NameNodeProxies.
+    (Xiao Chen via zhz)
+
 Release 2.7.3 - UNRELEASED
 
   INCOMPATIBLE CHANGES

+ 35 - 0
hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/TestDFSClientFailover.java

@@ -46,6 +46,7 @@ import org.apache.hadoop.hdfs.server.namenode.NameNode;
 import org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider;
 import org.apache.hadoop.hdfs.server.namenode.ha.HATestUtil;
 import org.apache.hadoop.hdfs.server.namenode.ha.IPFailoverProxyProvider;
+import org.apache.hadoop.hdfs.server.protocol.NamenodeProtocol;
 import org.apache.hadoop.io.IOUtils;
 import org.apache.hadoop.io.retry.FailoverProxyProvider;
 import org.apache.hadoop.net.ConnectTimeoutException;
@@ -291,6 +292,40 @@ public class TestDFSClientFailover {
     Mockito.verify(spyNS, Mockito.never()).lookupAllHostAddr(Mockito.eq(logicalHost));
   }
 
+  /**
+   * Test that creating proxy doesn't ever try to DNS-resolve the logical URI.
+   * Regression test for HDFS-9364.
+   */
+  @Test(timeout=60000)
+  public void testCreateProxyDoesntDnsResolveLogicalURI() throws IOException {
+    final NameService spyNS = spyOnNameService();
+    final Configuration conf = new HdfsConfiguration();
+    final String service = "nameservice1";
+    final String namenode = "namenode113";
+    conf.set(DFSConfigKeys.DFS_NAMESERVICES, service);
+    conf.set(FileSystem.FS_DEFAULT_NAME_KEY, "hdfs://" + service);
+    conf.set(
+        HdfsClientConfigKeys.Failover.PROXY_PROVIDER_KEY_PREFIX + "." + service,
+        "org.apache.hadoop.hdfs.server.namenode.ha."
+        + "ConfiguredFailoverProxyProvider");
+    conf.set(DFSConfigKeys.DFS_HA_NAMENODES_KEY_PREFIX + "." + service,
+        namenode);
+    conf.set(DFSConfigKeys.DFS_NAMENODE_RPC_ADDRESS_KEY + "." + service + "."
+        + namenode, "localhost:8020");
+
+    // call createProxy implicitly and explicitly
+    Path p = new Path("/");
+    p.getFileSystem(conf);
+    NameNodeProxiesClient.createProxyWithClientProtocol(conf,
+        FileSystem.getDefaultUri(conf), null);
+    NameNodeProxies.createProxy(conf, FileSystem.getDefaultUri(conf),
+        NamenodeProtocol.class, null);
+
+    // Ensure that the logical hostname was never resolved.
+    Mockito.verify(spyNS, Mockito.never()).lookupAllHostAddr(
+        Mockito.eq(service));
+  }
+
   /** Dummy implementation of plain FailoverProxyProvider */
   public static class DummyLegacyFailoverProxyProvider<T>
       implements FailoverProxyProvider<T> {