-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
admin: making a streaming version of /clusters #32055
Comments
Quick thoughts on how to do this: /clusters impl is here: https://github.com/envoyproxy/envoy/blob/main/source/server/admin/clusters_handler.cc first place to look for the streaming API this should implement: Line 119 in 412a936
The current implementation builds a gigantic json structure that copies all the cluster information, and then builds a string that has another copy of that. So if you are generating 1G of data from /clusters it will hold 2G of that in memory. Goal is to represent none of that in memory, maybe a 100k buffer or so. One building block I recommend is a streaming json seriazlier, so you can incrementally write out chunks of json without holding the whole model in memory. see https://github.com/envoyproxy/envoy/blob/main/source/common/json/json_streamer.h for a class to help you with that. /config_dump is similar except that the data model exposed by /clusters is a lot simpler, so I think it will be easier to convert it to a seriazlied model. |
Hey @jmarantz. Thanks for assigning me this issue and providing some insight into the components to consider. It appears that the main work to be done is to implement Looking at the |
I think from the test perspective you can keep calling nextChunk and not drain the buffer, or you can alternatively drain the buffer on each call to nextChunk, and append to a string in the test. Then you can validate the compete JSON for functionality. You can also test the streaming functionality just by looking at the chunk sizes coming out one at a time. From an implementation perspective you need to be able to emit partal Json which is why I wrote source/common/json/json_streamer.h . |
High Level Design ConsiderationsI have two high-level approaches to this problem. One presents a stateful iteration-based solution that is simple to implement but provides somewhat minimal memory pressure relief. The second provides substantial memory pressure relief modeled as a token stream using simple pub/sub at the cost of a second temporary thread. Stateful Cluster IterationMy first approach employs stateful iteration. The working proof of concept can be found in this diff. The idea is to transform the The remainder of the implementation follows pretty similarly to the class collaborators in streaming stats rendering but uses the logic of the existing clusters handler. Advantages
Disadvantages
Token-Like Pub/Sub StreamThe alternative approach employs token-like pub/sub stream processing. In this solution, for each Advantages
Disadvantages
I could probably develop a proof-of-concept of the second option in a branch off of the diff supplied above. |
@miroswan chatted with me about this offline, so I wanted to post the relevant bits here. I think "Stateful Cluster Iteration" is the way to go here, since its simpler and the disadvantages are moot. AFAIK, the memory usage problems are not caused by small numbers of really big clusters, so this will almost certainly be an improvement where we need it. I can help review the PR whenever you want feedback. |
+1: stateful cluster iteration is a lot more like the /stats request system, which would also be defeated by small numbers of huge clusters. I think we want to avoid more threads if possible, especially if there might be a thread per active request. |
Excellent. I proceed with stateful cluster iteration this week. Thanks for the feedback folks. |
Going to solve this issue and come back once it's merged: #33752 |
/clusters can produce a remarkably huge response. This will need to be fully buffered as an in-memory continuous string. For large configs, this will be slow and may exert memory pressure as well.
See also #31755 as well as prior work streaming admin stats in #19693. This work is not trivial and has risks. See also the difficult attempt to make /stats/prometheus stream as well: #24998 which needed to be rolled back due to complexities in the Prom format that made streaming difficult.
See also #32054 which is a similar request for /config_dump
The text was updated successfully, but these errors were encountered: