-
Notifications
You must be signed in to change notification settings - Fork 9.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support specifying MaxBytes
in range request
#14810
Conversation
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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 ! |
@@ -86,12 +86,16 @@ func (tr *storeTxnRead) rangeKeys(ctx context.Context, key, end []byte, curRev i | |||
} | |||
|
|||
limit := int(ro.Limit) | |||
if limit <= 0 || limit > len(revpairs) { | |||
if limit <= 0 || limit >= len(revpairs) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is no-op
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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