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 upLarge amount of metrics cause excessive traffic, target-side computation load #2686
Comments
This comment has been minimized.
This comment has been minimized.
This would require keeping a cache of every single scrape - which we would rarely get a hit on.
This wouldn't help with either. Determining the metadata requires the exact same work as determining the data, as metrics and time series can change from scrape to scrape. It's also really fast to parse. We also currently throw away the metadata. |
This comment has been minimized.
This comment has been minimized.
|
Does metrics metadata really change from scrape to scrape? I would imagine it doesn't (usually the monitored series doesn't change), so you'd need a cache the size of the number targets you monitor, and the hit rate would be 100%. We're probably not on the same page here. Here's the first 1k of a scrape:
There are about 7.5 metrics there, so each metric is ~ 136 bytes of data+metadata. ~128 bytes of metadata are exactly the same between scrapes, with just 8 bytes of data changing. |
This comment has been minimized.
This comment has been minimized.
|
@avikivity Prometheus's scrape protocol is very well-established, so I don't think such a change (that also makes the protocol and its implementations significantly more complex) will happen. Going back to your original problem report: "Everything is working smoothly. However, the target sends 1.2 MB per scrape, and has to spend a considerable effort to create the response. This creates latency in the thread that prepares the response." Is latency in the response-preparing thread a problem if that happens on an independent thread? What is the latency you are seeing? Do you know where the latency is actually coming from? From producing the values, or assembling them, or serializing, or sending them? |
This comment has been minimized.
This comment has been minimized.
|
@juliusv of course, such a change, if made, would not remove the 0.0.4 format but rather define a new format which would be supported in parallel. Existing clients would not be impacted. I don't think it's significantly more complex. You could still have a top-level
Targets can fill in metadata unconditionally if they don't care about reducing bandwidth. Back to my system, it is using a thread-per-core architecture with user-space scheduling (not unlike golang's) so I don't have independent threads. I can yield within the thread (similar to the I am seeing about 20ms latency from this code (includes assembling and serialization, but not production or transmission). This is running in a database which can serve requests in sub 1ms latency for the 99th percentile in some loads, so these 20ms have a huge impact. I plan to optimize it by having the message object survive from iteration to iteration with the and changing just the data (essentially applying my proposal for the assembly part), but that's just a band-aid that may buy me some time, but not solve the problem completely. |
brian-brazil
added
the
wont-fix
label
Jul 14, 2017
This comment has been minimized.
This comment has been minimized.
|
I think the best option here is to hand-assemble the text format with just the names and values, no metadata. |
brian-brazil
closed this
Jul 14, 2017
This comment has been minimized.
This comment has been minimized.
lock
bot
commented
Mar 23, 2019
|
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
avikivity commentedMay 8, 2017
What did you do?
I'm monitoring Scylla. The target exposes a large amount of metrics. Those metrics are per-cpu, so a target with 48 logical cores (not uncommon) has 48 times as many metrics as a target with 1 logical code (very rare).
What did you expect to see?
Everything working smoothly.
What did you see instead? Under which circumstances?
Everything is working smoothly. However, the target sends 1.2 MB per scrape, and has to spend a considerable effort to create the response. This creates latency in the thread that prepares the response.
Environment
Not relevant -- the problem is not in the Prometheus server, but in the target. But the problem can be fixed by improving the protocol (and Prometheus will benefit by having to process less data).
I think this could be much improved by using a "prepared statement" type of protocol. Instead of having a single scrape target, have two. This first one returns the metadata: all the various metrics, their types, and label sets, and creates a version number of the metadata. The second one accepts a metadata version number, and responds with just the metrics data if the version numbers match, or an error otherwise (prompting Prometheus to re-fetch the metadata). Alternative approaches are possible, perhaps a single get-if-changed endpoint that accepts the metadata version number in a header, and responds with just the data (on match) or both data and metadata (on mismatch).
This could reduce the size of the response by more than an order of magnitude, and reduce processing time for both the target and Prometheus significantly.