Support specifying MaxBytes in range request#14810
Support specifying MaxBytes in range request#14810linxiulei wants to merge 6 commits intoetcd-io:mainfrom
MaxBytes in range request#14810Conversation
|
The new feature makes sense to me, only limiting the max number of entries isn't enough if each entry is too big. When client specifies both limit and maxBytes, then server side truncates the result when whichever is satisfied first. It should have no impact on Kubernetes, because the maxByte defaults to 0, which means no limit. |
|
Please also add some common e2e/integration test. Since this PR is already too big, so I'm OK to add it in a separate PR. |
MaxBytes in range request
|
When this PR gets merged, probably someone could enhance K8s side to support FYI. #14810 (comment) |
2880545 to
e7df7d4
Compare
e7df7d4 to
b4c6693
Compare
|
@linxiulei Please also add a changelog in https://github.com/etcd-io/etcd/blob/main/CHANGELOG/CHANGELOG-3.6.md, of course, can be in a separate PR. TODO list:
|
|
Will do. Thanks @ahrtr ! |
|
|
||
| limit := int(ro.Limit) | ||
| if limit <= 0 || limit > len(revpairs) { | ||
| if limit <= 0 || limit >= len(revpairs) { |
b4c6693 to
f1f4dd1
Compare
|
I would like to see more tests before we merge this PR. This code is on a pretty important code path and there were already multiple edge cases not handled properly in this PR (for example maxBytes not working when sorting is enabled). |
|
I manually tested it when making changes, which I can put into e2e/integration in later PR. What tests else do we need here? |
f1f4dd1 to
70a8cd5
Compare
There was a problem hiding this comment.
LGTM(non-binding)
It seems that it reduces that grpc unary API memory usage. The grpc http2 transport only releases the memory after last byte has been sent. I was thinking that if the Range can be streaming type, the List-All from kube-apiserver won't cause memory spike in ETCD side because the pending bytes in memory is limit by http2 stream/connection windows size. However, it might be hard to integrate.
This patch can chunk the data. Thanks! @linxiulei Help a lot.
|
Would also want to get some feedback from K8s scalability people who have some experience with issue that this feature tries to fix. cc @mborsz |
|
I think it would be worth discussing this with authors/reviewers of https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/3157-watch-list which currently tries to solve similar (the same?) problem. Probably it makes sense to get buy-in from sig-apimachinery that we will be able to use this in kube-apiserver before we make changes to etcd. |
|
I agree to get more buy-ins from k8s side to make this feature more appealing. But I do not think it should be a blocker for etcd as this feature can benefit other use cases other than k8s. Also getting buy-ins from k8s side involves more discussions and takes time. Nonetheless, I will try to initiate some discussion within k8s. |
| totalBytes += int64(kv.Size()) | ||
| if totalBytes > r.MaxBytes { | ||
| resp.More = true | ||
| rr.KVs = rr.KVs[:i] |
There was a problem hiding this comment.
If I understand the code correctly, it means we might be sending '0' items, it is, we might stuck completely,
giving empty responses and retries.
I think we should prioritize giving at least 1 item in such situation. And be very explicit that in this situation the maxBytes contract can be exceeded.
But this is the exact semantic discussion we should have with k8s api machinery team @mborsz @lavalamp
We also need to have tests for this.
There was a problem hiding this comment.
Yes, you understood correctly. The initial version was to return the result with size just exceeding the maxBytes so at least one item is returned. But this made the maxBytes a bit ambiguous.
Given the max object size is 1.5MB, we can warm users the maxBytes should be bigger than 1.5MB to avoid returning 0 items. WDYT?
k8s would not directly expose this to end users, to be clear. (but thanks for the heads up!) |
Signed-off-by: Eric Lin <exlin@google.com>
Signed-off-by: Eric Lin <exlin@google.com>
Run 1. ./script/genproto.sh 2. ./scripts/update_proto_annotations.sh Signed-off-by: Eric Lin <exlin@google.com>
Signed-off-by: Eric Lin <exlin@google.com>
Signed-off-by: Eric Lin <exlin@google.com>
Signed-off-by: Eric Lin <exlin@google.com>
e97726b to
97d4b6c
Compare
I added a commit of e2e tests in the previous push |
Codecov Report
@@ Coverage Diff @@
## main #14810 +/- ##
==========================================
- Coverage 74.74% 74.57% -0.17%
==========================================
Files 415 415
Lines 34287 34311 +24
==========================================
- Hits 25629 25589 -40
- Misses 7018 7071 +53
- Partials 1640 1651 +11
Flags with carried forward coverage won't be shown. Click here to find out more.
📣 We’re building smart automated test selection to slash your CI/CD build times. Learn more |
|
This issue has been automatically marked as stale because it has not had recent activity. It will be closed after 21 days if no further activity occurs. Thank you for your contributions. |
|
/reopen |
|
How can I re-open it? I am still active on this PR if maintainers are able to evaluate it |
|
I am not able to reopen either. Please raise a new PR, thx |
|
@linxiulei maybe it will be active after you repush? |
This comment was marked as off-topic.
This comment was marked as off-topic.
|
repush didn't work either. Let me raise a new PR. |
fixes: #14809