|
51 | 51 | import org.apache.hadoop.hdfs.protocol.datatransfer.PacketHeader; |
52 | 52 | import org.apache.hadoop.hdfs.security.token.block.BlockTokenIdentifier; |
53 | 53 | import org.apache.hadoop.hdfs.server.datanode.CachingStrategy; |
| 54 | +import org.apache.hadoop.hdfs.server.namenode.NotReplicatedYetException; |
54 | 55 | import org.apache.hadoop.hdfs.server.namenode.RetryStartFileException; |
55 | 56 | import org.apache.hadoop.hdfs.server.namenode.SafeModeException; |
56 | 57 | import org.apache.hadoop.hdfs.util.ByteArrayManager; |
@@ -212,14 +213,17 @@ private DFSOutputStream(DFSClient dfsClient, String src, Progressable progress, |
212 | 213 | /** Construct a new output stream for creating a file. */ |
213 | 214 | protected DFSOutputStream(DFSClient dfsClient, String src, HdfsFileStatus stat, |
214 | 215 | EnumSet<CreateFlag> flag, Progressable progress, |
215 | | - DataChecksum checksum, String[] favoredNodes) throws IOException { |
| 216 | + DataChecksum checksum, String[] favoredNodes, boolean createStreamer) |
| 217 | + throws IOException { |
216 | 218 | this(dfsClient, src, progress, stat, checksum); |
217 | 219 | this.shouldSyncBlock = flag.contains(CreateFlag.SYNC_BLOCK); |
218 | 220 |
|
219 | 221 | computePacketChunkSize(dfsClient.getConf().getWritePacketSize(), bytesPerChecksum); |
220 | 222 |
|
221 | | - streamer = new DataStreamer(stat, null, dfsClient, src, progress, checksum, |
222 | | - cachingStrategy, byteArrayManager, favoredNodes); |
| 223 | + if (createStreamer) { |
| 224 | + streamer = new DataStreamer(stat, null, dfsClient, src, progress, |
| 225 | + checksum, cachingStrategy, byteArrayManager, favoredNodes); |
| 226 | + } |
223 | 227 | } |
224 | 228 |
|
225 | 229 | static DFSOutputStream newStreamForCreate(DFSClient dfsClient, String src, |
@@ -276,7 +280,7 @@ static DFSOutputStream newStreamForCreate(DFSClient dfsClient, String src, |
276 | 280 | flag, progress, checksum, favoredNodes); |
277 | 281 | } else { |
278 | 282 | out = new DFSOutputStream(dfsClient, src, stat, |
279 | | - flag, progress, checksum, favoredNodes); |
| 283 | + flag, progress, checksum, favoredNodes, true); |
280 | 284 | } |
281 | 285 | out.start(); |
282 | 286 | return out; |
@@ -476,7 +480,7 @@ protected void adjustChunkBoundary() { |
476 | 480 | * |
477 | 481 | * @throws IOException |
478 | 482 | */ |
479 | | - protected void endBlock() throws IOException { |
| 483 | + void endBlock() throws IOException { |
480 | 484 | if (getStreamer().getBytesCurBlock() == blockSize) { |
481 | 485 | setCurrentPacketToEmpty(); |
482 | 486 | enqueueCurrentPacket(); |
@@ -921,4 +925,52 @@ protected DataStreamer getStreamer() { |
921 | 925 | public String toString() { |
922 | 926 | return getClass().getSimpleName() + ":" + streamer; |
923 | 927 | } |
| 928 | + |
| 929 | + static LocatedBlock addBlock(DatanodeInfo[] excludedNodes, DFSClient dfsClient, |
| 930 | + String src, ExtendedBlock prevBlock, long fileId, String[] favoredNodes) |
| 931 | + throws IOException { |
| 932 | + final DfsClientConf conf = dfsClient.getConf(); |
| 933 | + int retries = conf.getNumBlockWriteLocateFollowingRetry(); |
| 934 | + long sleeptime = conf.getBlockWriteLocateFollowingInitialDelayMs(); |
| 935 | + long localstart = Time.monotonicNow(); |
| 936 | + while (true) { |
| 937 | + try { |
| 938 | + return dfsClient.namenode.addBlock(src, dfsClient.clientName, prevBlock, |
| 939 | + excludedNodes, fileId, favoredNodes); |
| 940 | + } catch (RemoteException e) { |
| 941 | + IOException ue = e.unwrapRemoteException(FileNotFoundException.class, |
| 942 | + AccessControlException.class, |
| 943 | + NSQuotaExceededException.class, |
| 944 | + DSQuotaExceededException.class, |
| 945 | + QuotaByStorageTypeExceededException.class, |
| 946 | + UnresolvedPathException.class); |
| 947 | + if (ue != e) { |
| 948 | + throw ue; // no need to retry these exceptions |
| 949 | + } |
| 950 | + if (NotReplicatedYetException.class.getName().equals(e.getClassName())) { |
| 951 | + if (retries == 0) { |
| 952 | + throw e; |
| 953 | + } else { |
| 954 | + --retries; |
| 955 | + LOG.info("Exception while adding a block", e); |
| 956 | + long elapsed = Time.monotonicNow() - localstart; |
| 957 | + if (elapsed > 5000) { |
| 958 | + LOG.info("Waiting for replication for " + (elapsed / 1000) |
| 959 | + + " seconds"); |
| 960 | + } |
| 961 | + try { |
| 962 | + LOG.warn("NotReplicatedYetException sleeping " + src |
| 963 | + + " retries left " + retries); |
| 964 | + Thread.sleep(sleeptime); |
| 965 | + sleeptime *= 2; |
| 966 | + } catch (InterruptedException ie) { |
| 967 | + LOG.warn("Caught exception", ie); |
| 968 | + } |
| 969 | + } |
| 970 | + } else { |
| 971 | + throw e; |
| 972 | + } |
| 973 | + } |
| 974 | + } |
| 975 | + } |
924 | 976 | } |
0 commit comments