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

Andrey Yarovoy reassigned HDDS-17033:
-------------------------------------

    Assignee: Andrey Yarovoy

> Stop taking EC stripe buffers from the shared client buffer pool on every 
> stripe
> --------------------------------------------------------------------------------
>
>                 Key: HDDS-17033
>                 URL: https://issues.apache.org/jira/browse/HDDS-17033
>             Project: Apache Ozone
>          Issue Type: Improvement
>          Components: EC Client
>            Reporter: Andrey Yarovoy
>            Assignee: Andrey Yarovoy
>            Priority: Major
>
> **Problem**
> `ECKeyOutputStream` creates a new `ECChunkBuffers` for every stripe 
> (`ECKeyOutputStream.handleWrite`, after
> `addStripeToQueue`). Each one takes d+p cell buffers from the client's 
> `BoundedElasticByteBufferPool`
> (`ECChunkBuffers.allocateBuffers`). After sending the stripe, the flush 
> thread returns them
> (`flushStripeFromQueue` → `ECChunkBuffers.release` → `putBuffer`).
> There is one pool per `RpcClient`, so all writers in a client JVM share it. 
> Its `getBuffer` and `putBuffer` are
> `synchronized` over a `TreeMap`. With many concurrent EC writers in one 
> client, which is typical for S3 Gateway and
> multi-threaded applications, every stripe takes the same lock 2×(d+p) times.
> **Evidence** (16 concurrent rs-3-2-1024k writers, one client)
> - Writer threads spend about 30% of their time blocked on the pool monitor in 
> `getBuffer`. Another ~6% goes to
> `ByteBuffer.allocate` of new 1 MB heap buffers on pool misses.
> - Flush threads spend about 34% of their busy time blocked on the pool 
> monitor in `putBuffer`.
> - Throughput is 4,270 MB/s, 47% of linear scaling from one writer (566 MB/s). 
> Key p50 doubles, from 437 ms at 1
> and 4 writers to 850 ms at 16.
> - RATIS/THREE reaches 5,477 MB/s on the same client.
> - The client is neither CPU-bound (64% idle) nor NIC-bound (7.2 GB/s of about 
> 25 GB/s).
> **Proposal**
> Reuse stripe buffer sets inside each `ECKeyOutputStream`:
> - Keep a small per-stream free list of `ECChunkBuffers`, bounded by the 
> stripe queue size plus the stripe being
> filled and the one being flushed.
> - The flush thread clears a sent stripe and returns it to the stream's free 
> list instead of to the shared pool.
> - The writer takes the next stripe from the free list, and falls back to the 
> shared pool only when the list is
> empty.
> - On close or failure, all buffers go back to the shared pool.
> As a result, the shared pool is used about once per stream instead of 2×(d+p) 
> times per stripe.
> Peak memory per stream doesn't change: the same number of stripe sets are in 
> use as today. The HDDS-13400 bound
> on the shared pool keeps its meaning.
> Reused buffers must be fully reset, with position and limit restored and 
> padding regions zeroed. A partial last
> stripe relies on zero padding for parity (`padBufferToLimit`).
> **Alternatives considered**
> Making `BoundedElasticByteBufferPool` concurrent, for example striped or 
> using a concurrent sorted map. That change
> is broader, because the class is shared by other users, and it still costs 
> two pool operations per cell per stripe.
> Per-stream reuse is local to the EC write path.
> **Compatibility**
> Client-only. No wire, format or configuration change.
> **Testing**
> - Existing `TestECKeyOutputStream` and `TestOzoneECClient`.
> - New unit tests: stripe buffers are reused and returned to the pool on close 
> and on failure; a partial last
> stripe after reuse produces correct parity (read back and compare).
> - Before and after: freon ockg rs-3-2 / rs-6-3 at 1, 4 and 16 threads on one 
> client. Expect 16-thread throughput
> up roughly 1.3–1.45x (removing the ~30% blocking), and 1-thread throughput 
> unchanged.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

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

Reply via email to