[ 
https://issues.apache.org/jira/browse/RATIS-688?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16936231#comment-16936231
 ] 

Tsz Wo Nicholas Sze commented on RATIS-688:
-------------------------------------------

It seems there is no simple way to avoid data copying.  As stated in 
https://developers.google.com/protocol-buffers/docs/techniques#large-data ,
bq. Protocol Buffers are not designed to handle large messages. As a general 
rule of thumb, if you are dealing in messages larger than a megabyte each, it 
may be time to consider an alternate strategy. 

One possible way is to break the ContainerCommandRequestProto to two parts, 
header and body.  Serialize header and body to individual ByteString(s).  Then, 
serialize the final ByteString using ByteString.concat(..).  It works since, 
bq. In general, the concatenate involves no copying.
according to 
https://developers.google.com/protocol-buffers/docs/reference/java/com/google/protobuf/ByteString.html#concat-com.google.protobuf.ByteString-

> Avoid buffer copies while submitting client requests in Ratis
> -------------------------------------------------------------
>
>                 Key: RATIS-688
>                 URL: https://issues.apache.org/jira/browse/RATIS-688
>             Project: Ratis
>          Issue Type: Bug
>          Components: client, server
>            Reporter: Shashikant Banerjee
>            Assignee: Tsz Wo Nicholas Sze
>            Priority: Major
>             Fix For: 0.4.0
>
>
> Currently, while sending write requests to Ratis from ozone, a protobuf 
> object containing data encoded  and then resultant protobuf is again 
> converted to a byteString which internally does a copy of the buffer embedded 
> inside the protobuf again so that it can be submitted over to Ratis client. 
> Again, while sending the appendRequest as well while building up the 
> appendRequestProto, it might be again copying the data. The idea here is to 
> provide client so pass the raw data(stateMachine data) separately to ratis 
> client without copying overhead. 
>  
> {code:java}
> private CompletableFuture<RaftClientReply> sendRequestAsync(
>     ContainerCommandRequestProto request) {
>   try (Scope scope = GlobalTracer.get()
>       .buildSpan("XceiverClientRatis." + request.getCmdType().name())
>       .startActive(true)) {
>     ContainerCommandRequestProto finalPayload =
>         ContainerCommandRequestProto.newBuilder(request)
>             .setTraceID(TracingUtil.exportCurrentSpan())
>             .build();
>     boolean isReadOnlyRequest = HddsUtils.isReadOnly(finalPayload);
> //  finalPayload already has the byteString data embedded. 
>     ByteString byteString = finalPayload.toByteString(); -----> It involves a 
> copy again.
>     if (LOG.isDebugEnabled()) {
>       LOG.debug("sendCommandAsync {} {}", isReadOnlyRequest,
>           sanitizeForDebug(finalPayload));
>     }
>     return isReadOnlyRequest ?
>         getClient().sendReadOnlyAsync(() -> byteString) :
>         getClient().sendAsync(() -> byteString);
>   }
> }
> {code}



--
This message was sent by Atlassian Jira
(v8.3.4#803005)

Reply via email to