Skip to content

Commit a2fef12

Browse files
author
zengqiang.xu
committed
HDFS-16698. Add a metric to sense possible MaxDirectoryItemsExceededException in time.
1 parent 4c8cd61 commit a2fef12

File tree

5 files changed

+58
-5
lines changed

5 files changed

+58
-5
lines changed

hadoop-hdfs-project/hadoop-hdfs-rbf/src/main/java/org/apache/hadoop/hdfs/server/federation/metrics/NamenodeBeanMetrics.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -781,6 +781,11 @@ public int getFsLockQueueLength() {
781781
return 0;
782782
}
783783

784+
@Override
785+
public int getMaxDirectoryItemsAlarmNums() {
786+
return 0;
787+
}
788+
784789
@Override
785790
public long getTotalSyncCount() {
786791
return 0;

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSDirectory.java

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@
8383
import java.util.TreeSet;
8484
import java.util.concurrent.ForkJoinPool;
8585
import java.util.concurrent.RecursiveAction;
86+
import java.util.concurrent.atomic.AtomicInteger;
8687

8788
import static org.apache.hadoop.fs.CommonConfigurationKeys.FS_PROTECTED_DIRECTORIES;
8889
import static org.apache.hadoop.hdfs.DFSConfigKeys.DFS_NAMENODE_ACCESSTIME_PRECISION_DEFAULT;
@@ -156,6 +157,8 @@ private static INodeDirectory createRoot(FSNamesystem namesystem) {
156157
private volatile boolean skipQuotaCheck = false; //skip while consuming edits
157158
private final int maxComponentLength;
158159
private final int maxDirItems;
160+
private final int maxDirItemsAlarmThreshold;
161+
private final AtomicInteger maxDirItemsAlarmNum;
159162
private final int lsLimit; // max list limit
160163
private final int contentCountLimit; // max content summary counts per run
161164
private final long contentSleepMicroSec;
@@ -379,6 +382,8 @@ public enum DirOp {
379382
this.maxDirItems = conf.getInt(
380383
DFSConfigKeys.DFS_NAMENODE_MAX_DIRECTORY_ITEMS_KEY,
381384
DFSConfigKeys.DFS_NAMENODE_MAX_DIRECTORY_ITEMS_DEFAULT);
385+
this.maxDirItemsAlarmThreshold = (int) Math.ceil(this.maxDirItems * 0.8);
386+
this.maxDirItemsAlarmNum = new AtomicInteger(0);
382387
this.inodeXAttrsLimit = conf.getInt(
383388
DFSConfigKeys.DFS_NAMENODE_MAX_XATTRS_PER_INODE_KEY,
384389
DFSConfigKeys.DFS_NAMENODE_MAX_XATTRS_PER_INODE_DEFAULT);
@@ -1283,16 +1288,18 @@ void verifyMaxDirItems(INodeDirectory parent, String parentPath)
12831288
throws MaxDirectoryItemsExceededException {
12841289
final int count = parent.getChildrenList(CURRENT_STATE_ID).size();
12851290
if (count >= maxDirItems) {
1286-
final MaxDirectoryItemsExceededException e
1287-
= new MaxDirectoryItemsExceededException(parentPath, maxDirItems,
1288-
count);
1291+
final MaxDirectoryItemsExceededException e = new MaxDirectoryItemsExceededException(
1292+
parentPath, maxDirItems, count);
12891293
if (namesystem.isImageLoaded()) {
12901294
throw e;
12911295
} else {
12921296
// Do not throw if edits log is still being processed
1293-
NameNode.LOG.error("FSDirectory.verifyMaxDirItems: "
1294-
+ e.getLocalizedMessage());
1297+
NameNode.LOG.error("FSDirectory.verifyMaxDirItems: {}.", e.getLocalizedMessage());
12951298
}
1299+
} else if (count >= maxDirItemsAlarmThreshold) {
1300+
LOG.warn("File count exceeding alarm threshold for {}: {}/{}",
1301+
parentPath, count, this.maxDirItems);
1302+
this.maxDirItemsAlarmNum.incrementAndGet();
12961303
}
12971304
}
12981305

@@ -1579,6 +1586,10 @@ long totalInodes() {
15791586
return getInodeMapSize();
15801587
}
15811588

1589+
int getMaxDirItemsAlarmNum() {
1590+
return this.maxDirItemsAlarmNum.get();
1591+
}
1592+
15821593
/**
15831594
* Reset the entire namespace tree.
15841595
*/

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/FSNamesystem.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8888,6 +8888,17 @@ public long getTotalSyncCount() {
88888888
return fsImage.editLog.getTotalSyncCount();
88898889
}
88908890

8891+
/**
8892+
* Returns total number of alarms that SubDirectoryItems
8893+
* of one directory have reached alarm threshold.
8894+
*/
8895+
@Override
8896+
@Metric({"MaxDirectoryItemsAlarmNums",
8897+
"Total number of alarms that SubDirectoryItems more than alarm threshold"})
8898+
public int getMaxDirectoryItemsAlarmNums() {
8899+
return this.dir.getMaxDirItemsAlarmNum();
8900+
}
8901+
88918902
/**
88928903
* Return total time spent doing sync operations on FSEditLog.
88938904
*/

hadoop-hdfs-project/hadoop-hdfs/src/main/java/org/apache/hadoop/hdfs/server/namenode/metrics/FSNamesystemMBean.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,12 @@ public interface FSNamesystemMBean {
224224
*/
225225
int getFsLockQueueLength();
226226

227+
/**
228+
* Returns total number of alarms that SubDirectoryItems
229+
* of one directory have reached alarm threshold.
230+
*/
231+
public int getMaxDirectoryItemsAlarmNums();
232+
227233
/**
228234
* Return total number of Sync Operations on FSEditLog.
229235
*/

hadoop-hdfs-project/hadoop-hdfs/src/test/java/org/apache/hadoop/hdfs/server/namenode/TestFsLimits.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,26 @@ public void testMaxDirItems() throws Exception {
114114
mkdirs("/4444", MaxDirectoryItemsExceededException.class);
115115
}
116116

117+
@Test
118+
public void testMaxDirItemsAlarm() throws Exception {
119+
conf.setInt(DFSConfigKeys.DFS_NAMENODE_MAX_DIRECTORY_ITEMS_KEY, 10);
120+
mkdirs("/1", null);
121+
mkdirs("/22", null);
122+
mkdirs("/333", null);
123+
mkdirs("/4444", null);
124+
mkdirs("/55555", null);
125+
mkdirs("/666666", null);
126+
mkdirs("/7777777", null);
127+
mkdirs("/88888888", null);
128+
assertEquals(0, fs.getMaxDirectoryItemsAlarmNums());
129+
mkdirs("/999999999", null);
130+
assertEquals(1, fs.getMaxDirectoryItemsAlarmNums());
131+
mkdirs("/1010101010", null);
132+
assertEquals(2, fs.getMaxDirectoryItemsAlarmNums());
133+
mkdirs("/11111111111", MaxDirectoryItemsExceededException.class);
134+
assertEquals(2, fs.getMaxDirectoryItemsAlarmNums());
135+
}
136+
117137
@Test
118138
public void testMaxDirItemsRename() throws Exception {
119139
conf.setInt(DFSConfigKeys.DFS_NAMENODE_MAX_DIRECTORY_ITEMS_KEY, 2);

0 commit comments

Comments
 (0)