You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Every byte loaded from YDB via query gets allocated in heap three time.
For example if client reads from YDB 2 GiB/sec of bytes, the go runtime will have to allocate 6 GiB/sec of memory. Which adds additional pressure on GC.
These allocations are:
GRPC allocation for response message (https://github.com/grpc/grpc-go/blob/v1.63.x/rpc_util.go#L630, they are moving buffer around rn, so I use specific tag here for clarity). Basically to read every response GRPC allocates slice of bytes. It supports pooling, but by default the pool is noop, it simply allocates new slice every time.
Proto unmarshalling of Ydb_Table.ExecuteDataQueryResponse. Protobuf doesn't use zero-copy in standard implementation. So it is allocates new byte[] for every bytes field and copy values there.
Proto unmarshalling of Ydb_Table.ExecuteDataQueryResponse.Result into Ydb_Table.ExecuteQueryResult. Resul has Any type, which is essentially a byte array with type name attached, so it undergoes one more unmarshalling.
The possible improvements.
For (1) it is pretty easy to allow sdk users to enable grpc pool. It is experimental though (https://github.com/grpc/grpc-go/blob/v1.63.x/experimental/experimental.go#L46). And right now it doesn't work without additional hacks, because pool can't be used when stats.Handler is used. And sdk uses ststs.Handler internally. (Maybe this gets fixed in grpc code itself)
For (3) the easiest solution would be to stop using Any for query response. And instead switching to something like oneof to specialize more common/important response types.
Otherwise (2) and (3) can be resolved only by switching from standard proto unmarshalling to something custom, to have zero copy. But probably resolving just (1) and (3) can be enough.
The text was updated successfully, but these errors were encountered:
You can set your pool with option config.WithGrpcOptions(experimental.WithRecvBufferPool(yourPool))
By default we dont want to set this option because this is experimental feature of grpc-go library and can vbe brokes in different versions of grpc-go. If you return good feedback about option after some time in production - we consider the idea of using WithRecvBufferPool by default
we did, but unfortunately it doesn't work on its own, because ydb sdk also sets stats.Handler internally. Because of that grpc doesn't return bytes back to pool. And we have to register additional stats.Handler to do it on our own.
Also I was told there is another API (query.Service) which doesn't use Any in response, which should remove one more allocation. So as long as it becomes usable (#1429) I'll try it.
Every byte loaded from YDB via query gets allocated in heap three time.
For example if client reads from YDB 2 GiB/sec of bytes, the go runtime will have to allocate 6 GiB/sec of memory. Which adds additional pressure on GC.
These allocations are:
Ydb_Table.ExecuteDataQueryResponse
. Protobuf doesn't use zero-copy in standard implementation. So it is allocates new byte[] for every bytes field and copy values there.Ydb_Table.ExecuteDataQueryResponse.Result
intoYdb_Table.ExecuteQueryResult
. Resul hasAny
type, which is essentially a byte array with type name attached, so it undergoes one more unmarshalling.The possible improvements.
For (1) it is pretty easy to allow sdk users to enable grpc pool. It is experimental though (https://github.com/grpc/grpc-go/blob/v1.63.x/experimental/experimental.go#L46). And right now it doesn't work without additional hacks, because pool can't be used when stats.Handler is used. And sdk uses ststs.Handler internally. (Maybe this gets fixed in grpc code itself)
For (3) the easiest solution would be to stop using Any for query response. And instead switching to something like oneof to specialize more common/important response types.
Otherwise (2) and (3) can be resolved only by switching from standard proto unmarshalling to something custom, to have zero copy. But probably resolving just (1) and (3) can be enough.
The text was updated successfully, but these errors were encountered: