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

Siyao Meng updated HDDS-17445:
------------------------------
    Affects Version/s: 2.3.0

> Short-circuit GetBlock parks the opened block file in a map shared by all 
> requests instead of handing it to the request's own context
> -------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HDDS-17445
>                 URL: https://issues.apache.org/jira/browse/HDDS-17445
>             Project: Apache Ozone
>          Issue Type: Bug
>    Affects Versions: 2.3.0
>            Reporter: Siyao Meng
>            Priority: Major
>         Attachments: MC-3-hand-short-circuit-block-file-to-own-request.patch
>
>
> h3. Mechanism
> For a GetBlock with {{requestShortCircuitAccess}} set, 
> {{KeyValueHandler.handleGetBlock}} opens the block file 
> ({{ChunkManager.getShortCircuitFd}}), parks the {{RandomAccessFile}} in 
> {{blockFileMap}} under {{BlockUtils.getBlockMapKey}} ({{clientId}}, 
> {{callId}}, local ID, container ID) and sets {{shortCircuitAccessGranted}} in 
> the response. The handler does this for any GetBlock that carries the flag, 
> because it does not know which path dispatched the request, and the map is 
> shared by all requests. Only the domain socket {{Receiver}} takes the file 
> out again, through {{Handler.getBlockFile}} after dispatch, and closes it 
> after sending the descriptor (HDDS-11627, HDDS-12883).
> So the hand off between the handler and {{Receiver}} depends on a lookup by 
> request fields rather than on the request itself:
> * A GetBlock with the flag dispatched by another path 
> ({{GrpcXceiverService}}, {{ContainerStateMachine.query}}) parks a file that 
> nothing takes out, and its response reports 
> {{shortCircuitAccessGranted=true}} although that path does not pass a 
> descriptor.
> * Requests with the same key use the same entry: a later put replaces an 
> earlier file without closing it, and the {{Receiver}} task that looks second 
> finds no entry.
> A file that is parked and never taken out stays open while the map holds it, 
> and a file replaced by a later put is closed only when it is collected.
> h3. Reproduction
> No standalone reproduction is attached. The regression test in the patch 
> covers both cases at the handler level.
> h3. Patch
> [^MC-3-hand-short-circuit-block-file-to-own-request.patch], against 
> 69d77beff60b9106e2517c36a7a1b2cc726af568. It also applies to master at 
> 1acf315d546.
> The opened file is handed to the request's own context instead of a shared 
> map, and the flag is ignored on every other path. {{Receiver}} dispatches 
> each request with its own {{DispatcherContext}} of the new op 
> {{HANDLE_SHORT_CIRCUIT_READ}}; {{handleGetBlock}} opens the file only when it 
> gets such a context, stores it there, and {{Receiver}} takes it from that 
> context. A GetBlock with the flag dispatched without that context gets the 
> block data and {{shortCircuitAccessGranted=false}}, which the read path 
> already treats as "read normally". {{blockFileMap}}, 
> {{KeyValueHandler.getBlockFile}} and the abstract {{Handler.getBlockFile}} 
> are removed. The block token is still verified for the new op 
> ({{Op.validateToken}} defaults to true), and there is no wire or protocol 
> change.
> Not changed: a successful GetBlock without the flag on the domain socket 
> still has no file to send; that is the separate issue HDDS-17443. This patch 
> and the patch of HDDS-17443 change adjacent lines in 
> {{Receiver.ProcessRequestTask.run}}, so whichever is applied second needs a 
> trivial rebase.
> Covered by 
> {{TestKeyValueHandler.testShortCircuitGetBlockHandsFileToOwnContext}}: a 
> GetBlock with the flag dispatched without the domain socket context gets 
> {{shortCircuitAccessGranted=false}} and counts no local bytes, a domain 
> socket context without the flag gets no file, and two dispatches of the same 
> request with their own contexts each get their own open file. On unmodified 
> source the first part fails with "Expecting value to be false but was true"; 
> the other two parts use the new context and do not compile there. 
> {{testGetBlockMetrics}} now takes the file from the context, and 
> {{TestHddsDispatcher}} lists the new op among those whose token is verified. 
> With the patch {{TestKeyValueHandler}}, 
> {{TestKeyValueHandlerWithUnhealthyContainer}} and {{TestHddsDispatcher}} pass 
> (129 tests), as do {{TestXceiverServerDomainSocket}}, 
> {{TestXceiverClientManagerSC}}, {{TestLocalChunkInputStream}} and 
> {{TestDomainSocketFactory}} (17 tests), and checkstyle on 
> {{hadoop-hdds/container-service}} is clean.
> Found by TLA+ model checking and code review of the datanode short-circuit 
> read paths under HDDS-15926, on commit 
> 69d77beff60b9106e2517c36a7a1b2cc726af568. Checked against HDDS issues and 
> apache/ozone pull requests for duplicates before filing. Related but not 
> duplicates: HDDS-11627 (added GetBlock on the short-circuit channel and 
> {{blockFileMap}}), HDDS-12883 (closes the block file after it is sent), 
> HDDS-16918 (fallback to gRPC is not logged on the datanode), HDDS-16335 
> (concurrent access on the other side of the domain socket). The attached 
> patch is a proposal for review. Generated with Specula (Claude Opus 5.5).



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