Ver código fonte

HDFS-1041. DFSClient.getFileChecksum(..) should retry if connection to the first datanode fails.

git-svn-id: https://svn.apache.org/repos/asf/hadoop/hdfs/trunk@932036 13f79535-47bb-0310-9956-ffa450edef68
Tsz-wo Sze 15 anos atrás
pai
commit
67c2e4e950

+ 3 - 0
CHANGES.txt

@@ -811,6 +811,9 @@ Release 0.20.3 - Unreleased
     HDFS-955. New implementation of saveNamespace() to avoid loss of edits 
     when name-node fails during saving. (shv)
 
+    HDFS-1041. DFSClient.getFileChecksum(..) should retry if connection to
+    the first datanode fails.  (szetszwo)
+
 Release 0.20.2 - Unreleased
 
   IMPROVEMENTS

+ 16 - 13
src/java/org/apache/hadoop/hdfs/DFSClient.java

@@ -914,24 +914,27 @@ public class DFSClient implements FSConstants, java.io.Closeable {
       final int timeout = 3000 * datanodes.length + socketTimeout;
       boolean done = false;
       for(int j = 0; !done && j < datanodes.length; j++) {
-        //connect to a datanode
-        final Socket sock = socketFactory.createSocket();
-        NetUtils.connect(sock, 
-                         NetUtils.createSocketAddr(datanodes[j].getName()),
-                         timeout);
-        sock.setSoTimeout(timeout);
-
-        DataOutputStream out = new DataOutputStream(
-            new BufferedOutputStream(NetUtils.getOutputStream(sock), 
-                                     DataNode.SMALL_BUFFER_SIZE));
-        DataInputStream in = new DataInputStream(NetUtils.getInputStream(sock));
-
-        // get block MD5
+        Socket sock = null;
+        DataOutputStream out = null;
+        DataInputStream in = null;
+        
         try {
+          //connect to a datanode
+          sock = socketFactory.createSocket();
+          NetUtils.connect(sock,
+              NetUtils.createSocketAddr(datanodes[j].getName()), timeout);
+          sock.setSoTimeout(timeout);
+
+          out = new DataOutputStream(
+              new BufferedOutputStream(NetUtils.getOutputStream(sock), 
+                                       DataNode.SMALL_BUFFER_SIZE));
+          in = new DataInputStream(NetUtils.getInputStream(sock));
+
           if (LOG.isDebugEnabled()) {
             LOG.debug("write to " + datanodes[j].getName() + ": "
                 + BLOCK_CHECKSUM + ", block=" + block);
           }
+          // get block MD5
           DataTransferProtocol.Sender.opBlockChecksum(out, block.getBlockId(),
               block.getGenerationStamp(), lb.getAccessToken());
 

+ 31 - 0
src/test/hdfs/org/apache/hadoop/hdfs/TestDFSClientRetries.java

@@ -660,4 +660,35 @@ public class TestDFSClientRetries extends TestCase {
     public synchronized void inc() { ++counter; }
     public int get() { return counter; }
   }
+
+  public void testGetFileChecksum() throws Exception {
+    final String f = "/testGetFileChecksum";
+    final Path p = new Path(f);
+
+    final Configuration conf = new Configuration();
+    final MiniDFSCluster cluster = new MiniDFSCluster(conf, 3, true, null);
+    try {
+      cluster.waitActive();
+
+      //create a file
+      final FileSystem fs = cluster.getFileSystem();
+      DFSTestUtil.createFile(fs, p, 1L << 20, (short)3, 20100402L);
+
+      //get checksum
+      final FileChecksum cs1 = fs.getFileChecksum(p);
+      assertTrue(cs1 != null);
+
+      //stop the first datanode
+      final List<LocatedBlock> locatedblocks = DFSClient.callGetBlockLocations(
+          cluster.getNameNode(), f, 0, Long.MAX_VALUE).getLocatedBlocks();
+      final DatanodeInfo first = locatedblocks.get(0).getLocations()[0];
+      cluster.stopDataNode(first.getName());
+
+      //get checksum again
+      final FileChecksum cs2 = fs.getFileChecksum(p);
+      assertEquals(cs1, cs2);
+    } finally {
+      cluster.shutdown();
+    }
+  }
 }