Skip to content

HDDS-13660. Ozone client support readVectored.#9402

Closed
ashishkumar50 wants to merge 6 commits into
apache:masterfrom
ashishkumar50:testvector
Closed

HDDS-13660. Ozone client support readVectored.#9402
ashishkumar50 wants to merge 6 commits into
apache:masterfrom
ashishkumar50:testvector

Conversation

@ashishkumar50

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Ozone client support readVectored which allows reading multiple file ranges in parallel.

What is the link to the Apache JIRA

https://issues.apache.org/jira/browse/HDDS-13660

How was this patch tested?

Tests are added

@jojochuang

Copy link
Copy Markdown
Contributor

@yandrey321

@jojochuang
jojochuang self-requested a review December 1, 2025 17:19
@adoroszlai

adoroszlai commented Dec 3, 2025

Copy link
Copy Markdown
Contributor

Thanks @ashishkumar50 for the patch. I have ported the corresponding contract test from Hadoop, which shows that some input validation is missing (negative length and offset, overlapping ranges, same ranges).

Please feel free to pick it from adoroszlai@ee11cf3 and include in this PR.

https://github.com/adoroszlai/ozone/actions/runs/19905480757/job/57061761264#step:13:5599

adoroszlai and others added 2 commits December 4, 2025 18:07
@ashishkumar50

Copy link
Copy Markdown
Contributor Author

@adoroszlai Thanks for the review, handled comments.

(offset, buffer) -> readRangeData(offset, buffer, initialPosition));
} finally {
// Restore position
synchronized (this) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would happen in case of concurrent readVectored() calls?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Synchronized now to avoid race condition in same concurrent stream reads.

});
} finally {
// Restore position
synchronized (this) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would happen in case of concurrent readVectored() calls?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Synchronized now to avoid race condition in same concurrent stream reads.

@chungen0126
chungen0126 self-requested a review December 5, 2025 07:26
@adoroszlai

Copy link
Copy Markdown
Contributor

@chungen0126 @jojochuang @yandrey321 please take a look

@chungen0126 chungen0126 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for @ashishkumar50 the patch. Are there plans to optimize read vector further? The current implementation doesn't seem to fully support fully parallel reading for different ranges yet. I also added some comments.

);

// Restore position
seek(initialPosition);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if the seek to initialPosition is necessary here? Since the offset changes asynchronously, restoring it at this point might not work correctly. It seems like readRangeData already handles the position restoration correctly.

);

// Restore position before returning from method
seek(initialPosition);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as above.

@github-actions

github-actions Bot commented Feb 6, 2026

Copy link
Copy Markdown

This PR has been marked as stale due to 21 days of inactivity. Please comment or remove the stale label to keep it open. Otherwise, it will be automatically closed in 7 days.

@github-actions github-actions Bot added the stale label Feb 6, 2026
@adoroszlai

Copy link
Copy Markdown
Contributor

@ashishkumar50 please take a look at @chungen0126's comments.

@yandrey321 yandrey321 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These changes add a lot of synchronization on IO path, is there a write up that justify these changes? Are there any performance benchmark results that measure performance impact of these changes?

