Explains strategies to scale Prometheus and achieve high availability including vertical and horizontal scaling, sharding, federation, aggregate metrics and Thanos integration.
In this video we’re going to be learning about how we canscale Prometheus, as well as implement high availability.So let’s say that we have a Prometheus server, and this Prometheusserver is configured to monitor several devices.Now over time, you’re going to see that you’re going to startadding more jobs, and your Prometheus server is going to be configuredto scrape more and more devices.And eventually, even though Prometheus is designed to scale, it’s going toeventually hit a limit, where once you have enough devices to monitor
and scrape configured, it’s eventually going to overwhelm Prometheus.And so you’ll see that Prometheus will start to have a littlebit of trouble maintaining and collecting all of these metrics.And on top of that, as you configure more and more jobsfor your Prometheus server, every time you make changes, youhave to restart your Prometheus server.And you may not think that this is that big of adeal, but keep in mind, every time you restart your Prometheus server,if you want to see current metrics, you might see slightly outdated
metrics because you have to wait for the next scrape intervalto collect the most recent data.And so if you’re constantly restarting your Prometheus server because you’re addingnew devices, it may become a little bit slow to use thatPrometheus server because you’re always waiting for it to collect the nextbatch of metrics, because you had to restart it.And so what’s the solution to this?How do we actually scale up Prometheus sothat we can monitor more devices?Well, I think it’s a pretty simple and obvious solution, which is,what if we use multiple Prometheus servers?And so that way, each Prometheus server gets its own set ofdevices that it collects metrics from, and it helpsus avoid hitting any scalability issues.We won’t have to worry about overwhelming our Prometheus server because eachPrometheus server only gets a subset of your different applications anddevices that it needs to monitor.Now, when it comes to scaling Prometheus, we have two different options.We have vertical scaling and horizontal scaling.So let’s start off by going over vertical scaling.And so in this case, you’re going to have two Prometheus servers,or you can have more than two, but we’ll just keepthis example as simple as possible.So we’ve got two Prometheus servers, and the idea behind vertical scalingis that one Prometheus server is responsible for managing one set ofapplications, services, or devices, and then another Prometheus server is responsible for
monitoring a different set of services or applications.And so if your team has, you know, if your organization hasmultiple different applications that they want to monitor, you mighthave one Prometheus manage, you know,PrometheusA manage a couple of those services, and then Prometheus B managea couple of the other services.So they’re all monitoring different applications, different devices, different servers.So with vertical scaling, we get a couple of benefits.One is it makes cardinality considerations more visible to the service owners,because you’re going to have, you know, maybe each team within yourcompany manages the Prometheus server that monitors their own application.So they have to be a little bit more careful on howthey set up the different labels and the cardinality of them, sothat they don’t overwhelm their own Prometheusserver, because they own it, right?They are the team that owns it because thatPrometheus server monitors just their application.Teams will feel both empowered and accountable for monitoring their specific servicesbecause they own that Prometheus instance.And it can enable more experimentation for rules and dashboards without the
fear of impacting other teams, because you can have a Prometheus serverfor each of the different teams within your organization.So you can kind of customize it however you want for yourteam without worrying about it potentially breaking things for another team.So now let’s take a look at horizontal scaling.So in this case, we’ve got one service called service A runningon a couple of different machines.And what you’re going to do with horizontal scaling is that forone scrape job, right, we have a scrape job for service A,we’re going to split that scrape job across multiple Prometheus servers.So we’ve got server one, server two, and we’regoing to perform what’s called sharding.So the Prometheus server one will cover, you know, in this case,half of the service A instances, and the second Prometheusinstance will cover the other half.So the main difference that I want to highlight is that vertical
scaling is they’re going to cover different services, different applications.Horizontal scaling is if you have a very large number of instancesfor one scrape job, you know, Prometheus might struggle with that.So you spread that one scrape job across multiple Prometheus servers.Okay, so let’s see how to configure horizontal sharding.And I want to give you an example of how to performthe horizontal scaling, because vertical scaling is easy.It’s just a different scrape job for each Prometheus server.Whereas for horizontal scaling, we have to split one scrape job.So I’m going to show you guys how to do that.So here on Prometheus server one, we’re going tohave our scrape job called node.
And what you have to do is, youperform this, you add this configuration.So you do relabel configs.And the first action is you’re going to match on the address.
So we want to get all of the differenttargets based off of their address.And we’re going to perform a hash mod.So it’s going to perform a hash on each one, and thenit’s going to perform a modulus operation.And we’d set the modulus value tobe the number of Prometheus instances.So if you want to spread the job across five Prometheus servers,you would set the modulus to five.And then we take the value that we get returned from performingthe modulus on the hash mod, and we add it to atemporary label called underscore underscore temp underscore underscore hash mod.And then we say we want to keep any metrics that havea label with __temp__hashmod set to a value of zero.So when you perform the modulus operation and you set it totwo, it’s going to start counting from zero.So it’s going to give you eithera value of zero or one.So when we say we want to keep the ones that havea value of zero, that means we’regoing to keep half of them.And then on the other Prometheus server, it’s the same exact configuration.But we set the regex value to be one.So Prometheus one is going to keep half the metrics, which isgoing to have a value of zero, and the other half isgoing to have a value of one.So that’s why we do that.If you had five Prometheus servers, thenyou would do zero through four.And you’re going to see that after you do that, it’s going
to split all of your targets.You’re going to have roughly, and it may not be exactly fiftypercent, but you’re going to have ideally close to fifty percent onPrometheus one and the other fifty percent on Prometheus two.
And one thing I want to highlight is all of your targetsshould be configured on all of your Prometheus servers.So if you have one hundred targets, you don’t configure fifty on
one and then fifty on another.You configure all one hundred on both of them.And then this relabel config will make sure that it onlykeeps the metrics that it needs.Now, when it comes to assisting with Prometheus and helping it scaleup, if you’re finding that your Prometheus server is getting a littleslow or it’s having a hard time keeping up, one of thethings that you can do, if this is an option for your
organization, is you can modify the scrape interval for your jobs.So instead of scraping it every fifteen seconds, maybe do one minute.You know, if you don’t have to scrape as often, then youdon’t have to worry about your Prometheus server getting overwhelmed because itdoesn’t have to scrape all those metrics as frequently as possible.So that’s one option that you have at your disposal tohelp your Prometheus server scale up.If you don’t want to perform vertical scaling or horizontal scaling, ifyou want to just keep it as one Prometheus server, thisis one option that you have.Now another option that you have to kind of help prevent your
yamlscrape_configs: - job_name: 'slow-metrics-job' scrape_interval: 1m # Scrape every 1 minute instead of the default static_configs: - targets: ['localhost:9100']
Prometheus server from getting overwhelmed is to add a sample limit.Now this is almost like a security mechanism because it sets alimit to the number of time series that canbe returned by a single scrape.And so if the limit is exceeded, the scrape isgoing to be considered a failure.So in this case, we set it to ten thousand.
yamlscrape_configs: - job_name: 'example' static_configs: - targets: ['localhost:8080'] sample_limit: 10000 # This job will only ingest 10,000 samples per scrape
So if we have a little scrape job and we receive overten thousand metrics, just, you know, potentially due to a misconfiguration orsomething like that, that causes us to receive too many metrics, then
yamlscrape_configs: - job_name: 'example' static_configs: - targets: ['localhost:8080'] sample_limit: 10000 # This job will only ingest 10,000 samples per scrape
we will just drop it, just so that we can avoidour Prometheus server from getting overloaded.So now let’s move on to a feature called federation.So let’s say that we have three datacenters.Now, a common deployment option when it comes to Prometheus is, youwould deploy a Prometheus server for each data center.And this would be a form of horizontal scaling because, you know,they’re going to be scraping different things.The first Prometheus server will handle data center one, the second onewill handle data center two, and the thirdone will handle data center three.So you can break up all of those instances for each datacenterand spread them out to three different Prometheus servers.The problem with this is that you as the user, if youwant to get some metrics, if you want to get metrics fromdatacenter one, you’d have to go and connect to that Prometheus server.If you want to get metrics from datacenter 2, you’re going tohave to connect to that one.And if you want to get metrics from datacenter three, you’re goingto have to connect to that Prometheus server.So you have to be able toconnect to all three Prometheus servers.And we as human beings don’t really want to do that.We don’t want to have to go and connectto different devices to get information.And on top of that, we don’t actually have a way tosee data across all of our data centers in one single placebecause each Prometheus server manages its own data center.And ideally, as human beings, we want tohave a single pane of glass.I want to be able to connect to one application or oneweb browser and be able to see everythingacross all of my data centers.It’s going to simplify my life and make it alot easier to monitor our infrastructure.And so what we can do with Prometheus is we can actuallydeploy a fourth Prometheus server, and we’llcall this the global Prometheus server.And that Prometheus server will aggregate metrics from the three individual Prometheusservers that we assigned to each data center.And then we, as the infrastructure team, or the monitoring team, orthe DevOps team, we can then connect to the global Prometheus serverto get information about all of ourdata centers in one single location.So, how do we configure a global Prometheus server tocollect metrics from other Prometheus servers?Well, it’s actually pretty simple.So, we configure another job.And here, under the targets, this is going to be our individualPrometheus servers, so the ones for each data center.So you just put the IP addresses and then the port thatPrometheus is running on, whose default is nine zero nine zero.And then the metrics path, it’s going to, you know, each Prometheus
server will expose the metrics it’s collectedon a path called slash federate.So we want to tell it to scrape that specific path.And then we have to tell the global Prometheusserver which metrics do we want.So you do params, then you do match, and then you haveto match on some specific label.So in this case, this will collect every single metric witha label of job equals node.
You could specify whichever metrics you want.In general, you don’t want to collect all the metrics, you wantto collect a very specific subset that you’re interested in.And then finally, we have to set the honor labels to true,
which is going to prevent the global Prometheusserver from overriding the original labels.We want to keep the original labels.So we keep honor labels, set that to true.So now we’ve got the federation configured.And so Prometheus, the global Prometheus server, will now be ableto collect all of the metrics.But there’s just one problem.If all of the metrics that were collected by the individual Prometheusservers get sent to the global Prometheus server, well, that ultimately defeatsthe purpose of us performing that vertical scaling, right?We separated each data center out with their own Prometheus serverso that we didn’t overwhelm them.But then if we take all the metrics from each Prometheus serverand then send it to one individual Prometheusserver, it’s going to overwhelm that.So we don’t ever want to just send all of our metricsto the global Prometheus server, because we’re going to overwhelm it.And it would defeat the purpose of having multiple Prometheus servers, becausewe want to limit the amount ofmetrics each one has to handle.So instead, what we should ideally want to do is, instead ofsending regular instance-level metrics, right, so metrics for each individual target, what
Job="node"
we want to do is we wantto actually only send aggregate metrics.So you’re going to set up some kind of recording rule tocollect some sort of aggregate metric.In this case, we’ve got two of them here with the CPUusage for a specific job and the entire data center.And then we also have the memoryavailable across our entire data center.So these are like big-picture aggregate information about an entire data center
yamlgroups: - name: aggregated-node-metrics rules: # CPU usage by job - record: node:cpu_seconds:sum_rate5m expr: sum(rate(node_cpu_seconds_total[5m])) by (job) # Memory usage by job - record: node:memory_MemAvailable_bytes:sum expr: sum(node_memory_MemAvailable_bytes) by (job)
that would be interesting for us to know.And we would configure this on both of the Prometheus servers.And then what we would do is, on our global Prometheus server,we would tell it that instead of collecting all the metrics forthe node job, which would overwhelm our Prometheus server, we want toactually collect just those aggregate metrics that we configured.And this is going to limit the metrics that get
sent to the global Prometheus server.Because ultimately, we only care about big picturethings in the global Prometheus server.We want to see high-level metrics.And we don’t want to overwhelm the globalPrometheus server with instance-level, target-level metrics.
Right.And so now we’re just sending aggregate metrics.And that should allow our global Prometheus server to not be overwhelmed.But there is still one last problem.When we send these aggregate metrics, they’re going to have somesort of label associated with them.It may not be job equals node, but they’re all goingto have the exact same labels.And so if you have two Prometheus servers sending the same metricwith the same exact labels, what’s going to happen is one ofthem is going to get dropped because the global Prometheus server isgoing to think that it’s a duplicate metric.So we need a way to make these metrics unique so that
we can know that one is for data center one and theother is for data center two.How do we do that?Well, we’re going to, essentially, for all the metrics coming from datacenterone, we’re going to add a labelcalled datacenter equals d c one.And then for datacenter two, we’re going to add alabel that says datacenter equals DC2.And so since they have this extra label, it’s going to makesure that the metrics are unique between the two data centers.
And so the global Prometheus server will keep both of them.How do we do that?Very simple.We just add this config where we do relabel underscore configs, setthe target label to data center, and then set replacement, which isgoing to set the value to be D C one.And then the same thing goes for Prometheus two, but we justset that to be DC two.
And then in the recording rules, we want to make sure thatwe add data center here when we do the group by, sothat it’s going to add those metrics there as well.
yamlgroups: - name: aggregated-node-metrics rules: # CPU usage by job - record: node:cpu_seconds:sum_rate5m expr: sum(rate(node_cpu_seconds_total[5m])) by (job, datacenter) # Memory usage by job - record: node:memory_MemAvailable_bytes:sum expr: sum(node_memory_MemAvailable_bytes) by (job, datacenter)
And so then on our global Prometheus server, we can search forthese metrics and filter based off of whether it’s DC one wewant, or if we want DC two, we could just say DCtwo, and we’ll be able to filter downbased off a specific data center.
_node:cpu_seconds:sum_rate5m{datacenter="dc2"}
And so with federation, I want to highlight that federation is notfor copying the contents of an entire Prometheus server.So in your global Prometheus server, you do not wantto copy all of the metrics.And more importantly, federation is not a way to have one Prometheusserver proxy to another Prometheus server.That is not the purpose of it.And you should not use federation topull metrics with an instance label.If you’re pulling any metrics with aninstance label, you’re doing it wrong.You need to be focusing on big picture aggregate metrics and notmetrics for a specific application or a specific server.
You want big picture metrics.Now, if you do want a single pane of glass where youcan monitor and take a look at metrics from multiple Prometheus servers,and you don’t want to use federation because you don’t want tofocus on, you know, aggregate metrics or things like that, youcan also utilize something like Thanos.So Thanos has this ability where you can send a query toThanos, and Thanos can then basically spread that query out to multiplePrometheus servers and then kind of aggregate it for you so thatyou can see everything all in one single location.And so that is one option that you have.And we kind of already covered Thanos a little bit about whenwe were going over how long-term storage