Skip to content

HDFS-17953. DataNode IBR pendingIBRs grows unbounded when a NameNode is unreachable, causing OOM#8626

Open
singer-bin wants to merge 1 commit into
apache:trunkfrom
singer-bin:HDFS-17953
Open

HDFS-17953. DataNode IBR pendingIBRs grows unbounded when a NameNode is unreachable, causing OOM#8626
singer-bin wants to merge 1 commit into
apache:trunkfrom
singer-bin:HDFS-17953

Conversation

@singer-bin

Copy link
Copy Markdown
Contributor

Description of PR

JIRA: HDFS-17953

Problem

When a DataNode is configured with HA NameNodes (dfs.ha.namenodes.<nsId>), but
one of the configured NameNode IDs has no (or a wrong) RPC address — or the
NameNode is permanently unreachable — the
IncrementalBlockReportManager.pendingIBRs map for that actor grows without
bound and eventually causes the DataNode to OOM.

In BPOfferService#notifyNamenodeBlock, every block receive/delete event is
added to the IBR queue of every BPServiceActor, including the actor for the
unreachable NameNode. In IncrementalBlockReportManager#sendIBRs, on send
failure putMissing() puts all blocks back into the queue. When the NameNode is
permanently unreachable the send always fails, new events keep arriving, and the
queue grows indefinitely — there is no size limit, no TTL and no eviction.

The only existing protection (HDFS-9917) calls clearIBRs() during
reRegister() for STANDBY/OBSERVER NNs, but reRegister() is never triggered
when the NN is completely unreachable (no DNA_REGISTER command can be
received). A production heap dump showed ~223M ReceivedDeletedBlockInfo
instances occupying ~30 GB, caused by a stale nn3 whose RPC address was never
configured (it fell back to the logical nameservice:8020 which never
resolves).

Fix

  1. Add a configurable cap dfs.datanode.ibr.max.pending.size (default
    1,000,000). When exceeded, the pending IBR queue is cleared with a warning.
  2. Add a staleness guard dfs.datanode.ibr.max.stale.interval.ms (default
    30 min): if no successful IBR send happens within this window while entries
    are pending, the queue is cleared.
  3. After clearing (overflow or staleness), a Full Block Report is scheduled so
    the NameNode gets a complete, consistent view once reachable again.

This is safe: the FBR is the ultimate consistency guarantee; IBRs are only an
optimization for incremental updates between FBRs. Dropping queued IBRs for an
unreachable NN cannot cause inconsistency because a fresh FBR is sent on
reconnect/re-register.

Both protections can be disabled by setting the corresponding value to 0.

How was this patch tested?

New unit tests in TestIncrementalBlockReportManager:

  • testIBRQueueSizeLimit — queue is capped and cleared on overflow.
  • testIBRQueueStaleInterval — queue is cleared after the stale interval.
  • testIBRQueueNoLimit — cap disabled (0) keeps old behavior.
  • testIBRDeduplication — per-block dedup still works.
  • testTotalPendingIBRSizeMultipleStorages — size counting across storages.

For code changes:

  • Does the title or this PR starts with the corresponding JIRA issue id (e.g. 'HADOOP-17799. Your PR title ...')?
  • Object storage: N/A
  • If applicable, have you updated the LICENSE, LICENSE-binary, NOTICE-binary files? N/A

@hadoop-yetus

Copy link
Copy Markdown

🎊 +1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 22s Docker mode activated.
_ Prechecks _
+1 💚 dupname 0m 0s No case conflicting files found.
+0 🆗 codespell 0m 1s codespell was not available.
+0 🆗 detsecrets 0m 1s detect-secrets was not available.
+0 🆗 xmllint 0m 1s xmllint was not available.
+1 💚 @author 0m 0s The patch does not contain any @author tags.
+1 💚 test4tests 0m 0s The patch appears to include 1 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 26m 3s trunk passed
+1 💚 compile 0m 58s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 1m 1s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 5s trunk passed
+1 💚 mvnsite 1m 8s trunk passed
+1 💚 javadoc 0m 57s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 52s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 16s trunk passed
+1 💚 shadedclient 17m 45s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 0m 44s the patch passed
+1 💚 compile 0m 42s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 42s the patch passed
+1 💚 compile 0m 45s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 45s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
-0 ⚠️ checkstyle 0m 45s /results-checkstyle-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs-project/hadoop-hdfs: The patch generated 2 new + 259 unchanged - 0 fixed = 261 total (was 259)
+1 💚 mvnsite 0m 48s the patch passed
+1 💚 javadoc 0m 35s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 37s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 3s the patch passed
+1 💚 shadedclient 16m 50s patch has no errors when building and testing our client artifacts.
_ Other Tests _
+1 💚 unit 177m 19s hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 28s The patch does not generate ASF License warnings.
253m 40s
Subsystem Report/Notes
Docker ClientAPI=1.55 ServerAPI=1.55 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8626/1/artifact/out/Dockerfile
GITHUB PR #8626
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux c5d6c20ef4c9 5.15.0-181-generic #191-Ubuntu SMP Fri May 22 19:09:02 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / 93ebc4b
Default Java Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Multi-JDK versions /usr/lib/jvm/java-21-openjdk-amd64:Ubuntu-21.0.11+10-1-24.04.2-Ubuntu /usr/lib/jvm/java-17-openjdk-amd64:Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Test Results https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8626/1/testReport/
Max. process+thread count 4415 (vs. ulimit of 10000)
modules C: hadoop-hdfs-project/hadoop-hdfs U: hadoop-hdfs-project/hadoop-hdfs
Console output https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8626/1/console
versions git=2.43.0 maven=3.9.15 spotbugs=4.9.7
Powered by Apache Yetus 0.14.1 https://yetus.apache.org

This message was automatically generated.

@hadoop-yetus

Copy link
Copy Markdown

🎊 +1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 25s Docker mode activated.
_ Prechecks _
+1 💚 dupname 0m 0s No case conflicting files found.
+0 🆗 codespell 0m 0s codespell was not available.
+0 🆗 detsecrets 0m 0s detect-secrets was not available.
+0 🆗 xmllint 0m 0s xmllint was not available.
+1 💚 @author 0m 0s The patch does not contain any @author tags.
+1 💚 test4tests 0m 0s The patch appears to include 2 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 33m 20s trunk passed
+1 💚 compile 0m 57s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 1m 4s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 5s trunk passed
+1 💚 mvnsite 1m 10s trunk passed
+1 💚 javadoc 0m 45s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 46s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 18s trunk passed
+1 💚 shadedclient 21m 42s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 0m 54s the patch passed
+1 💚 compile 0m 49s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 49s the patch passed
+1 💚 compile 0m 50s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 50s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
-0 ⚠️ checkstyle 0m 46s /results-checkstyle-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs-project/hadoop-hdfs: The patch generated 2 new + 261 unchanged - 0 fixed = 263 total (was 261)
+1 💚 mvnsite 0m 52s the patch passed
+1 💚 javadoc 0m 35s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 39s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 37s the patch passed
+1 💚 shadedclient 19m 43s patch has no errors when building and testing our client artifacts.
_ Other Tests _
+1 💚 unit 182m 43s hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 26s The patch does not generate ASF License warnings.
273m 21s
Subsystem Report/Notes
Docker ClientAPI=1.55 ServerAPI=1.55 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8626/3/artifact/out/Dockerfile
GITHUB PR #8626
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux 24fbcb230fdd 5.15.0-181-generic #191-Ubuntu SMP Fri May 22 19:09:02 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / 308e2b0
Default Java Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Multi-JDK versions /usr/lib/jvm/java-21-openjdk-amd64:Ubuntu-21.0.11+10-1-24.04.2-Ubuntu /usr/lib/jvm/java-17-openjdk-amd64:Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
Test Results https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8626/3/testReport/
Max. process+thread count 4498 (vs. ulimit of 10000)
modules C: hadoop-hdfs-project/hadoop-hdfs U: hadoop-hdfs-project/hadoop-hdfs
Console output https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8626/3/console
versions git=2.43.0 maven=3.9.15 spotbugs=4.9.7
Powered by Apache Yetus 0.14.1 https://yetus.apache.org

This message was automatically generated.

@Hexiaoqiao

Copy link
Copy Markdown
Contributor

@singer-bin Great catch! I am confused why we need maxStaleIntervalMs here? IIUC, keep only pendingIBRs count less than threshold will avoid heap footprint oversize?

@singer-bin

Copy link
Copy Markdown
Contributor Author

Thanks for the review, @Hexiaoqiao ! You are right — the pending-block-count cap alone is enough to bound the DataNode heap footprint, so maxStaleIntervalMs was redundant. I have removed it and the related config (dfs.datanode.ibr.max.stale.interval.ms).

The fix now keeps a single, simple guard: dfs.datanode.ibr.max.pending.blocks (default 1,000,000). The pending block count is tracked in O(1), and when it reaches the cap IncrementalBlockReportManager#clearIBRsIfNeeded() clears the queue and the BPServiceActor schedules a full block report so the NameNode can resync once it is reachable again. Set the value to 0 to disable.

Updated tests (all passing locally):

  • TestIncrementalBlockReportManager: counter accounting, dedup, size-cap clear, and cap-disabled behavior.
  • TestIncrementalBlockReports#testIBRQueueBoundedWhenNNUnreachable: end-to-end test with a MiniDFSCluster and an unreachable NN, asserting the pending block count never exceeds the cap.

Please take another look. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants