From 245c3728efc5f3c6661c5c5dd5b572919477232d 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 67a46c6c467..31fa3796e20 100644 --- a/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt +++ b/hadoop-hdfs-project/hadoop-hdfs/CHANGES.txt @@ -54,6 +54,9 @@ Release 2.9.0 - UNRELEASED BUG FIXES + HDFS-9601. NNThroughputBenchmark.BlockReportStats should handle + NotReplicatedYetException on adding block (iwasakims) + HDFS-9621. Consolidate FSDirStatAndListingOp#createFileStatus to let its INodesInPath parameter always include the target INode. (jing9) 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.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 @@ private ExtendedBlock addBlocks(String fileName, String clientName) 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 @@ private ExtendedBlock addBlocks(String fileName, String clientName) 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 */