|
@@ -116,6 +116,39 @@ public class DFSInputStream extends FSInputStream {
|
|
* Grab the open-file info from namenode
|
|
* Grab the open-file info from namenode
|
|
*/
|
|
*/
|
|
synchronized void openInfo() throws IOException, UnresolvedLinkException {
|
|
synchronized void openInfo() throws IOException, UnresolvedLinkException {
|
|
|
|
+ lastBlockBeingWrittenLength = fetchLocatedBlocksAndGetLastBlockLength();
|
|
|
|
+ int retriesForLastBlockLength = 3;
|
|
|
|
+ while (retriesForLastBlockLength > 0) {
|
|
|
|
+ // Getting last block length as -1 is a special case. When cluster
|
|
|
|
+ // restarts, DNs may not report immediately. At this time partial block
|
|
|
|
+ // locations will not be available with NN for getting the length. Lets
|
|
|
|
+ // retry for 3 times to get the length.
|
|
|
|
+ if (lastBlockBeingWrittenLength == -1) {
|
|
|
|
+ DFSClient.LOG.warn("Last block locations not available. "
|
|
|
|
+ + "Datanodes might not have reported blocks completely."
|
|
|
|
+ + " Will retry for " + retriesForLastBlockLength + " times");
|
|
|
|
+ waitFor(4000);
|
|
|
|
+ lastBlockBeingWrittenLength = fetchLocatedBlocksAndGetLastBlockLength();
|
|
|
|
+ } else {
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
|
|
+ retriesForLastBlockLength--;
|
|
|
|
+ }
|
|
|
|
+ if (retriesForLastBlockLength == 0) {
|
|
|
|
+ throw new IOException("Could not obtain the last block locations.");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void waitFor(int waitTime) throws IOException {
|
|
|
|
+ try {
|
|
|
|
+ Thread.sleep(waitTime);
|
|
|
|
+ } catch (InterruptedException e) {
|
|
|
|
+ throw new IOException(
|
|
|
|
+ "Interrupted while getting the last block length.");
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private long fetchLocatedBlocksAndGetLastBlockLength() throws IOException {
|
|
LocatedBlocks newInfo = DFSClient.callGetBlockLocations(dfsClient.namenode, src, 0, prefetchSize);
|
|
LocatedBlocks newInfo = DFSClient.callGetBlockLocations(dfsClient.namenode, src, 0, prefetchSize);
|
|
if (DFSClient.LOG.isDebugEnabled()) {
|
|
if (DFSClient.LOG.isDebugEnabled()) {
|
|
DFSClient.LOG.debug("newInfo = " + newInfo);
|
|
DFSClient.LOG.debug("newInfo = " + newInfo);
|
|
@@ -134,10 +167,13 @@ public class DFSInputStream extends FSInputStream {
|
|
}
|
|
}
|
|
}
|
|
}
|
|
locatedBlocks = newInfo;
|
|
locatedBlocks = newInfo;
|
|
- lastBlockBeingWrittenLength = 0;
|
|
|
|
|
|
+ long lastBlockBeingWrittenLength = 0;
|
|
if (!locatedBlocks.isLastBlockComplete()) {
|
|
if (!locatedBlocks.isLastBlockComplete()) {
|
|
final LocatedBlock last = locatedBlocks.getLastLocatedBlock();
|
|
final LocatedBlock last = locatedBlocks.getLastLocatedBlock();
|
|
if (last != null) {
|
|
if (last != null) {
|
|
|
|
+ if (last.getLocations().length == 0) {
|
|
|
|
+ return -1;
|
|
|
|
+ }
|
|
final long len = readBlockLength(last);
|
|
final long len = readBlockLength(last);
|
|
last.getBlock().setNumBytes(len);
|
|
last.getBlock().setNumBytes(len);
|
|
lastBlockBeingWrittenLength = len;
|
|
lastBlockBeingWrittenLength = len;
|
|
@@ -145,13 +181,12 @@ public class DFSInputStream extends FSInputStream {
|
|
}
|
|
}
|
|
|
|
|
|
currentNode = null;
|
|
currentNode = null;
|
|
|
|
+ return lastBlockBeingWrittenLength;
|
|
}
|
|
}
|
|
|
|
|
|
/** Read the block length from one of the datanodes. */
|
|
/** Read the block length from one of the datanodes. */
|
|
private long readBlockLength(LocatedBlock locatedblock) throws IOException {
|
|
private long readBlockLength(LocatedBlock locatedblock) throws IOException {
|
|
- if (locatedblock == null || locatedblock.getLocations().length == 0) {
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
|
|
+ assert locatedblock != null : "LocatedBlock cannot be null";
|
|
int replicaNotFoundCount = locatedblock.getLocations().length;
|
|
int replicaNotFoundCount = locatedblock.getLocations().length;
|
|
|
|
|
|
for(DatanodeInfo datanode : locatedblock.getLocations()) {
|
|
for(DatanodeInfo datanode : locatedblock.getLocations()) {
|