|
@@ -43,6 +43,7 @@ import org.apache.hadoop.hdfs.protocol.HdfsFileStatus;
|
|
import org.apache.hadoop.hdfs.protocol.QuotaExceededException;
|
|
import org.apache.hadoop.hdfs.protocol.QuotaExceededException;
|
|
import org.apache.hadoop.hdfs.server.common.HdfsConstants.BlockUCState;
|
|
import org.apache.hadoop.hdfs.server.common.HdfsConstants.BlockUCState;
|
|
import org.apache.hadoop.hdfs.server.common.HdfsConstants.StartupOption;
|
|
import org.apache.hadoop.hdfs.server.common.HdfsConstants.StartupOption;
|
|
|
|
+import org.apache.hadoop.hdfs.util.ByteArray;
|
|
import static org.apache.hadoop.hdfs.server.common.Util.now;
|
|
import static org.apache.hadoop.hdfs.server.common.Util.now;
|
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
|
import org.apache.hadoop.hdfs.DFSConfigKeys;
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
import org.apache.hadoop.security.UserGroupInformation;
|
|
@@ -64,6 +65,12 @@ class FSDirectory implements Closeable {
|
|
private static final long UNKNOWN_DISK_SPACE = -1;
|
|
private static final long UNKNOWN_DISK_SPACE = -1;
|
|
private final int lsLimit; // max list limit
|
|
private final int lsLimit; // max list limit
|
|
|
|
|
|
|
|
+ /**
|
|
|
|
+ * Caches frequently used file names used in {@link INode} to reuse
|
|
|
|
+ * byte[] objects and reduce heap usage.
|
|
|
|
+ */
|
|
|
|
+ private final NameCache<ByteArray> nameCache;
|
|
|
|
+
|
|
/** Access an existing dfs name directory. */
|
|
/** Access an existing dfs name directory. */
|
|
FSDirectory(FSNamesystem ns, Configuration conf) {
|
|
FSDirectory(FSNamesystem ns, Configuration conf) {
|
|
this(new FSImage(), ns, conf);
|
|
this(new FSImage(), ns, conf);
|
|
@@ -72,6 +79,7 @@ class FSDirectory implements Closeable {
|
|
NameNode.LOG.info("set FSImage.restoreFailedStorage");
|
|
NameNode.LOG.info("set FSImage.restoreFailedStorage");
|
|
fsImage.setRestoreFailedStorage(true);
|
|
fsImage.setRestoreFailedStorage(true);
|
|
}
|
|
}
|
|
|
|
+
|
|
fsImage.setCheckpointDirectories(FSImage.getCheckpointDirs(conf, null),
|
|
fsImage.setCheckpointDirectories(FSImage.getCheckpointDirs(conf, null),
|
|
FSImage.getCheckpointEditsDirs(conf, null));
|
|
FSImage.getCheckpointEditsDirs(conf, null));
|
|
}
|
|
}
|
|
@@ -86,6 +94,13 @@ class FSDirectory implements Closeable {
|
|
DFSConfigKeys.DFS_LIST_LIMIT, DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT);
|
|
DFSConfigKeys.DFS_LIST_LIMIT, DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT);
|
|
this.lsLimit = configuredLimit>0 ?
|
|
this.lsLimit = configuredLimit>0 ?
|
|
configuredLimit : DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT;
|
|
configuredLimit : DFSConfigKeys.DFS_LIST_LIMIT_DEFAULT;
|
|
|
|
+
|
|
|
|
+ int threshold = conf.getInt(
|
|
|
|
+ DFSConfigKeys.DFS_NAMENODE_NAME_CACHE_THRESHOLD_KEY,
|
|
|
|
+ DFSConfigKeys.DFS_NAMENODE_NAME_CACHE_THRESHOLD_DEFAULT);
|
|
|
|
+ NameNode.LOG.info("Caching file names occuring more than " + threshold
|
|
|
|
+ + " times ");
|
|
|
|
+ nameCache = new NameCache<ByteArray>(threshold);
|
|
}
|
|
}
|
|
|
|
|
|
private FSNamesystem getFSNamesystem() {
|
|
private FSNamesystem getFSNamesystem() {
|
|
@@ -119,6 +134,7 @@ class FSDirectory implements Closeable {
|
|
}
|
|
}
|
|
synchronized (this) {
|
|
synchronized (this) {
|
|
this.ready = true;
|
|
this.ready = true;
|
|
|
|
+ this.nameCache.initialized();
|
|
this.notifyAll();
|
|
this.notifyAll();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -270,6 +286,7 @@ class FSDirectory implements Closeable {
|
|
try {
|
|
try {
|
|
newParent = rootDir.addToParent(src, newNode, parentINode,
|
|
newParent = rootDir.addToParent(src, newNode, parentINode,
|
|
false, propagateModTime);
|
|
false, propagateModTime);
|
|
|
|
+ cacheName(newNode);
|
|
} catch (FileNotFoundException e) {
|
|
} catch (FileNotFoundException e) {
|
|
return null;
|
|
return null;
|
|
}
|
|
}
|
|
@@ -1396,7 +1413,9 @@ class FSDirectory implements Closeable {
|
|
long childDiskspace, boolean inheritPermission)
|
|
long childDiskspace, boolean inheritPermission)
|
|
throws QuotaExceededException, UnresolvedLinkException {
|
|
throws QuotaExceededException, UnresolvedLinkException {
|
|
byte[][] components = INode.getPathComponents(src);
|
|
byte[][] components = INode.getPathComponents(src);
|
|
- child.setLocalName(components[components.length-1]);
|
|
|
|
|
|
+ byte[] path = components[components.length-1];
|
|
|
|
+ child.setLocalName(path);
|
|
|
|
+ cacheName(child);
|
|
INode[] inodes = new INode[components.length];
|
|
INode[] inodes = new INode[components.length];
|
|
synchronized (rootDir) {
|
|
synchronized (rootDir) {
|
|
rootDir.getExistingPathINodes(components, inodes, false);
|
|
rootDir.getExistingPathINodes(components, inodes, false);
|
|
@@ -1852,4 +1871,20 @@ class FSDirectory implements Closeable {
|
|
}
|
|
}
|
|
return newNode;
|
|
return newNode;
|
|
}
|
|
}
|
|
|
|
+
|
|
|
|
+ /**
|
|
|
|
+ * Caches frequently used file names to reuse file name objects and
|
|
|
|
+ * reduce heap size.
|
|
|
|
+ */
|
|
|
|
+ void cacheName(INode inode) {
|
|
|
|
+ // Name is cached only for files
|
|
|
|
+ if (inode.isDirectory() || inode.isLink()) {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ ByteArray name = new ByteArray(inode.getLocalNameBytes());
|
|
|
|
+ name = nameCache.put(name);
|
|
|
|
+ if (name != null) {
|
|
|
|
+ inode.setLocalName(name.getBytes());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
}
|
|
}
|