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

Dmitry Konstantinov edited comment on CASSANDRA-21354 at 7/13/26 6:08 PM:
--------------------------------------------------------------------------

Hi, I've addressed review comments provided by [~aleksey]
1) I've added byte limit to avoid cases when rows are huge and it may impact GC 
due to an extended lifetime for them.
I've combined it with the original row based limit: it should be safer as we 
may have a lot of small rows/objects under a byte limit.
2) I've added separate limits for CL = ONE/LOCAL_ONE, if we have single local 
replica then the lifetime of a response is much shorter and we can keep in 
memory more.
3) I moved away from a combined (in-memory + serialized suffix) response to 
pure in-memory or fully serialised response: such logic is simpler

Additionally to the review comments I've also added few metrics to improve 
observability of this logic (counters - how many times we crossed limits).

We also discussed a global limit/budget (consume/release bytes from a global 
atomic variable) but it looks too dangerous to introduce it due to lack of 
explicit response lifecycle - we may miss returning in some cases 
(timeouts/spec retries/errors/etc) and it will be a leak (and it always a pain 
to investigate such kind of leaks based on my previous experience with memtable 
accounting) 



was (Author: dnk):
Hi, I've addressed review comments provided by [~aleksey]
1) I've added byte limit to avoid cases when rows are huge and it may impact GC 
due to an extended lifetime for them.
I've combined it with the original row based limit: it should be safer as we 
may have a lot of small rows/objects under a byte limit.
2) I've added separate limits for CL = ONE/LOCAL_ONE, if we have single local 
replica then the lifetime of a response is much shorter and we can keep in 
memory more.
3) I moved away from a combined (in-memory + serialized suffix) response to 
pure in-memory or pure-serilized response: such logic is simpler

Additionally to the review comments I've also added few metrics to improve 
observability of this logic (counters - how many times we crossed limits).


> Avoid serialization and deserialization for coordinator-local single 
> partition data read
> ----------------------------------------------------------------------------------------
>
>                 Key: CASSANDRA-21354
>                 URL: https://issues.apache.org/jira/browse/CASSANDRA-21354
>             Project: Apache Cassandra
>          Issue Type: Improvement
>          Components: Local/Other
>            Reporter: Dmitry Konstantinov
>            Assignee: Dmitry Konstantinov
>            Priority: Normal
>             Fix For: 6.x, 7.x
>
>         Attachments: image-2026-05-07-10-10-16-886.png, may3_max_alloc.html, 
> may6_noser_alloc.html, read_noser_proto_trunk_ci_summary.htm
>
>          Time Spent: 1h 10m
>  Remaining Estimate: 0h
>
> Currently when we execute a local read we fetch data from SSTables and 
> Memtables using a merging iterator and write it to a byte buffer. Later when 
> we combine a CQL response we deserialize the data back to iterate over them 
> as a part of coordinator logic. So, we allocate rows and cells twice here, 
> during the read from SSTables/Memtables and during the deserialization by 
> coordinator logic if we read data locally (it is a typical scenario because 
> usually drivers are sending requests to replicas).
> The idea of optimization: if we do a single partition read of a small number 
> of rows we can keep the data in memory and avoid this double row objects 
> allocation.
> We should limit amount of such data kept in memory to avoid too much pressure 
> on GC due to extended lifetime for these objects and promoting them to an old 
> generation.
> So, a system property can be used to limit number of rows we keep in memory 
> in this scenario, as well as to disable the logic in case of any issues.
> We cannot get a number of rows in advance, so we do a rows limiting logic in 
> the following way: we read first N rows to memory and if we still have 
> something we serialize the remaining to a buffer and then concatenate 
> iterators for the in-memory rows + deserialized one
>  !image-2026-05-07-10-10-16-886.png|width=800! 



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