|
@@ -17,8 +17,38 @@
|
|
*/
|
|
*/
|
|
package org.apache.hadoop.hdfs;
|
|
package org.apache.hadoop.hdfs;
|
|
|
|
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_BLOCK_SIZE_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_BLOCK_SIZE_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_BYTES_PER_CHECKSUM_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_BYTES_PER_CHECKSUM_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_BLOCK_WRITE_LOCATEFOLLOWINGBLOCK_RETRIES_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_BLOCK_WRITE_LOCATEFOLLOWINGBLOCK_RETRIES_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_BLOCK_WRITE_RETRIES_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_BLOCK_WRITE_RETRIES_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_CACHED_CONN_RETRY_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_CACHED_CONN_RETRY_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_FAILOVER_MAX_ATTEMPTS_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_FAILOVER_MAX_ATTEMPTS_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_FAILOVER_SLEEPTIME_BASE_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_FAILOVER_SLEEPTIME_BASE_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_FAILOVER_SLEEPTIME_MAX_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_FAILOVER_SLEEPTIME_MAX_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_MAX_BLOCK_ACQUIRE_FAILURES_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_MAX_BLOCK_ACQUIRE_FAILURES_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_READ_PREFETCH_SIZE_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_RETRY_WINDOW_BASE;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_SOCKET_CACHE_CAPACITY_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_SOCKET_CACHE_CAPACITY_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_SOCKET_TIMEOUT_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_USE_LEGACY_BLOCKREADER;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_USE_LEGACY_BLOCKREADER_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_WRITE_PACKET_SIZE_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_CLIENT_WRITE_PACKET_SIZE_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_DATANODE_SOCKET_WRITE_TIMEOUT_KEY;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_REPLICATION_DEFAULT;
|
|
|
|
+import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_REPLICATION_KEY;
|
|
|
|
+
|
|
import java.io.BufferedOutputStream;
|
|
import java.io.BufferedOutputStream;
|
|
-import java.io.Closeable;
|
|
|
|
import java.io.DataInputStream;
|
|
import java.io.DataInputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.DataOutputStream;
|
|
import java.io.FileNotFoundException;
|
|
import java.io.FileNotFoundException;
|
|
@@ -26,11 +56,8 @@ import java.io.IOException;
|
|
import java.io.OutputStream;
|
|
import java.io.OutputStream;
|
|
import java.net.InetAddress;
|
|
import java.net.InetAddress;
|
|
import java.net.InetSocketAddress;
|
|
import java.net.InetSocketAddress;
|
|
-import java.net.NetworkInterface;
|
|
|
|
import java.net.Socket;
|
|
import java.net.Socket;
|
|
-import java.net.SocketException;
|
|
|
|
import java.net.URI;
|
|
import java.net.URI;
|
|
-import java.net.URISyntaxException;
|
|
|
|
import java.util.Collections;
|
|
import java.util.Collections;
|
|
import java.util.EnumSet;
|
|
import java.util.EnumSet;
|
|
import java.util.HashMap;
|
|
import java.util.HashMap;
|
|
@@ -60,8 +87,6 @@ import org.apache.hadoop.fs.ParentNotDirectoryException;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.Path;
|
|
import org.apache.hadoop.fs.UnresolvedLinkException;
|
|
import org.apache.hadoop.fs.UnresolvedLinkException;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
import org.apache.hadoop.fs.permission.FsPermission;
|
|
-import static org.apache.hadoop.hdfs.DFSConfigKeys.*;
|
|
|
|
-
|
|
|
|
import org.apache.hadoop.hdfs.protocol.ClientProtocol;
|
|
import org.apache.hadoop.hdfs.protocol.ClientProtocol;
|
|
import org.apache.hadoop.hdfs.protocol.CorruptFileBlocks;
|
|
import org.apache.hadoop.hdfs.protocol.CorruptFileBlocks;
|
|
import org.apache.hadoop.hdfs.protocol.DSQuotaExceededException;
|
|
import org.apache.hadoop.hdfs.protocol.DSQuotaExceededException;
|
|
@@ -101,7 +126,6 @@ import org.apache.hadoop.ipc.RPC;
|
|
import org.apache.hadoop.ipc.RemoteException;
|
|
import org.apache.hadoop.ipc.RemoteException;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
import org.apache.hadoop.net.NetUtils;
|
|
import org.apache.hadoop.security.AccessControlException;
|
|
import org.apache.hadoop.security.AccessControlException;
|
|
-import org.apache.hadoop.security.SecurityUtil;
|
|
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
import org.apache.hadoop.security.token.SecretManager.InvalidToken;
|
|
import org.apache.hadoop.security.token.SecretManager.InvalidToken;
|
|
import org.apache.hadoop.security.token.Token;
|
|
import org.apache.hadoop.security.token.Token;
|
|
@@ -133,6 +157,7 @@ public class DFSClient implements java.io.Closeable {
|
|
|
|
|
|
final UserGroupInformation ugi;
|
|
final UserGroupInformation ugi;
|
|
volatile boolean clientRunning = true;
|
|
volatile boolean clientRunning = true;
|
|
|
|
+ volatile long lastLeaseRenewal;
|
|
private volatile FsServerDefaults serverDefaults;
|
|
private volatile FsServerDefaults serverDefaults;
|
|
private volatile long serverDefaultsLastUpdate;
|
|
private volatile long serverDefaultsLastUpdate;
|
|
final String clientName;
|
|
final String clientName;
|
|
@@ -381,6 +406,12 @@ public class DFSClient implements java.io.Closeable {
|
|
void putFileBeingWritten(final String src, final DFSOutputStream out) {
|
|
void putFileBeingWritten(final String src, final DFSOutputStream out) {
|
|
synchronized(filesBeingWritten) {
|
|
synchronized(filesBeingWritten) {
|
|
filesBeingWritten.put(src, out);
|
|
filesBeingWritten.put(src, out);
|
|
|
|
+ // update the last lease renewal time only when there was no
|
|
|
|
+ // writes. once there is one write stream open, the lease renewer
|
|
|
|
+ // thread keeps it updated well with in anyone's expiration time.
|
|
|
|
+ if (lastLeaseRenewal == 0) {
|
|
|
|
+ updateLastLeaseRenewal();
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -388,6 +419,9 @@ public class DFSClient implements java.io.Closeable {
|
|
void removeFileBeingWritten(final String src) {
|
|
void removeFileBeingWritten(final String src) {
|
|
synchronized(filesBeingWritten) {
|
|
synchronized(filesBeingWritten) {
|
|
filesBeingWritten.remove(src);
|
|
filesBeingWritten.remove(src);
|
|
|
|
+ if (filesBeingWritten.isEmpty()) {
|
|
|
|
+ lastLeaseRenewal = 0;
|
|
|
|
+ }
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -403,6 +437,19 @@ public class DFSClient implements java.io.Closeable {
|
|
return clientRunning;
|
|
return clientRunning;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ long getLastLeaseRenewal() {
|
|
|
|
+ return lastLeaseRenewal;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ void updateLastLeaseRenewal() {
|
|
|
|
+ synchronized(filesBeingWritten) {
|
|
|
|
+ if (filesBeingWritten.isEmpty()) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ lastLeaseRenewal = System.currentTimeMillis();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
/**
|
|
/**
|
|
* Renew leases.
|
|
* Renew leases.
|
|
* @return true if lease was renewed. May return false if this
|
|
* @return true if lease was renewed. May return false if this
|
|
@@ -410,8 +457,24 @@ public class DFSClient implements java.io.Closeable {
|
|
**/
|
|
**/
|
|
boolean renewLease() throws IOException {
|
|
boolean renewLease() throws IOException {
|
|
if (clientRunning && !isFilesBeingWrittenEmpty()) {
|
|
if (clientRunning && !isFilesBeingWrittenEmpty()) {
|
|
- namenode.renewLease(clientName);
|
|
|
|
- return true;
|
|
|
|
|
|
+ try {
|
|
|
|
+ namenode.renewLease(clientName);
|
|
|
|
+ updateLastLeaseRenewal();
|
|
|
|
+ return true;
|
|
|
|
+ } catch (IOException e) {
|
|
|
|
+ // Abort if the lease has already expired.
|
|
|
|
+ final long elapsed = System.currentTimeMillis() - getLastLeaseRenewal();
|
|
|
|
+ if (elapsed > HdfsConstants.LEASE_SOFTLIMIT_PERIOD) {
|
|
|
|
+ LOG.warn("Failed to renew lease for " + clientName + " for "
|
|
|
|
+ + (elapsed/1000) + " seconds (>= soft-limit ="
|
|
|
|
+ + (HdfsConstants.LEASE_SOFTLIMIT_PERIOD/1000) + " seconds.) "
|
|
|
|
+ + "Closing all files being written ...", e);
|
|
|
|
+ closeAllFilesBeingWritten(true);
|
|
|
|
+ } else {
|
|
|
|
+ // Let the lease renewer handle it and retry.
|
|
|
|
+ throw e;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|