Skip to content

HDFS-17973. Add DataNode write-memory batching to improve write IO pattern throughput and latency - #8714

Open
rdhabalia wants to merge 1 commit into
apache:trunkfrom
rdhabalia:datanode-vertical-efficiency
Open

HDFS-17973. Add DataNode write-memory batching to improve write IO pattern throughput and latency#8714
rdhabalia wants to merge 1 commit into
apache:trunkfrom
rdhabalia:datanode-vertical-efficiency

Conversation

@rdhabalia

Copy link
Copy Markdown

Description of PR

HDFS blocks are processed as smaller packets. Concurrent writes across multiple blocks/files can interleave these packets, creating non-sequential disk I/O.

This is particularly expensive on HDDs, resulting in:

  • Small and fragmented writes
  • Higher IOPS and seek overhead
  • Page-cache pressure from dirty pages
  • Read/write contention
  • Higher read and write tail latency
  • Lower disk and DataNode throughput

Goal: Improve DataNode vertical efficiency and provide more predictable performance for mixed read/write workloads.


Proposed Solution

Introduce a DataNode-managed in-memory write buffer:

Small Packets
    |
    v
In-Memory Buffer
    |
    v
Large Batched Writes
    |
    v
 O_DIRECT
    |
    v
   Disk

Key Design

  1. Large write buffers
  • Accumulate small packets before flushing.
  • Reduce I/O operations and physical I/O fragmentation.
  • Improve sequential writes and disk bandwidth utilization.
  1. Direct I/O
  • Use O_DIRECT for buffered flushes.
  • Avoid dirty-page pressure and preserve OS page cache for reads and read-ahead.
  1. Controlled flush concurrency
  • Limit concurrent flush bytes per volume.
  • Balance disk parallelism, sequential I/O, and read latency.
  1. Last-replica-only mode
  • Optionally enable buffering only on the last DataNode in the replication pipeline.
  1. Bounded memory
  • Configurable limits for total buffer capacity, per-block buffer size, and flush concurrency.
  1. Idle flush
  • Flush partially filled buffers after a configurable timeout.

Read Path Benefit

By bypassing the OS page cache for DataNode writes, system memory can be used more effectively for:

  • Read cache
  • Read-ahead
  • Other filesystem activity

Expected benefits:

  • Lower read latency
  • Better read-ahead effectiveness
  • Reduced eviction of useful read pages
  • Less read/write contention
  • More stable mixed-workload performance

Key Configuration

Property Description
dfs.datanode.write.memory.buffer.enabled Enable write buffering
dfs.datanode.write.memory.buffer.last-replica-only Buffer only the last replica
dfs.datanode.write.memory.buffer.max.capacity.mb Maximum total buffer capacity
dfs.datanode.write.buffer.size.bytes Per-block buffer size
dfs.datanode.write.buffer.idle.flush.timeout.ms Idle flush timeout
dfs.datanode.concurrent.flush.mb.per.volume Maximum concurrent flush capacity per volume

The feature is disabled by default.


Implementation

The change introduces:

  • BufferedBlockWriter
  • BufferedBlockWriterImpl

Integrated with:

  • BlockReceiver
  • DataXceiver
  • FsVolumeImpl

When disabled, the existing DataNode write path remains unchanged.


Benchmark Results

Metric Improvement
Mixed 80/20 read/write throughput ~30% higher
Read-only throughput Up to ~45% higher
Large-block P99 write latency ~80% lower
Read latency during concurrent writes Significant reduction

Disk-level results also show:

  • r_await: Reduced from frequently >100 ms to consistently <50 ms
  • w_await: Reduced from frequently >200 ms to <90 ms
  • Per-disk throughput: Improved from ~120 MB/s to >170 MB/s under mixed workloads

Expected Impact

For I/O-bound workloads:

  • 25-40% higher throughput for write-heavy workloads
  • Up to ~45% higher throughput for read-heavy workloads
  • ~80% lower large-block P99 write latency
  • Lower read latency during concurrent writes
  • Reduced random I/O and disk contention
  • Better disk bandwidth utilization
  • More predictable mixed read/write performance

Actual gains depend on workload characteristics and storage hardware. CPU-, network-, or metadata-bound workloads are expected to see limited benefit.

Performance impact and IO Stats

IO stats for a single disk: Before the change, the disk achieved around 120 MBps for certain read-heavy workloads, but the throughput was bursty and inconsistent. After the change, the disk consistently achieved around 170 MBps, as shown in Image 1.
Image 2 compares the read_await time before and after the change. After the change, r_await consistently remains low, enabling higher and more stable read throughput compared to the previous results.

Read, Write, Total Throughput

Image

Read await_time and RPS

Image ---

Rollout

  • Disabled by default
  • Enable selectively for benchmarking and validation
  • Monitor throughput, disk utilization, IOPS, await, read latency, write P99, CPU, and memory
  • Validate sustained mixed read/write workloads before broad rollout
  • Tune buffer size and flush concurrency based on workload and storage characteristics

Recommended Kernel tuning with this change

The following kernel settings can complement the DataNode optimization:

Read-ahead and larger block-layer requests
 /sys/block/sd${disk}/queue/read_ahead_kb => >4096
/sys/block/sd${disk}/queue/max_sectors_kb => 4096

How was this patch tested?

Tested by newly added unit test

For code changes:

  • Does the title of this PR start with the corresponding JIRA issue id (e.g. 'HADOOP-17799. Your PR title ...')?
  • Object storage: Have the integration tests been executed and the endpoint
    declared according to the connector-specific documentation? Note: Automated CI
    testing doesn't cover all cases so manual testing with cloud storage is still
    required.
  • If adding new dependencies to the code, are these dependencies licensed in a way that is compatible for inclusion under ASF 2.0?
  • If applicable, have you updated the LICENSE, LICENSE-binary, NOTICE-binary files?

AI Tooling

If an AI tool was used:

@rdhabalia
rdhabalia force-pushed the datanode-vertical-efficiency branch 4 times, most recently from 43e2805 to e864967 Compare September 5, 2026 06:06
@hadoop-yetus

Copy link
Copy Markdown

💔 -1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 21s 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 4 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 26m 18s trunk passed
+1 💚 compile 0m 58s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 1m 0s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 6s trunk passed
+1 💚 mvnsite 1m 7s trunk passed
+1 💚 javadoc 0m 55s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 57s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 19s trunk passed
+1 💚 shadedclient 18m 22s branch has no errors when building and testing our client artifacts.
-0 ⚠️ patch 18m 39s Used diff version of patch file. Binary files and potentially other changes not applied. Please rebase and squash commits if necessary.
_ Patch Compile Tests _
+1 💚 mvninstall 0m 48s the patch passed
+1 💚 compile 0m 43s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 43s the patch passed
+1 💚 compile 0m 44s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 44s the patch passed
-1 ❌ blanks 0m 0s /blanks-eol.txt The patch has 7 line(s) that end in blanks. Use git apply --whitespace=fix <<patch_file>>. Refer https://git-scm.com/docs/git-apply
-0 ⚠️ checkstyle 0m 43s /results-checkstyle-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs-project/hadoop-hdfs: The patch generated 61 new + 417 unchanged - 0 fixed = 478 total (was 417)
+1 💚 mvnsite 0m 45s the patch passed
-1 ❌ javadoc 0m 35s /patch-javadoc-hadoop-hdfs-project_hadoop-hdfs-jdkUbuntu-21.0.11+10-1-24.04.2-Ubuntu.txt hadoop-hdfs in the patch failed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu.
-1 ❌ javadoc 0m 37s /patch-javadoc-hadoop-hdfs-project_hadoop-hdfs-jdkUbuntu-17.0.19+10-1-24.04.2-Ubuntu.txt hadoop-hdfs in the patch failed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu.
-1 ❌ spotbugs 2m 7s /new-spotbugs-hadoop-hdfs-project_hadoop-hdfs.html hadoop-hdfs-project/hadoop-hdfs generated 2 new + 0 unchanged - 0 fixed = 2 total (was 0)
+1 💚 shadedclient 17m 29s patch has no errors when building and testing our client artifacts.
_ Other Tests _
-1 ❌ unit 188m 21s /patch-unit-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 23s The patch does not generate ASF License warnings.
265m 54s
Reason Tests
SpotBugs module:hadoop-hdfs-project/hadoop-hdfs
Nullcheck of BlockReceiver.replicaInfo at line 302 of value previously dereferenced in new org.apache.hadoop.hdfs.server.datanode.BlockReceiver(ExtendedBlock, StorageType, DataInputStream, String, String, BlockConstructionStage, long, long, long, String, DatanodeInfo, DataNode, DataChecksum, CachingStrategy, boolean, boolean, String, boolean) At BlockReceiver.java:302 of value previously dereferenced in new org.apache.hadoop.hdfs.server.datanode.BlockReceiver(ExtendedBlock, StorageType, DataInputStream, String, String, BlockConstructionStage, long, long, long, String, DatanodeInfo, DataNode, DataChecksum, CachingStrategy, boolean, boolean, String, boolean) At BlockReceiver.java:[line 289]
Integral division result cast to double or float in org.apache.hadoop.hdfs.server.datanode.DataNode.initWriteBufferSemaphore(Configuration) At DataNode.java:double or float in org.apache.hadoop.hdfs.server.datanode.DataNode.initWriteBufferSemaphore(Configuration) At DataNode.java:[line 715]
Failed junit tests hadoop.hdfs.server.datanode.TestDataNodeLifeline
Subsystem Report/Notes
Docker ClientAPI=1.56 ServerAPI=1.56 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8714/2/artifact/out/Dockerfile
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux 37e76ebfb1e6 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / 706d4dc
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-8714/2/testReport/
Max. process+thread count 4271 (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-8714/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.

@hadoop-yetus

Copy link
Copy Markdown

💔 -1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 21s 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 4 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 26m 47s trunk passed
+1 💚 compile 0m 57s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 1m 2s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 9s trunk passed
+1 💚 mvnsite 1m 9s trunk passed
+1 💚 javadoc 0m 56s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 57s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 19s trunk passed
+1 💚 shadedclient 17m 17s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 0m 46s 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 44s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 44s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
-0 ⚠️ checkstyle 0m 44s /results-checkstyle-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs-project/hadoop-hdfs: The patch generated 61 new + 417 unchanged - 0 fixed = 478 total (was 417)
+1 💚 mvnsite 0m 49s the patch passed
+1 💚 javadoc 0m 36s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 38s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
-1 ❌ spotbugs 2m 3s /new-spotbugs-hadoop-hdfs-project_hadoop-hdfs.html hadoop-hdfs-project/hadoop-hdfs generated 2 new + 0 unchanged - 0 fixed = 2 total (was 0)
+1 💚 shadedclient 16m 44s patch has no errors when building and testing our client artifacts.
_ Other Tests _
+1 💚 unit 184m 51s hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 30s The patch does not generate ASF License warnings.
261m 24s
Reason Tests
SpotBugs module:hadoop-hdfs-project/hadoop-hdfs
Nullcheck of BlockReceiver.replicaInfo at line 302 of value previously dereferenced in new org.apache.hadoop.hdfs.server.datanode.BlockReceiver(ExtendedBlock, StorageType, DataInputStream, String, String, BlockConstructionStage, long, long, long, String, DatanodeInfo, DataNode, DataChecksum, CachingStrategy, boolean, boolean, String, boolean) At BlockReceiver.java:302 of value previously dereferenced in new org.apache.hadoop.hdfs.server.datanode.BlockReceiver(ExtendedBlock, StorageType, DataInputStream, String, String, BlockConstructionStage, long, long, long, String, DatanodeInfo, DataNode, DataChecksum, CachingStrategy, boolean, boolean, String, boolean) At BlockReceiver.java:[line 289]
Integral division result cast to double or float in org.apache.hadoop.hdfs.server.datanode.DataNode.initWriteBufferSemaphore(Configuration) At DataNode.java:double or float in org.apache.hadoop.hdfs.server.datanode.DataNode.initWriteBufferSemaphore(Configuration) At DataNode.java:[line 715]
Subsystem Report/Notes
Docker ClientAPI=1.56 ServerAPI=1.56 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8714/4/artifact/out/Dockerfile
GITHUB PR #8714
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux 0455c22a5256 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / 43e2805
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-8714/4/testReport/
Max. process+thread count 4190 (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-8714/4/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 4 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 31m 18s trunk passed
+1 💚 compile 0m 54s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 0m 56s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 0s trunk passed
+1 💚 mvnsite 1m 2s trunk passed
+1 💚 javadoc 0m 53s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 50s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 24s trunk passed
+1 💚 shadedclient 21m 45s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 0m 52s the patch passed
+1 💚 compile 0m 48s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 48s the patch passed
+1 💚 compile 0m 51s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 51s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
-0 ⚠️ checkstyle 0m 56s /results-checkstyle-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs-project/hadoop-hdfs: The patch generated 5 new + 417 unchanged - 0 fixed = 422 total (was 417)
+1 💚 mvnsite 0m 56s 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 36s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
-1 ❌ spotbugs 2m 25s /new-spotbugs-hadoop-hdfs-project_hadoop-hdfs.html hadoop-hdfs-project/hadoop-hdfs generated 2 new + 0 unchanged - 0 fixed = 2 total (was 0)
+1 💚 shadedclient 21m 49s patch has no errors when building and testing our client artifacts.
_ Other Tests _
+1 💚 unit 184m 14s hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 30s The patch does not generate ASF License warnings.
274m 54s
Reason Tests
SpotBugs module:hadoop-hdfs-project/hadoop-hdfs
Nullcheck of BlockReceiver.replicaInfo at line 302 of value previously dereferenced in new org.apache.hadoop.hdfs.server.datanode.BlockReceiver(ExtendedBlock, StorageType, DataInputStream, String, String, BlockConstructionStage, long, long, long, String, DatanodeInfo, DataNode, DataChecksum, CachingStrategy, boolean, boolean, String, boolean) At BlockReceiver.java:302 of value previously dereferenced in new org.apache.hadoop.hdfs.server.datanode.BlockReceiver(ExtendedBlock, StorageType, DataInputStream, String, String, BlockConstructionStage, long, long, long, String, DatanodeInfo, DataNode, DataChecksum, CachingStrategy, boolean, boolean, String, boolean) At BlockReceiver.java:[line 289]
Integral division result cast to double or float in org.apache.hadoop.hdfs.server.datanode.DataNode.initWriteBufferSemaphore(Configuration) At DataNode.java:double or float in org.apache.hadoop.hdfs.server.datanode.DataNode.initWriteBufferSemaphore(Configuration) At DataNode.java:[line 715]
Subsystem Report/Notes
Docker ClientAPI=1.56 ServerAPI=1.56 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8714/5/artifact/out/Dockerfile
GITHUB PR #8714
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux 721818beaf48 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / e864967
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-8714/5/testReport/
Max. process+thread count 4177 (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-8714/5/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.

@rdhabalia
rdhabalia force-pushed the datanode-vertical-efficiency branch from e864967 to b6ce6e3 Compare September 6, 2026 06:53
@hadoop-yetus

Copy link
Copy Markdown

💔 -1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 21s 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 4 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 25m 36s trunk passed
+1 💚 compile 0m 58s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 compile 0m 58s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 checkstyle 1m 5s trunk passed
+1 💚 mvnsite 1m 5s trunk passed
+1 💚 javadoc 0m 54s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 54s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 18s trunk passed
+1 💚 shadedclient 17m 19s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 0m 48s the patch passed
+1 💚 compile 0m 45s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 45s the patch passed
+1 💚 compile 0m 44s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 44s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
-0 ⚠️ checkstyle 0m 42s /results-checkstyle-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs-project/hadoop-hdfs: The patch generated 5 new + 417 unchanged - 0 fixed = 422 total (was 417)
+1 💚 mvnsite 0m 47s 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 38s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 6s the patch passed
+1 💚 shadedclient 16m 35s patch has no errors when building and testing our client artifacts.
_ Other Tests _
-1 ❌ unit 184m 49s /patch-unit-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 30s The patch does not generate ASF License warnings.
259m 42s
Reason Tests
Failed junit tests hadoop.hdfs.server.balancer.TestBalancerWithHANameNodes
Subsystem Report/Notes
Docker ClientAPI=1.56 ServerAPI=1.56 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8714/6/artifact/out/Dockerfile
GITHUB PR #8714
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux 6badb0be5522 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / b6ce6e3
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-8714/6/testReport/
Max. process+thread count 4274 (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-8714/6/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.

…, throughput and latency

Motivation
----------
On write-heavy clusters the DataNode receives each packet and writes it
straight to the block file. For workloads that issue many small and/or
random writes, this produces a large number of small, scattered disk
writes and pollutes the OS page cache, which in turn hurts concurrent
read latency on the same volumes. Under mixed read/write load the small
write pattern drives high tail latencies and caps aggregate node
throughput well below the underlying disk capability.

This change adds an opt-in, per-replica write-memory buffer on the
DataNode that batches incoming packet data in memory and flushes it to
the block file in large, sequential chunks. Coalescing writes turns many
small IOs into fewer large sequential IOs, reduces page-cache churn, and
significantly improves both write throughput and concurrent read
latency.

Approach
--------
- BufferedBlockWriter (new interface) + BufferedBlockWriterImpl (new)
  accumulate a replica's incoming data in a pooled, size-bounded memory
  buffer and flush it to disk in large sequential writes. The buffer is
  created only for a brand-new RBW replica (recovery/append paths use
  the existing direct-write path).
- BlockReceiver routes packet payloads through the buffer when enabled
  (buffer.writeData) and otherwise falls back to the direct
  streams.writeDataToDisk path. A full buffer is flushed automatically;
  hsync and close drain and fsync the buffer. fsync failures on
  hsync/close propagate to the caller so bytes are never falsely
  acknowledged as durable.
- Read-visibility consistency: because un-synced packet data may still
  reside in the in-memory buffer, the RBW replica's visible (acked)
  length is never advanced past the bytes actually flushed to the block
  file. This guarantees a concurrent reader (BlockSender, short-circuit,
  replica-pinned) can never read past the physical end of the file.
  Buffered-but-unflushed bytes become visible on the next flush (buffer
  full, idle-flush timer, hsync, or close). This slightly relaxes the
  immediacy of hflush visibility in exchange for the batched-write IO
  pattern; the tradeoff is only taken when the feature is explicitly
  enabled.
- A per-DataNode Semaphore bounds the number of concurrent large flushes
  across volumes so buffered flushing does not overwhelm the disks; the
  concurrency is derived from a configurable per-volume MB budget.
- A periodic idle-flush timer flushes a replica's buffered data if no
  packet is received for a configurable interval, bounding how long data
  may sit only in memory for slow/idle writers.
- On upstream failure / thread interruption the buffer is flushed to
  disk before the receiver thread exits so already-received data is not
  lost.
- The per-DataNode memory-cap permit is acquired BEFORE the off-heap
  buffer is allocated (so concurrent writers block instead of each
  allocating and overshooting the cap), and pooled buffers / permits are
  released on any construction failure to avoid leaks.
- A safe-rollout gate ("last-replica-only", default true) restricts the
  buffered path to the terminal DataNode in the write pipeline; set to
  false to enable it on every replica.
- Read side: an optional read-ahead-cache threshold and drop-cache
  behind reads reduce page-cache pressure from large sequential reads
  competing with buffered writes.

Configuration (all DataNode-side; feature disabled by default)
--------------------------------------------------------------
  dfs.datanode.write.memory.buffer.enabled            (default false)
  dfs.datanode.write.memory.buffer.last-replica-only  (default true)
  dfs.datanode.write.memory.buffer.max.capacity.mb
  dfs.datanode.write.memory.buffer.min.volumes
  dfs.datanode.write.buffer.size.bytes
  dfs.datanode.write.buffer.idle.flush.timeout.ms
  dfs.datanode.concurrent.flush.mb.per.volume
  dfs.datanode.read.ahead.cache.bytes.threshold

Results
-------
On a mixed 80/20 read/write benchmark aggregate node throughput improved
by 30%+ (~2.9 GB/s -> ~3.8 GB/s; ~4.2 GB/s read-only), P50 read transfer
rose above 150 MB/s, read await dropped below ~50 ms, and 128 MB-block
P99 write latency fell from ~22s to ~4s. The feature is off by default
and has no effect on the write/read path until enabled.
@rdhabalia
rdhabalia force-pushed the datanode-vertical-efficiency branch from b6ce6e3 to b70fb16 Compare September 6, 2026 13:56
@hadoop-yetus

Copy link
Copy Markdown

🎊 +1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 21s 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 4 new or modified test files.
_ trunk Compile Tests _
+1 💚 mvninstall 26m 4s 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 0s trunk passed
+1 💚 mvnsite 1m 5s trunk passed
+1 💚 javadoc 0m 55s trunk passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 57s trunk passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 2m 20s trunk passed
+1 💚 shadedclient 17m 37s branch has no errors when building and testing our client artifacts.
_ Patch Compile Tests _
+1 💚 mvninstall 0m 45s the patch passed
+1 💚 compile 0m 44s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javac 0m 44s 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 43s /results-checkstyle-hadoop-hdfs-project_hadoop-hdfs.txt hadoop-hdfs-project/hadoop-hdfs: The patch generated 5 new + 417 unchanged - 0 fixed = 422 total (was 417)
+1 💚 mvnsite 0m 54s the patch passed
+1 💚 javadoc 0m 33s the patch passed with JDK Ubuntu-21.0.11+10-1-24.04.2-Ubuntu
+1 💚 javadoc 0m 36s the patch passed with JDK Ubuntu-17.0.19+10-1-24.04.2-Ubuntu
+1 💚 spotbugs 1m 59s the patch passed
+1 💚 shadedclient 16m 26s patch has no errors when building and testing our client artifacts.
_ Other Tests _
+1 💚 unit 184m 17s hadoop-hdfs in the patch passed.
+1 💚 asflicense 0m 30s The patch does not generate ASF License warnings.
259m 53s
Subsystem Report/Notes
Docker ClientAPI=1.56 ServerAPI=1.56 base: https://ci-hadoop.apache.org/job/hadoop-multibranch/job/PR-8714/7/artifact/out/Dockerfile
GITHUB PR #8714
Optional Tests dupname asflicense compile javac javadoc mvninstall mvnsite unit shadedclient spotbugs checkstyle codespell detsecrets xmllint
uname Linux 5b1fd5332a98 5.15.0-190-generic #200-Ubuntu SMP Fri Aug 7 15:06:04 UTC 2026 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/bin/hadoop.sh
git revision trunk / b70fb16
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-8714/7/testReport/
Max. process+thread count 4410 (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-8714/7/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.

@rdhabalia

Copy link
Copy Markdown
Author

@tomscut @virajjasani when you get a chance, could you please help review this? It adds opt-in DataNode write-memory batching to improve write throughput and latency. CI is green (+1 overall). 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.

2 participants