-
Notifications
You must be signed in to change notification settings - Fork 151
Reduce resource consumption when using file discovery with same file in multiple probes #634
Comments
@benner If all probes are using the same targets you can consider using Sorry, it's not documented, but here is what you can do: Add the following config stanza at the config file level:
and, then at the probe level:
This way we create only one target structure in memory .. and hence only one file refresh loop. |
Ah, but you're using different filters. Can these filters be a regex on target names?
|
I saw shared_targets or regex filtering nut in my case all probes have different targets. Now I'm using label filters. |
Example of cfg:
|
I see. I guess rds_targets semantics would have been better for file_targets as well. RDS server could run in the same process (all transparent to the probes or configuration), and all probes could just rds_targets. From configuration standpoint, it will look like this:
Does that make sense at all? I can try implementing it. It may take a few days to get it reviewed and submitted though. |
I will look into that |
@benner, fyi: I am also looking at adding the "file" provider to RDS. I'll try to create a PR soonish, so that you can test with it if you want. |
I still need to get changed reviewed internally, but here is the proposed change: #635 (branch rds_file). With this change you can do the following:
If you'd like to test, you can download pre-built binaries from here: linux, all. |
I tried From what I see
Only inner |
Good point regarding not being to control client side To change refresh interval on the server side (where the file is actually reloaded), you can modify your rds_server config:
I am wondering if 14GB vs 40GB difference is only due to temporary objects in the memory or something else is going on. At the time of refresh, new objects are created, and old objects should automatically be garbage collected. I've thought about implementing some improvements to RDS protocol to track if resources have changed and signal to the client in case refresh is not needed, but I've largely avoided that as it may make things more complex and may introduce new failure modes. Was it 14GB with file_targets or targets directly embedded in the config file? |
I think it is directly related. I actually did some heap dumps (pporf) during RSS growth and looked at Attaching one when RSS was 5G (less probes). I don't have svg now when it was 40G but situation was the same but numbers was bigger. Next week I'll redo the test with hands changed and recompiled rds.ClientConf.re_eval_sec. Ether way, situation with rds files solution is like 5-6 times better than it was before :-) |
Yes |
Thanks for sharing the heap profile. Few observations:
Thoughts:
I'll look at implementing 1 (at least for JSON) & 3. |
I was always using TextProto |
Tested full configuration with default 30s and with 60min
with 60 min re_eval_sec it works as expected. RSS grows almost the same as with static configuration. For default 30s interval main reason for memory usage is big number of probes. In my setups it means RDS server receives around 3 requests per second. Result: all CPUs are busy (20 logical CPUs) and memory grows to ~40G. 60 min ~900 probes: One drawback with longer re_eval_sec is that all probing can be delayed up to same interval for actual probing but I can live with that because whole point of that is to keep Cloudprober without restarting :-) |
To avoid breaking existing users, continuing providing "file_targets" (directly), but implement them using RDS file targets provider. Main reasoning behind this RDS provider is to allow multiple probes to use the same targets file without each probe having to load the same file again and again. Ref: #634 PiperOrigin-RevId: 387196102
To avoid breaking existing users, continuing providing "file_targets" (directly), but implement them using RDS file targets provider. Main reasoning behind this RDS provider is to allow multiple probes to use the same targets file without each probe having load the same file again and again. Ref: #634 PiperOrigin-RevId: 387196102
To avoid breaking existing users, continuing providing "file_targets" (directly), but implement them using RDS file targets provider. Main reasoning behind this RDS provider is to allow multiple probes to use the same targets file without each probe having load the same file again and again. Ref: #634 PiperOrigin-RevId: 387196102
Interesting. Thanks again for the heap profiles @benner! So ListResources should get better with the change that I just committed in the main branch: #640. There was inefficient resource allocation in the previous change. Another improvement I am planning to make is to reload file "only if" it has been modified since the last load. With that you won't have to worry about re_eval_sec so much. |
Even though resources allocation efficiency mentioned in the previous update will help quite a bit, I think #641 will have the most impact for a scenario like yours. |
Ref: #634 PiperOrigin-RevId: 387390152
Ref: #634 PiperOrigin-RevId: 387390152
Ref: #634. PiperOrigin-RevId: 387655415
With all the changes so far, I think you should see substantial improvement in performance (much better than the default case earlier). You can even keep the re_eval_sec very low in RDS file provider config -- it won't reload file unless it has changed. Next up is #641. I'm working on it. |
If request contains if_modified_since field, use that field to decide whether to send all the resources in the response or not. We always returns last_modified in the response. This timestamp corresponds to when lister's cache was refreshed from the actual file. Ref: #641 & #634 PiperOrigin-RevId: 388502695
If request contains if_modified_since field, use that field to decide whether to send all the resources in the response or not. We always returns last_modified in the response. This timestamp corresponds to when lister's cache was refreshed from the actual file. Ref: #641 & #634 PiperOrigin-RevId: 388502695
@benner, I think we should be good here now. You should be able to use lower re_eval_sec (30s) without any performance impact. Until you update the targets file, no new large data allocation should happen. Let me know how it goes. |
Awesome. Great to hear. Thanks for checking! |
@benner Awesome, great to see. |
Reduce resource consumption when using file discovery with same file in multiple probes
Setup:
Multiple HTTP probes with same file_targets {file_path} (generated from consul-template) and different filter{} to for each probe to select related targets (similar approach as with
run_on
{}),.textpb
file is about 220 MiB in size with more than 1M resource{}s,cloudprober.cfg
has more than 500 probes.Problem:
During start all probes launch file.refresh() and it kills almost any machine. Looking at code - all probes simultaneous opens same file and do .Unmarshal() in same time. This is memory and CPU heavy operation. Later on everything normalized due random delays and GC.
Description of what you want to happen and what problem will it solve for you.
I tried few different ways like putting global file mutex which serializes all processing but then it takes ages to gather targets for all probes. Doing similar randomization as in refresh loop will help too but same as with serial processing it will take ages. I also tried similar approach as described here: https://firas.dev.sy/post/go/2020/making-timed-maps-golang/ but simpler and with extended API with .LoadOrStore() as in sync.Map for reserving computation (file reading to avoid thundering herd problem), two maps - for reservation and another one for caching Unmarshal()'ed resources (before filtering). I got some promising results but don't have working/publishable code yet.
Some numbers I've measured (no concurrency):
BTW, I have everything working with all probes and targets when I put everything statically in main configuration file.
The text was updated successfully, but these errors were encountered: