From 5fd4bd1d8c6e02fdca5b1e620cf7416c5e07c6c2 Mon Sep 17 00:00:00 2001 From: Masatake Iwasaki Date: Fri, 22 Jan 2016 12:28:38 +0900 Subject: [PATCH] HDFS-9601. NNThroughputBenchmark.BlockReportStats should handle NotReplicatedYetException on adding block (iwasakims) --- hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt | 3 ++ .../namenode/NNThroughputBenchmark.java | 34 ++++++++++++++++++- 2 files changed, 36 insertions(+), 1 deletion(-) diff --git a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt index 604e51de4d9..4d41daeb78f 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -1713,6 +1713,9 @@ Release 2.8.0 - UNRELEASED HDFS-9748. Avoid duplication in pendingReplications when addExpectedReplicasToPending is called twice. (Walter Su via jing9) + HDFS-9601. NNThroughputBenchmark.BlockReportStats should handle + NotReplicatedYetException on adding block (iwasakims) + Release 2.7.3 - UNRELEASED INCOMPATIBLE CHANGES diff --git a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/NNThroughputBenchmark.java b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/NNThroughputBenchmark.java index 8a594ede4a0..42cb72f8a3b 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/NNThroughputBenchmark.java +++ b/hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/NNThroughputBenchmark.java @@ -68,6 +68,7 @@ import org.apache.hadoop.hdfs.server.protocol.StorageBlockReport; import org.apache.hadoop.hdfs.server.protocol.StorageReceivedDeletedBlocks; import org.apache.hadoop.hdfs.server.protocol.StorageReport; import org.apache.hadoop.io.EnumSetWritable; +import org.apache.hadoop.ipc.RemoteException; import org.apache.hadoop.net.DNS; import org.apache.hadoop.net.NetworkTopology; import org.apache.hadoop.security.Groups; @@ -1181,7 +1182,7 @@ public class NNThroughputBenchmark implements Tool { throws IOException { ExtendedBlock prevBlock = null; for(int jdx = 0; jdx < blocksPerFile; jdx++) { - LocatedBlock loc = clientProto.addBlock(fileName, clientName, + LocatedBlock loc = addBlock(fileName, clientName, prevBlock, null, HdfsConstants.GRANDFATHER_INODE_ID, null); prevBlock = loc.getBlock(); for(DatanodeInfo dnInfo : loc.getLocations()) { @@ -1195,10 +1196,41 @@ public class NNThroughputBenchmark implements Tool { dataNodeProto.blockReceivedAndDeleted(datanodes[dnIdx].dnRegistration, bpid, report); } + // IBRs are asynchronously processed by NameNode. The next + // ClientProtocol#addBlock() may throw NotReplicatedYetException. } return prevBlock; } + /** + * Retry ClientProtocol.addBlock() if it throws NotReplicatedYetException. + * Because addBlock() also commits the previous block, + * it fails if enough IBRs are not processed by NameNode. + */ + private LocatedBlock addBlock(String src, String clientName, + ExtendedBlock previous, DatanodeInfo[] excludeNodes, long fileId, + String[] favoredNodes) throws IOException { + for (int i = 0; i < 30; i++) { + try { + return clientProto.addBlock(src, clientName, + previous, excludeNodes, fileId, favoredNodes); + } catch (NotReplicatedYetException|RemoteException e) { + if (e instanceof RemoteException) { + String className = ((RemoteException) e).getClassName(); + if (!className.equals(NotReplicatedYetException.class.getName())) { + throw e; + } + } + try { + Thread.sleep(100); + } catch (InterruptedException ie) { + LOG.warn("interrupted while retrying addBlock.", ie); + } + } + } + throw new IOException("failed to add block."); + } + /** * Does not require the argument */