Skip to content

Streaming json list encoder#129334

Merged
k8s-ci-robot merged 1 commit intokubernetes:masterfrom
serathius:streaming-json-list-encoder
Feb 28, 2025
Merged

Streaming json list encoder#129334
k8s-ci-robot merged 1 commit intokubernetes:masterfrom
serathius:streaming-json-list-encoder

Conversation

@serathius
Copy link
Copy Markdown
Contributor

@serathius serathius commented Dec 20, 2024

/kind feature

Implements proposal from #129304 where streaming json respones reduced the memory used by apiserver 3-6x times. Validated on configmaps and pods objects with 5 concurrent list each returning 1.5GB of data.

Improved how the API server responds to **list** requests where the response format negotiates to JSON. List responses in JSON are marshalled one element at the time, drastically reducing memory needed to serve large collections. Streaming list responses can be disabled via the `StreamingJSONListEncoding` feature gate.

/cc @mborsz @wojtek-t @jpbetz @deads2k @p0lyn0mial

@k8s-ci-robot k8s-ci-robot added the release-note Denotes a PR that will be considered when it comes time to generate release notes. label Dec 20, 2024
@k8s-ci-robot k8s-ci-robot added kind/feature Categorizes issue or PR as related to a new feature. size/L Denotes a PR that changes 100-499 lines, ignoring generated files. cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. needs-triage Indicates an issue or PR lacks a `triage/foo` label and requires one. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. area/apiserver sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. and removed do-not-merge/needs-sig Indicates an issue or PR lacks a `sig/foo` label and requires one. labels Dec 20, 2024
@serathius serathius force-pushed the streaming-json-list-encoder branch from 038e705 to 1b4e17e Compare December 20, 2024 15:54
@sftim
Copy link
Copy Markdown
Contributor

sftim commented Dec 20, 2024

💭 If we wanted to do streaming encoding to YAML or CBOR, is there anything in this code making the YAML / CBOR option hard to do?

Comment thread staging/src/k8s.io/apiserver/pkg/features/kube_features.go Outdated
Comment thread staging/src/k8s.io/apiserver/pkg/features/kube_features.go Outdated
@sftim
Copy link
Copy Markdown
Contributor

sftim commented Dec 20, 2024

Changelog suggestion

-List responses in JSON are marshalled one element at the time, drastically reducing memory needed to serve large responses. Can be disabled via StreamingJSONListEncoding feature flag
+Improved how the API server responds to **list** requests where the response format negotiates to JSON. List responses in JSON are marshalled one element at the time, drastically reducing memory needed to serve large collections. Streaming list responses can be disabled via the `StreamingJSONListEncoding` feature gate.

(will need adjusting if the feature gate name changes per my opinion / suggestion)

Comment thread staging/src/k8s.io/apimachinery/pkg/runtime/serializer/json/json.go Outdated
@serathius
Copy link
Copy Markdown
Contributor Author

If we wanted to do streaming encoding to YAML or CBOR, is there anything in this code making the YAML / CBOR option hard to do?

Don't know, my focus is on JSON for CRDs and than Proto for built in types. I would need to get some help for the others.

@serathius serathius force-pushed the streaming-json-list-encoder branch 3 times, most recently from 42ab20e to 6148aef Compare December 25, 2024 10:28
@serathius serathius force-pushed the streaming-json-list-encoder branch from 6148aef to 92837da Compare December 26, 2024 13:58
@k8s-ci-robot k8s-ci-robot added area/release-eng Issues or PRs related to the Release Engineering subproject sig/release Categorizes an issue or PR as relevant to SIG Release. labels Dec 26, 2024
@serathius serathius force-pushed the streaming-json-list-encoder branch from 92837da to 85425d6 Compare December 26, 2024 15:01
Comment thread staging/src/k8s.io/apimachinery/pkg/api/meta/help.go
serathius added a commit to serathius/kubernetes that referenced this pull request Feb 17, 2025
Used test cases from:
* Original PR kubernetes#129334
* KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests

For now testing current serializer implementation to show encoder
behavior and agree on set of tests. Having a separate PR should make review easier.
In separate PR will add the implementation for streaming that should
provide same response byte-to-byte.
serathius added a commit to serathius/kubernetes that referenced this pull request Feb 18, 2025
Used test cases from:
* Original PR kubernetes#129334
* KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests

For now testing current serializer implementation to show encoder
behavior and agree on set of tests. Having a separate PR should make review easier.
In separate PR will add the implementation for streaming that should
provide same response byte-to-byte.
serathius added a commit to serathius/kubernetes that referenced this pull request Feb 18, 2025
Used test cases from:
* Original PR kubernetes#129334
* KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests

For now testing current serializer implementation to show encoder
behavior and agree on set of tests. Having a separate PR should make review easier.
In separate PR will add the implementation for streaming that should
provide same response byte-to-byte.
serathius added a commit to serathius/kubernetes that referenced this pull request Feb 18, 2025
Used test cases from:
* Original PR kubernetes#129334
* KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests

For now testing current serializer implementation to show encoder
behavior and agree on set of tests. Having a separate PR should make review easier.
In separate PR will add the implementation for streaming that should
provide same response byte-to-byte.
serathius added a commit to serathius/kubernetes that referenced this pull request Feb 18, 2025
Used test cases from:
* Original PR kubernetes#129334
* KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests

For now testing current serializer implementation to show encoder
behavior and agree on set of tests. Having a separate PR should make review easier.
In separate PR will add the implementation for streaming that should
provide same response byte-to-byte.
serathius added a commit to serathius/kubernetes that referenced this pull request Feb 18, 2025
Used test cases from:
* Original PR kubernetes#129334
* KEP https://github.com/kubernetes/enhancements/tree/master/keps/sig-api-machinery/5116-streaming-response-encoding#unit-tests

For now testing current serializer implementation to show encoder
behavior and agree on set of tests. Having a separate PR should make review easier.
In separate PR will add the implementation for streaming that should
provide same response byte-to-byte.
@serathius
Copy link
Copy Markdown
Contributor Author

@anson627 @haosdent Thanks for taking initiative, however as described in #129334 (comment) the work has grown beyond just this PR.

The work for streaming encoding was upgraded from a single PR to a full KEP. To understand the next steps you can read the design https://github.com/kubernetes/enhancements/blob/master/keps/sig-api-machinery/5116-streaming-response-encoding/README.md and follow the implementation plan in kubernetes/enhancements#5116

@anson627
Copy link
Copy Markdown
Contributor

anson627 commented Feb 19, 2025

thanks @serathius! I will take a closer look at the plan, and see where and how I can help

@serathius
Copy link
Copy Markdown
Contributor Author

@serathius
Copy link
Copy Markdown
Contributor Author

The PR is ready for re-review @liggitt

@serathius
Copy link
Copy Markdown
Contributor Author

/retest

@liggitt
Copy link
Copy Markdown
Member

liggitt commented Feb 28, 2025

/lgtm
/approve
/hold cancel

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

LGTM label has been added.

DetailsGit tree hash: 12bd3e248c3fe40c2d548ba8821c72b363229964

@k8s-ci-robot
Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: fuweid, liggitt, serathius

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@serathius
Copy link
Copy Markdown
Contributor Author

https://perf-dash.k8s.io/#/?jobname=benchmark%20list&metriccategoryname=E2E&metricname=Resources&Resource=memory&PodName=kube-apiserver-benchmark-list-master%2Fkube-apiserver###
share_5433293128249547611

@songminglong
Copy link
Copy Markdown

we tested in our env: list 6000 configmaps with size 150kb

Conclusion: under json list streaming conditions, gzip may be more time-consuming

before the mr #130281

//total durations
Trace[1274966822]: ["cacher list" audit-id:3c8cb522-d8b6-4a0b-ad1a-265dd3e5ecb3,type:configmaps 91429ms

// for example, one of steam
size:150373,firstWrite:false 8ms

after the mr #130281

//total durations:
Trace[574860878]: ["cacher list" audit-id:70a49c16-fd5c-4ddb-aec4-35eebd5249f7,type:configmaps 104139ms

// and one of each per stream
size:150373,firstWrite:false 13ms

@serathius
Copy link
Copy Markdown
Contributor Author

10% difference seems ok. Our goal was to reduce memory usage, doing so is already a tradeoff that increases CPU usage.

@haosdent
Copy link
Copy Markdown
Member

10% difference seems ok. Our goal was to reduce memory usage, doing so is already a tradeoff that increases CPU usage.

Agree, users could toggle off this if they don't want to compromise on latency

@songminglong
Copy link
Copy Markdown

10% difference seems ok. Our goal was to reduce memory usage, doing so is already a tradeoff that increases CPU usage.

I agree with this tradeoff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/apiserver area/release-eng Issues or PRs related to the Release Engineering subproject cncf-cla: yes Indicates the PR's author has signed the CNCF CLA. kind/feature Categorizes issue or PR as related to a new feature. lgtm "Looks good to me", indicates that a PR is ready to be merged. needs-priority Indicates a PR lacks a `priority/foo` label and requires one. release-note Denotes a PR that will be considered when it comes time to generate release notes. sig/api-machinery Categorizes an issue or PR as relevant to SIG API Machinery. sig/architecture Categorizes an issue or PR as relevant to SIG Architecture. sig/release Categorizes an issue or PR as relevant to SIG Release. size/XL Denotes a PR that changes 500-999 lines, ignoring generated files. triage/accepted Indicates an issue or PR is ready to be actively worked on.

Projects

None yet

Development

Successfully merging this pull request may close these issues.