* @apiNote This method is synchronized to prevent race conditions from
* concurrent readVectored() calls on the same stream instance.
*/
public synchronized void readVectored(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it need to be syncronized?

*/
private void readRangeData(long offset, ByteBuffer buffer, long initialPosition)
throws IOException {
synchronized (this) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is there a reason for not allowing concurrent reads?

*/
@Override
public int read(long position, ByteBuffer buf) throws IOException {
public synchronized int read(long position, ByteBuffer buf) throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the reason for adding syncrhonized here?

*/
@Override
public void readFully(long position, ByteBuffer buf) throws IOException {
public synchronized void readFully(long position, ByteBuffer buf) throws IOException {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is the reason for adding syncrhonized here?

* concurrent readVectored() calls on the same stream instance.
*/
@Override
public synchronized void readVectored(List<? extends FileRange> ranges,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

does it need to be synchronized?

@github-actions github-actions Bot removed the stale label Feb 10, 2026
@github-actions

github-actions Bot commented Mar 4, 2026

Copy link
Copy Markdown

This PR has been marked as stale due to 21 days of inactivity. Please comment or remove the stale label to keep it open. Otherwise, it will be automatically closed in 7 days.

@github-actions github-actions Bot added the stale label Mar 4, 2026
@github-actions

Copy link
Copy Markdown

Thank you for your contribution. This PR is being closed due to inactivity. Please contact a maintainer if you would like to reopen it.

@github-actions github-actions Bot closed this Mar 12, 2026
@chungen0126

Copy link
Copy Markdown
Contributor

Hi @ashishkumar50 @yandrey321 @adoroszlai @jojochuang , just checking in to see if this PR is still active?

I’ve been looking into readVectored lately. To optimize it further, I think BlockInputStream and BlockStreamInputStream should implement ByteBufferPositionedReadable to reduce lock contention between inputstreams.

I'm planning to create two subtasks to track BlockInputStream and StreamBlockInputStream separately. Let me know if you have any thoughts or feedback on this!

@adoroszlai

Copy link
Copy Markdown
Contributor

Thanks @chungen0126 for checking. I guess this was dropped due to lack of time. It would be great if you could continue work on readVectored support.

@chungen0126

Copy link
Copy Markdown
Contributor

Hi all,

I've submitted a PR to implement positional reads in BlockInputStream. Please take a look and review it when you are available.

Along with the implementation, I've written a microbenchmark for readVectored on this branch to verify the performance gains on the client side from reducing lock contention.

Benchmark Setup:

Platform: Local macOS
File Configuration:
FILE_SIZE = 100 * 1024 * 1024 (100 MB)
BLOCK_SIZE = 20 * 1024 * 1024 (20 MB / 5 blocks total)
CHUNK_SIZE = 4 * 1024 * 1024 (4 MB / 5 chunks per block)

Test Scenarios:

Consecutive range pattern: 20 ranges, 1 MB each
Random range pattern: 20 ranges, 1 MB each, spread randomly
Sparse range pattern: 5 ranges, 128 KB each, widely separated

Results:

Plaintext
--- Pattern: Consecutive Ranges ---
Vectored Read (Positional Enabled=true) : Mean: 90.54 ms | Min: 42.02 ms | Max: 146.75 ms | Throughput: 220.89 MB/s
Vectored Read (Positional Enabled=false) : Mean: 97.63 ms | Min: 48.74 ms | Max: 175.95 ms | Throughput: 204.86 MB/s

--- Pattern: Random Ranges ---
Number of ranges: 4
Total read size : 4.00 MB
Vectored Read (Positional Enabled=true) : Mean: 59.60 ms | Min: 36.05 ms | Max: 74.04 ms | Throughput: 67.12 MB/s
Vectored Read (Positional Enabled=false) : Mean: 120.47 ms | Min: 96.82 ms | Max: 150.69 ms | Throughput: 33.20 MB/s

--- Pattern: Sparse Ranges ---
Number of ranges: 5
Total read size : 0.63 MB
Vectored Read (Positional Enabled=true) : Mean: 164.00 ms | Min: 96.81 ms | Max: 245.98 ms | Throughput: 3.81 MB/s
Vectored Read (Positional Enabled=false) : Mean: 164.61 ms | Min: 101.27 ms | Max: 240.58 ms | Throughput: 3.80 MB/s

Current Progress & Next Steps:

Currently, this branch only implements positional read for general reads. While working on BlockStreamRead, I ran into a few bugs. Therefore, I will follow up with another PR to implement positional read for BlockStreamRead later.

@yandrey321

Copy link
Copy Markdown
Contributor

Hi @ashishkumar50 @yandrey321 @adoroszlai @jojochuang , just checking in to see if this PR is still active?

I’ve been looking into readVectored lately. To optimize it further, I think BlockInputStream and BlockStreamInputStream should implement ByteBufferPositionedReadable to reduce lock contention between inputstreams.

I'm planning to create two subtasks to track BlockInputStream and StreamBlockInputStream separately. Let me know if you have any thoughts or feedback on this!

We also need to evaluate how it would work with read streaming, I can pick one some of these tasks.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants