Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upImplement strategies to limit memory usage. #455
Comments
beorn7
added
the
feature-request
label
Jan 21, 2015
beorn7
self-assigned this
Feb 2, 2015
This comment has been minimized.
This comment has been minimized.
|
I too have had issues with this, I've found Prometheus very quickly eats up a lot of RAM and it can't easily be managed. |
This comment has been minimized.
This comment has been minimized.
|
@sammcj The problem here is that there is no standard way to get a Go program's actual memory consumption. The heap sizes reported in http://golang.org/pkg/runtime/#MemStats are usually off by a factor of 3 or so from the actual resident memory. This can be due to a number of things: memory fragmentation, Go metadata overhead, or the Go runtime not returning pages to the OS very eagerly. A proper solution needs yet to be found. One thing you can tune right now is how many sample chunks to keep in RAM. See this flag:
Keep in mind this is only one (albeit major factor) in RAM usage. Other factors are:
|
This comment has been minimized.
This comment has been minimized.
|
Also the various queues (Prometheus's own ones like sample ingestion queue but also Go and OS internal like queued up network queries or whatever). I have that idea of implementing a kind of memory chaperon that will not only evict evictable chunks but also throttle/reject queries and sample ingestion to keep total memory usage (or the amount of free memory on the machine) within limits. But that's all highly non-trivial stuff... |
beorn7
changed the title
Optional chunk eviction based on memory pressure.
Implement strategies to limit memory usage.
Mar 19, 2015
This comment has been minimized.
This comment has been minimized.
|
There are by now many things that may take memory, and there are many knobs to turn to tweak it. I changed then name of the issue into something more generic. A good news already: The ingestion queue is gone, so there will not be wild ram usage jumps anymore if ingestion piles up scrapes. |
This comment has been minimized.
This comment has been minimized.
camerondavison
commented
Apr 28, 2015
|
I am running with a retention of 4 hours, and the default "storage.local.memory-chunks", on version 0.13.1-fb3b464. While @juliusv said that I should expect that this means that the memory used up may be more than 1GB I am seeing it run out with the docker container setting at 2.5GB. Basically it looks like a memory lea, because on restart all of the memory goes back down and then slowly over time creeps back up. Is there any formula that could give me a good idea what to set the memory limit to, is there any way I can figure out if there is a leak somewhere or if it just because more and more data is coming in. |
This comment has been minimized.
This comment has been minimized.
|
@a86c6f7964 One thing to start out with: if you configure Prometheus to monitor itself (I'd always recommend it), does the metric |
This comment has been minimized.
This comment has been minimized.
camerondavison
commented
Apr 29, 2015
|
ya it was going up. it got almost to 1million, so maybe it just needs a little more memory |
This comment has been minimized.
This comment has been minimized.
|
@a86c6f7964 Retention is fundamentally a bad way to get memory usage under control. It will only affect memory usage if all your chunks fit into memory. Retention is meant to limit disk usage. Please refer to http://prometheus.io/docs/operating/storage/#memory-usage for a starter. Applying the rule of thumb given there, you should set I recommend to start with |
This comment has been minimized.
This comment has been minimized.
|
Problem here is that "what's my memory usage?" or "how much memory is free on the system?" are highly non trivial questions. See http://www.redhat.com/advice/tips/meminfo.html/ as a starter... |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Aug 20, 2015
|
I'm currently running prometheus (0.15.1) on a bare metal server with 64GB memory, default settings (except retention, one week) and around 750 compute servers to be scraped every 30s. The server is dedicated to prometheus. We have observed that memory consumption is going up until the machine is not responding anymore. It takes around two days to reach this point and killing prometheus process does not free all memory immediately. As suggested by @juliusv , I monitored
|
This comment has been minimized.
This comment has been minimized.
|
@pousa Yeah, sounds like that kind of server should normally not use that much RAM. Some things to dig into:
|
This comment has been minimized.
This comment has been minimized.
pousa
commented
Aug 20, 2015
|
I would say that the machine does get that much traffic. I had to reboot it in the afternoon (again memory problems) and right now it has:
They are node exporter and a collectd plugin developed by us, that basically aggregate data from /proc/PID/stat for each job. On our data center, a job is basically a parallel application from HPC domain composed of processes|threads. Great! Thanks for the pprof tip, I will do it and post it here later. |
This comment has been minimized.
This comment has been minimized.
|
@pousa That sounds like a low number of queries and very reasonable ingestion rate for that kind of server. Though that makes me wonder, if you have 1.5 million series active in memory, I would have expected ~50k samples per second ingestion rate (at 30s scrape interval) instead of 12k/s, unless your series are frequently changing, so that only a small subset of active memory series gets an update on every scrape. If you are monitoring jobs via Your memory usage is shooting up, while memory chunks and series are staying pretty constant. Weird! |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Aug 21, 2015
|
@juliusv the ingestion rate keeps around this and the number of monitored jobs is around 7k. I do not monitor PID explicitly, but JOBIDs (set of PIDs). However, they also change quiet a lot. Jobs have a maximum duration of 4h, 24h or 120h. And it is common to have jobs that run for few minutes. Yep, that is why I posted here. I could not understand this either. I still have to run pprof, will do this today. |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Aug 24, 2015
|
@juliusv run pprof and saw only 3GB being used. Need to investigate more.. |
This comment has been minimized.
This comment has been minimized.
|
@pousa The Go-reported heap size is always smaller than what the OS sees in terms of resident memory usage (due to internal metadata overhead and memory fragmentation), but that's usually factor 2 or so. I don't see how it would report 3GB, but then fill up 64GB in reality. Odd! |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Aug 24, 2015
|
@juliusv Thanks for the information. Ideed odd. I replicated the service on a different server today and I'm monitoring both servers/prometheus. I want to see if this could some how be related to the server and not prometheus itself, since top reports only half of memory being used by prometheus. |
This comment has been minimized.
This comment has been minimized.
killercentury
commented
Sep 8, 2015
|
I have similar issue as @pousa , the EC2 instance repeatly run out of memory after about 2 - 4 days. I do have much less memory than @pousa . But I am wondering what is the minimum/recommended memory capacity is required for running prometheus for long-term. Is it possible for prometheus to control its memory usage automatically instead of exhausting all the memory on the instance until it dies? |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Sep 8, 2015
|
@killercentury I still have the problem. I tried to build it with the newer version of GO but, no luck. I also looked into GO runtime environment variables, but could not find anything. |
This comment has been minimized.
This comment has been minimized.
|
Hi everybody, please read http://prometheus.io/docs/operating/storage/ . @killercentury if you have very little memory (less than ~4GiB), you want to reduce |
This comment has been minimized.
This comment has been minimized.
|
And yes, ideally all of these value would auto-tweak themselves. However, that's highly non-trivial and not a priority to implement right now. |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Sep 8, 2015
|
@beorn7 I will try tweaking those flags and if needed the scrape interval. Thanks! |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Sep 16, 2015
|
@beorn7 Changing those flags and increasing a bit the scraping interval allow our prometheus instances to run without running out of memory. Thanks! However, I still have long timings to get back results from expressions... sometimes even get timeouts. Concerning sharding, we were already doing it. |
This comment has been minimized.
This comment has been minimized.
|
Expensive queries can be pre-computed with recording rules: http://prometheus.io/docs/querying/rules/ To try out very expensive queries, you can increase the query timeout via the (Obviously, that's all now off-topic and has nothing to do with memory usage anymore. ;) |
This comment has been minimized.
This comment has been minimized.
pousa
commented
Sep 16, 2015
|
@beorn7 Thanks, I will try the flag. We already have rules in place, and I was talking about very simple queries (e.g single metrics). But, as you said, this is a different topic ;) |
This comment has been minimized.
This comment has been minimized.
|
If a single time series takes a long time to query, then we are kind of on-topic again. Because the time is most likely needed to load chunks from disk. Tweaking the flags discussed here, you can maximize the number of chunks Prometheus keeps in memory, and thereby avoid loading in chunks from disk. |
This comment has been minimized.
This comment has been minimized.
ntquyen
commented
Nov 9, 2016
|
@juliusv If you read my comments above and @brian-brazil's answers, you wouldn't be sure that the high memory would only come from |
beorn7
referenced this issue
Nov 14, 2016
Closed
Auto set memory-chunk base on the available free memory detected #2188
This comment has been minimized.
This comment has been minimized.
|
I think we have do some deeper analysis here to identify bottlenecks in the case of many active time series. The more dynamic the environment, the higher the time series churn, the more we encounter this issue. We all know I'm not a friend of storage tuning flags dictating memory usage (with limited accuracy), but at least it's static to a degree. Our in-memory held data should be the largest part of memory usage – even considering a moderate querying load. If there are any ideas where this memory goes to, I'm sure we can optimize in the right places. |
This comment has been minimized.
This comment has been minimized.
|
I did some research as reported in #455 (comment) above. I essentially tried to model the memory usage with two linear variables: chunks in memory and timeseries in memory. Without any luck at all. There is definitely more creating variable memory usage. Candidates include: number of targets, queries, service discovery, … It would obviously be great to understand the memory consumption pattern in more detail. But we can pretty safely assume that they are complicated enough so that you cannot create a simple rule of how to set the flags (or how to auto-set them). My plans are therefore more into the direction to make chunk eviction depend on memory pressure so that you ultimately tell Prometheus how much RAM it may take, and then the server tries to dynamically balance memory chunks (and even persistence efforts) accordingly. Since these are the only levers we have, we don't really have to know where the memory is used (outside of finding memory leaks or optimizing code) as long as we know how much is used. |
This comment has been minimized.
This comment has been minimized.
|
Sorry, I missed that comment. My general point: If there's a place where we can fix algorithmic complexity or a significant constant factor of our memory usage, it is well worth knowing about it. For example, a chunk is 1KB with in-mem chunks fully pre-allocated. Then there's obviously management around it – but why does that add up to 3KB? That's not to say that there aren't very good reasons for that. But it's a complex system by now and chances are we missed an opportunity for baseline improvement so far. |
This comment has been minimized.
This comment has been minimized.
My research resulted in the conclusion that there is no linear relationship like the above. The memory certainly goes somewhere, but it doesn't make sense to say that every memory chunk we add adds 3kiB of RAM usage or each series adds 10kiB of RAM usage. |
beorn7
referenced this issue
Nov 15, 2016
Closed
The document about memory usage need be clarify #2187
This comment has been minimized.
This comment has been minimized.
|
More results from ongoing investigation: |
This comment has been minimized.
This comment has been minimized.
coding-horror
commented
Jan 19, 2017
|
We are also seeing extreme memory usage by Prometheus at Discourse, 55GB of RAM. This actually caused our https termination machines to have small blip-like interruptions in service due to extreme memory pressure. :( |
This comment has been minimized.
This comment has been minimized.
randomInteger
commented
Jan 19, 2017
•
|
What a kick in the pants, seeing Jeff Atwood's reply pop up in my inbox because of my involvement in this thread. I am a huge coding-horror fan. Back on topic: I have been playing with trying to tune Prometheus but nothing I do seems to stop the ever creeping memory consumption. I am still restarting prometheus' container once every 24 hours and that is keeping memory use in check while still continuing to harvest/store/serve the data I'm collecting. Its not a great solution, but its an ok workaround in this instance. If there is anything I can do from my end to provide you with more data on this issue, please let me know. |
This comment has been minimized.
This comment has been minimized.
|
I've implemented a number of improvements to Prometheus ingestion that'll be in the 1.5.0, and in the best case will cut memory usage by 33%. That slow growth is likely chunkDescs which depending on your setup could take weeks to stabilise, with my changes things should now stabilise about 12 hours after your chunks fill. https://www.robustperception.io/how-much-ram-does-my-prometheus-need-for-ingestion/ has more information. |
This comment has been minimized.
This comment has been minimized.
|
We finally managed to run Prometheus stable in our production GKE cluster with following settings: 10 core cpu request -storage.local.retention=168h0m0s Earlier tests with local memory chunks calculated by dividing by 3 or 4 constantly ran us in to out of memory kills, since using 5 this no longer seems to happen. Memory usage slowly grows after start but flattens off somewhere around 60gb. We do experience an occasional hang, for that we just added In the GKE cluster itself we have about 40 4-core nodes running 750 pods, getting scraped each 15 seconds. Each node runs the node-exporter, so there's a wealth of information coming from Kubernetes itself and those node exporters. Ingestion isn't a problem at all for Prometheus, the querying side is more tricky. We can see clearly in cpu pressure - and to a lesser extent memory usage - whether people have their Grafana dashboards opened during the day. It drops to a really low level when the office goes empty. |
This comment has been minimized.
This comment has been minimized.
|
The quick math indicates that you needed ~3.9KB per chunk with 1.4 just to handle ingestion, so 5 with queries isn't surprising. |
This comment has been minimized.
This comment has been minimized.
|
With our current settings it seems more like 4.6kb per chunk (ending up at 60GB used memory). But part of that memory usage could be for querying or disk cache, or any other resident memory usage by the application I guess? Is it possible to see the separate types of memory usage in Prometheus' own metrics? |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Branch https://github.com/prometheus/prometheus/tree/beorn7/storage currently contains the implementation of an experimental flag |
This comment has been minimized.
This comment has been minimized.
|
That looks promising. One thing I noted during benchmarking was a ~10% overhead for memory usage above what purely the heap used, so reducing the number the user provides accordingly might be an idea. |
This comment has been minimized.
This comment has been minimized.
coding-horror
commented
Mar 6, 2017
•
|
We did see solid improvements (reduction in memory usage) after we deployed 1.5 on our infra thanks @brian-brazil -- keep the improvements coming! Let us know how we can help. |
This comment has been minimized.
This comment has been minimized.
|
@beorn7 golang/go#16843 and linked discussions may be of interest. |
This comment has been minimized.
This comment has been minimized.
|
Thanks for the pointer. The linked proposal document aligns very well with my research (and it even mentions Prometheus explicitly as a use case :). |
This comment has been minimized.
This comment has been minimized.
|
I noticed that :) The design also looks fairly similar to what your proposal is. Having two very similar control systems running on top of each other may cause undesirable interactions. |
brancz
referenced this issue
Mar 10, 2017
Closed
Enable control over Prometheus options, especially memory use #203
This comment has been minimized.
This comment has been minimized.
|
It's merged! Will be released in 1.6.0. |
beorn7
closed this
Mar 27, 2017
This comment has been minimized.
This comment has been minimized.
Eeemil
commented
Mar 13, 2019
|
|
This comment has been minimized.
This comment has been minimized.
|
See https://groups.google.com/forum/#!topic/prometheus-users/jU0Ghd_SyrQ It makes more sense to ask questions like this on the prometheus-users mailing list rather than in a GitHub issue (in particular if it is a closed GitHub issue). On the mailing list, more people are available to potentially respond to your question, and the whole community can benefit from the answers provided. |
beorn7 commentedJan 21, 2015
Currently, Prometheus simply limits the chunks in memory to a fixed number.
However, this number doesn't directly imply the total memory usage as many other things take memory as well.
Prometheus could measure its own memory consumption and (optionally) evict chunks early if it needs too much memory.
It's non-trivial to measure "actual" memory consumption in a platform independent way.