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

Andrey Yarovoy reassigned HDDS-17034:
-------------------------------------

    Assignee: Andrey Yarovoy

> Send an EC stripe's cells to their datanodes in parallel instead of serially 
> on one flush thread
> ------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-17034
>                 URL: https://issues.apache.org/jira/browse/HDDS-17034
>             Project: Apache Ozone
>          Issue Type: Improvement
>          Components: EC Client
>            Reporter: Andrey Yarovoy
>            Assignee: Andrey Yarovoy
>            Priority: Major
>
> **Problem**
> For each stripe, a single flush thread per key 
> (`ECKeyOutputStream.flushStripeToDatanodes` → `writeDataCells` /
> `writeParityCells`) processes the d+p cells one after another. For each cell 
> it:
> 1. computes the chunk checksum
> 2. builds the `WriteChunk` request
> 3. hands it to gRPC (`XceiverClientGrpc.sendCommandAsync`)
> That third step copies the 1 MB cell into gRPC's frame buffer 
> (`MessageFramer.writeRaw`). grpc-java's send path
> always copies the message into its own buffers, so this copy cannot be 
> removed on the client, only taken off the
> critical path.
> **Evidence** (single rs-3-2-1024k writer on the TLS cluster, flush-thread 
> busy time)
> | Activity | Share |
> |---|---|
> | WriteChunk serialization | 15.1% |
> | CRC (1 MB checksum unit) | 4.0% |
> | send | 2.2% |
> In total, about 21% of the flush thread's busy time is per-cell CPU work done 
> serially.
> - 87% of the serialization samples are the payload memcpy in 
> `MessageFramer.writeRaw` (`jbyte_disjoint_arraycopy`).
> - With the default 16 KB checksum unit, the CRC share is larger: 16% of flush 
> time in the mini-cluster profile.
> **Proposal**
> Dispatch each cell's checksum, request build and send on a per-stream 
> executor, so the d+p cells of a stripe are
> prepared concurrently. The existing barrier stays: the stripe still completes 
> when all WriteChunks are
> acknowledged. Per-datanode order is unchanged, because each datanode gets one 
> cell per stripe.
> - Executor size: bounded per client, shared across streams, to avoid thread 
> explosion with many writers.
> - The flush thread keeps orchestrating: it waits for all cells to be sent and 
> acknowledged, then sends PutBlock as
> today.
> **Projected effect**
> Removes most of the ~21% per-cell work from the flush thread's critical path 
> for one writer. 
> **Compatibility**
> Client-only. No wire, format or configuration change, except an optional 
> executor-size setting.
> **Testing**
> - `TestECKeyOutputStream` and the failure-handling tests (a datanode failing 
> mid-stripe must still exclude the
> datanode and rewrite the stripe).
> - A test that checksums and chunk metadata are identical to today's.
> - Before and after: freon at 1 thread. Benefit is expected only when the 
> flush thread is the bottleneck.



--
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