[ 
https://issues.apache.org/jira/browse/HDDS-17399?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Chu Cheng Li updated HDDS-17399:
--------------------------------
    Description: 
h3. Problem
* {{BlockInputStream.readPositioned}} and 
{{StreamBlockInputStream.readPositioned}} take the stream lock on each call.
* The sequential read of each class keeps the same lock while it waits for the 
datanode.
* Thus a positioned read waits for a sequential read in progress on the same 
block.

h3. Changes
After the one-time setup of a block stream, a positioned read takes no lock.
* {{BlockInputStream}}: after the volatile {{initialized}} is true, read 
{{chunkOffsets}}, {{chunkStreams}} and {{length}} without the lock. 
{{initialize()}} sets them first, and nothing changes them after that.
* {{StreamBlockInputStream}}: make {{needUpdateBlockLength}} volatile, and call 
{{updateBlockLength()}} only while it is set. Make {{xceiverClientFactory}} 
final.
* The block streams do not check that they are open. {{MultipartInputStream}}, 
their only caller, checks its volatile {{closed}} flag first.
* Sequential reads do not change.

h3. Tests
* For both classes, a positioned read completes while a sequential read on the 
same block holds the lock. Without the change, it times out.
* After {{close()}}, a positioned read fails and does not reach the block 
stream.

h3. Benchmark
{{ozone freon ocpr}} (HDDS-17433) on one host: 3 datanodes on one NVMe, warm 
page cache, a 256 MiB key (one block). All positioned-read threads share one 
stream with 1 sequential reader of 1 MiB reads. Each run takes 20 s. Each value 
is the median of 3 runs.
{noformat}
ozone freon ocpr -v vol1 -b bucket1 -k key1 -t 8 --read-size 65536 
--sequential-readers 1 --duration 20s
{noformat}
The stream rows add {{\-D ozone.client.stream.readblock.enable=true}} before 
{{ocpr}}.
||Read path||Positioned reads||Before (ops/s, p50, p99)||After (ops/s, p50, 
p99)||
|Chunk (default)|1 thread x 64 KiB|63, 4.0 ms, 267 ms|1,488, 0.45 ms, 1.6 ms|
|Chunk (default)|8 threads x 64 KiB|83, 41 ms, 908 ms|6,762, 0.89 ms, 2.4 ms|
|Stream ({{ozone.client.stream.readblock.enable}})|1 thread x 64 KiB|22, 9.2 
ms, 459 ms|463, 1.8 ms, 5.4 ms|
|Stream ({{ozone.client.stream.readblock.enable}})|8 threads x 64 KiB|51, 44 
ms, 1.17 s|1,975, 3.5 ms, 18.8 ms|
* Without the change, longer runs give lower rates. Stream, 1 thread: 24 ops/s 
in 20 s, 12 ops/s in 60 s.
* With positioned reads only (1 to 32 threads), throughput does not change 
beyond run-to-run noise (about ±10%).
* The sequential reader alone has the same speed with and without the change. 
Next to 8 positioned-read threads on the stream path, it is about 5% slower 
(median of 9 pairs). The positioned reads now run on the same datanode and do 
not wait. Thus the total bytes read increase by about 11%.

Follow-up to HDDS-16983 and HDDS-16395.

  was:
h3. Problem
* {{BlockInputStream.readPositioned}} and 
{{StreamBlockInputStream.readPositioned}} take the stream lock on each call.
* The sequential read of each class keeps the same lock while it waits for the 
datanode.
* Thus a positioned read waits for a sequential read in progress on the same 
block.

h3. Changes
After the one-time setup of a block stream, a positioned read takes no lock.
* {{BlockInputStream}}: after the volatile {{initialized}} is true, read 
{{chunkOffsets}}, {{chunkStreams}} and {{length}} without the lock. 
{{initialize()}} sets them first, and nothing changes them after that.
* {{StreamBlockInputStream}}: make {{needUpdateBlockLength}} volatile, and call 
{{updateBlockLength()}} only while it is set. Make {{xceiverClientFactory}} 
final.
* The block streams do not check that they are open. {{MultipartInputStream}}, 
their only caller, checks its volatile {{closed}} flag first.
* Sequential reads do not change.

h3. Tests
* For both classes, a positioned read completes while a sequential read on the 
same block holds the lock. Without the change, it times out.
* After {{close()}}, a positioned read fails and does not reach the block 
stream.

h3. Benchmark
One host, 3 datanodes, warm page cache. One shared stream on a 256 MiB key: 1 
sequential reader and N positioned-read threads. Median of 3 runs.
||Read path||Positioned reads||Before (ops/s, p50, p99)||After (ops/s, p50, 
p99)||
|Chunk (default)|1 thread x 64 KiB|2, 680 ms, 1.55 s|1,811, 0.41 ms, 1.36 ms|
|Chunk (default)|8 threads x 64 KiB|9, 721 ms, 4.89 s|7,398, 0.78 ms, 2.04 ms|
|Stream ({{ozone.client.stream.readblock.enable}})|1 thread x 64 KiB|3, 309 ms, 
641 ms|586, 1.3 ms, 5.6 ms|
|Stream ({{ozone.client.stream.readblock.enable}})|8 threads x 64 KiB|10, 653 
ms, 3.56 s|2,060, 3.3 ms, 9.4 ms|
* With positioned reads only (1 to 32 threads), throughput does not change 
beyond run-to-run noise (about ±10%).

Follow-up to HDDS-16983 and HDDS-16395.


> Make positioned reads lock-free after initialization in BlockInputStream and 
> StreamBlockInputStream
> ---------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-17399
>                 URL: https://issues.apache.org/jira/browse/HDDS-17399
>             Project: Apache Ozone
>          Issue Type: Improvement
>          Components: Ozone Client
>            Reporter: Chu Cheng Li
>            Assignee: Chu Cheng Li
>            Priority: Major
>              Labels: pull-request-available
>
> h3. Problem
> * {{BlockInputStream.readPositioned}} and 
> {{StreamBlockInputStream.readPositioned}} take the stream lock on each call.
> * The sequential read of each class keeps the same lock while it waits for 
> the datanode.
> * Thus a positioned read waits for a sequential read in progress on the same 
> block.
> h3. Changes
> After the one-time setup of a block stream, a positioned read takes no lock.
> * {{BlockInputStream}}: after the volatile {{initialized}} is true, read 
> {{chunkOffsets}}, {{chunkStreams}} and {{length}} without the lock. 
> {{initialize()}} sets them first, and nothing changes them after that.
> * {{StreamBlockInputStream}}: make {{needUpdateBlockLength}} volatile, and 
> call {{updateBlockLength()}} only while it is set. Make 
> {{xceiverClientFactory}} final.
> * The block streams do not check that they are open. 
> {{MultipartInputStream}}, their only caller, checks its volatile {{closed}} 
> flag first.
> * Sequential reads do not change.
> h3. Tests
> * For both classes, a positioned read completes while a sequential read on 
> the same block holds the lock. Without the change, it times out.
> * After {{close()}}, a positioned read fails and does not reach the block 
> stream.
> h3. Benchmark
> {{ozone freon ocpr}} (HDDS-17433) on one host: 3 datanodes on one NVMe, warm 
> page cache, a 256 MiB key (one block). All positioned-read threads share one 
> stream with 1 sequential reader of 1 MiB reads. Each run takes 20 s. Each 
> value is the median of 3 runs.
> {noformat}
> ozone freon ocpr -v vol1 -b bucket1 -k key1 -t 8 --read-size 65536 
> --sequential-readers 1 --duration 20s
> {noformat}
> The stream rows add {{\-D ozone.client.stream.readblock.enable=true}} before 
> {{ocpr}}.
> ||Read path||Positioned reads||Before (ops/s, p50, p99)||After (ops/s, p50, 
> p99)||
> |Chunk (default)|1 thread x 64 KiB|63, 4.0 ms, 267 ms|1,488, 0.45 ms, 1.6 ms|
> |Chunk (default)|8 threads x 64 KiB|83, 41 ms, 908 ms|6,762, 0.89 ms, 2.4 ms|
> |Stream ({{ozone.client.stream.readblock.enable}})|1 thread x 64 KiB|22, 9.2 
> ms, 459 ms|463, 1.8 ms, 5.4 ms|
> |Stream ({{ozone.client.stream.readblock.enable}})|8 threads x 64 KiB|51, 44 
> ms, 1.17 s|1,975, 3.5 ms, 18.8 ms|
> * Without the change, longer runs give lower rates. Stream, 1 thread: 24 
> ops/s in 20 s, 12 ops/s in 60 s.
> * With positioned reads only (1 to 32 threads), throughput does not change 
> beyond run-to-run noise (about ±10%).
> * The sequential reader alone has the same speed with and without the change. 
> Next to 8 positioned-read threads on the stream path, it is about 5% slower 
> (median of 9 pairs). The positioned reads now run on the same datanode and do 
> not wait. Thus the total bytes read increase by about 11%.
> Follow-up to HDDS-16983 and HDDS-16395.



--
This message was sent by Atlassian Jira
(v10.3.26#10030026)

---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to