Skip to content

HDFS-17890. Avoid slow disks datanode when reading data#8616

Open
junjie1233 wants to merge 1 commit into
apache:trunkfrom
junjie1233:HDFS-17890
Open

HDFS-17890. Avoid slow disks datanode when reading data#8616
junjie1233 wants to merge 1 commit into
apache:trunkfrom
junjie1233:HDFS-17890

Conversation

@junjie1233

@junjie1233 junjie1233 commented Jul 18, 2026

Copy link
Copy Markdown

Summary

When a client requests to read a block, the NameNode returns a list of DataNodes holding the replicas of that block.

The current logic sorts these DataNodes based on network topology (rack awareness, distance), without considering the performance of the underlying storage (disk/volume).

If a block replica resides on a slow or overloaded disk (for example, a hot disk with high latency), its DataNode may still be placed at the top of the sorted list and selected first by the client.


Example

Suppose a block has three replicas located on:

  • dn1: storage-A (slow disk)
  • dn2: storage-B (normal disk)
  • dn3: storage-C (normal disk)

Even if storage-A is known to be slow, the client will still prioritize reading from dn1, because the NameNode's sorting only considers network topology and ignores disk performance.


Fix

This PR adds disk-level slow storage tracking and deprioritization during block location sorting.

1. Disk-Level Tracking (SlowDiskTracker.java)

  • Track slow storage at StorageID granularity (not DataNode level).
  • Copy-on-Write cache cachedSlowDisksForRead (volatile reference swap) to avoid lock contention on read path.
  • Cache key: IP:PORT:StorageID (e.g., 127.0.0.1:50010:DS-xxx).
  • Dual key modes:
    • CACHE_KEY: IP:PORT:StorageID for read deprioritization.
    • LEGACY_KEY: IP:PORT:volumeName for backward compatibility with Top-N reports.
  • Background cache rebuild with configurable interval (default 30s), gated by deprioritizeSlowDiskDatanodeForRead — no background thread or overhead when the feature is disabled (default).
  • Automatic expiration of stale entries (reportValidityMs).
  • Cache stores READ latency (falls back to max latency if READ not reported) so sorting reflects the operation the client actually cares about.

2. Block Location Sorting (FSNamesystem.java)

  • New method sortLocatedBlocksBySlowDisk() reorders replicas after topology-based sorting.
  • Pre-compute slow keys before sorting to avoid string concatenation in comparator hot path.
  • Stable sort: preserves network topology order for non-slow replicas.
  • Slow replicas sorted by latency (higher latency → lower priority).
  • Erasure-coded blocks (LocatedStripedBlock) are skipped — reordering locations without updating blockIndices/blockTokens would cause data corruption.
  • Controlled by config:
    dfs.namenode.deprioritize.slow.disk.datanode.for.read (default: false).

3. Configuration (DFSConfigKeys.java + hdfs-default.xml)

  • dfs.namenode.deprioritize.slow.disk.datanode.for.read (default false) — master switch for read-path deprioritization.
  • dfs.namenode.slow.disk.cache.rebuild.interval (default 30s) — decouples cache rebuild frequency from Top-N report generation interval. Allows independent tuning for large clusters. Ignored when the feature is disabled.

4. Disk Key Format (DataNodeDiskMetrics.java)

  • Use volumeName|storageID format for slow disk reports.
  • Enables SlowDiskTracker to extract both legacy key (WebUI / Top-N reports) and cache key (read path) from a single disk ID.

Test

Test class: TestSlowDiskBlockLocations.java

Test Coverage

  • testSlowDiskDataNodeMovedToEnd
    Verifies that a slow disk DataNode is moved to the end of the replica location list.

  • testMultipleSlowDiskDataNodes
    Multiple slow disks across different DataNodes. Validates that normal DataNodes are prioritized and slow ones are deprioritized.

  • testAllSlowDiskDataNodes
    All DataNodes have slow disks. Verifies all replicas are still returned (no data loss).

  • testSlowDiskCacheRebuild
    Tests cache population after DataNode reports slow disk, and cache cleanup after disk recovery (expiration).

  • testSlowDiskExpiration
    Validates expiration of stale slow disk entries. Confirms cache is cleaned after disk recovery.

  • testCacheIntegrationWithReadPath
    End-to-end test: slow disk report → cache update → block location sorting. Verifies clients avoid slow replicas.

  • testIndependentCacheRebuildInterval
    Tests independent cache rebuild interval configuration. Verifies decoupling from Top-N report generation.


Test Configuration

  • DFS_HEARTBEAT_INTERVAL: 1s (fast heartbeat for testing)
  • DFS_NAMENODE_SLOW_DISK_CACHE_REBUILD_INTERVAL: 1s (quick cache rebuild)
  • DFS_DATANODE_OUTLIERS_REPORT_INTERVAL: 1s (rapid slow disk detection)
  • DFS_NAMENODE_DEPRIORITIZE_SLOW_DISK_DATANODE_FOR_READ: true (feature enabled)
  • Uses GenericTestUtils.waitFor() for async operations.

@hadoop-yetus

Copy link
Copy Markdown

💔 -1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 1m 26s 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 47m 57s trunk passed
+1 💚 compile 1m 44s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 1m 49s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 52s trunk passed
+1 💚 mvnsite 1m 57s trunk passed
+1 💚 javadoc 1m 27s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 1m 30s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 4m 21s trunk passed
+1 💚 shadedclient 37m 30s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 1m 24s the patch passed
+1 💚 compile 1m 16s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 1m 16s the patch passed
+1 💚 compile 1m 23s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 1m 23s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
+1 💚 checkstyle 1m 22s the patch passed
+1 💚 mvnsite 1m 28s the patch passed
+1 💚 javadoc 0m 59s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 1m 3s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 4m 2s the patch passed
+1 💚 shadedclient 37m 23s patch has no errors when building and testing our client artifacts.
_ Other Tests _
-1 ❌ unit 268m 26s /patch-unit-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 46s The patch does not generate ASF License warnings.
419m 7s
Reason Tests
Failed junit tests hadoop.hdfs.server.balancer.TestBalancerWithHANameNodes
Subsystem Report/Notes
Docker ClientAPI=1.55 ServerAPI=1.55 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8616/1/artifact/out/Dockerfile
GITHUB PR #8616
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux 5d0906acf927 5.15.0-177-generic #187-Ubuntu SMP Sat Apr 11 22:54:33 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / 911ba06
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-8616/1/testReport/
Max. process+thread count 2389 (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-8616/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.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@hadoop-yetus

Copy link
Copy Markdown

🎊 +1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 55s Docker mode activated.
_ Prechecks _
+1 💚 dupname 0m 1s 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 1 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 46m 51s trunk passed
+1 💚 compile 1m 44s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 1m 49s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 51s trunk passed
+1 💚 mvnsite 1m 56s trunk passed
+1 💚 javadoc 1m 27s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 1m 30s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 4m 24s trunk passed
+1 💚 shadedclient 37m 42s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 1m 24s the patch passed
+1 💚 compile 1m 16s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 1m 16s the patch passed
+1 💚 compile 1m 20s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 1m 20s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
+1 💚 checkstyle 1m 21s the patch passed
+1 💚 mvnsite 1m 28s the patch passed
+1 💚 javadoc 0m 59s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 1m 3s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 4m 2s the patch passed
+1 💚 shadedclient 37m 22s patch has no errors when building and testing our client artifacts.
_ Other Tests _
+1 💚 unit 268m 30s hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 48s The patch does not generate ASF License warnings.
417m 33s
Subsystem Report/Notes
Docker ClientAPI=1.55 ServerAPI=1.55 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8616/2/artifact/out/Dockerfile
GITHUB PR #8616
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux dcd510f0102d 5.15.0-177-generic #187-Ubuntu SMP Sat Apr 11 22:54:33 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / faf2a48
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-8616/2/testReport/
Max. process+thread count 2555 (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-8616/2/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.

@junjie1233

Copy link
Copy Markdown
Author

Hi @ZanderXu @KeeProMise @hfutatzhanghb, please take a look when you're free, 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