Prometheus 存儲(chǔ)的是時(shí)序數(shù)據(jù), 即按照相同時(shí)序(相同的名字和標(biāo)簽),以時(shí)間維度存儲(chǔ)連續(xù)的數(shù)據(jù)的集合。
時(shí)序
時(shí)序(time series) 是由名字(Metric),以及一組 key/value 標(biāo)簽定義的。具有相同的名字以及相同的標(biāo)簽則屬于相同時(shí)序。
時(shí)序的名字由 ASCII 字符,數(shù)字,下劃線,以及冒號(hào)組成。它的名字應(yīng)該具有語(yǔ)義化,一般表示一個(gè)可以度量的指標(biāo),例如: http_requests_total, 可以表示 http 請(qǐng)求的總數(shù)。
時(shí)序的標(biāo)簽可以使 Prometheus 的數(shù)據(jù)更加豐富,例如 http_requests_total{method="POST"} 可以表示所有 http 中的 POST 請(qǐng)求。
時(shí)序數(shù)據(jù)的4種類型
時(shí)序數(shù)據(jù)可以分為以下4種類型:
- Counter: Counter 表示收集的數(shù)據(jù)是按照某個(gè)趨勢(shì)(增加/減少)一直變化的,我們往往用它記錄服務(wù)請(qǐng)求總量、錯(cuò)誤總數(shù)等。例如 Prometheus server 中 http_requests_total, 表示 Prometheus 處理的 http 請(qǐng)求總數(shù),我們可以使用 delta, 很容易得到任意區(qū)間數(shù)據(jù)的增量。
- Gauge: Gauge 表示搜集的數(shù)據(jù)是一個(gè)瞬時(shí)的值,與時(shí)間沒(méi)有關(guān)系,可以任意變高變低,往往可以用來(lái)記錄內(nèi)存使用率、磁盤使用率等。例如 Prometheus server 中 go_goroutines, 表示 Prometheus 當(dāng)前 goroutines 的數(shù)量。
- Histogram: Histogram 由 <basename>_bucket{le="<upper inclusive bound>"},<basename>_bucket{le="+Inf"}, <basename>_sum,<basename>_count 組成,主要用于表示一段時(shí)間范圍內(nèi)對(duì)數(shù)據(jù)進(jìn)行采樣(通常是請(qǐng)求持續(xù)時(shí)間或響應(yīng)大小),并能夠?qū)ζ渲付▍^(qū)間以及總數(shù)進(jìn)行統(tǒng)計(jì),通常它采集的數(shù)據(jù)展示為直方圖。
- Summary: Summary 和 Histogram 類似,由 <basename>{quantile="<φ>"},<basename>_sum,<basename>_count 組成,主要用于表示一段時(shí)間內(nèi)數(shù)據(jù)采樣結(jié)果(通常是請(qǐng)求持續(xù)時(shí)間或響應(yīng)大?。苯哟鎯?chǔ)了 quantile 數(shù)據(jù),而不是根據(jù)統(tǒng)計(jì)區(qū)間計(jì)算出來(lái)的。
關(guān)于Histogram和Summary:
Histogram和Summary主用用于統(tǒng)計(jì)和分析樣本的分布情況。例如,統(tǒng)計(jì)延遲在010ms之間的請(qǐng)求數(shù)有多少而1020ms之間的請(qǐng)求數(shù)又有多少。通過(guò)這種方式可以快速分析系統(tǒng)慢的原因。Histogram和Summary都是為了能夠解決這樣問(wèn)題的存在,通過(guò)Histogram和Summary類型的監(jiān)控指標(biāo),我們可以快速了解監(jiān)控樣本的分布情況。
例如下面一個(gè)Summary類型的metric:
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.5"} 0.012352463
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.9"} 0.014458005
prometheus_tsdb_wal_fsync_duration_seconds{quantile="0.99"} 0.017316173
prometheus_tsdb_wal_fsync_duration_seconds_sum 2.888716127000002
prometheus_tsdb_wal_fsync_duration_seconds_count 216
表示當(dāng)前Prometheus Server進(jìn)行wal_fsync操作的總次數(shù)為216次,總耗時(shí)2.888716127000002s。其中耗時(shí)小于0.012352463秒的樣本占比50%,耗時(shí)小于0.014458005的樣本占比90%,而耗時(shí)小于0.017316173的樣本占比99%。因此,這個(gè)quanatile表示百分位數(shù),代表了相應(yīng)樣本值在總樣本中的分布比例。
下面是一個(gè)Histogram類型的mertric:
prometheus_tsdb_compaction_chunk_range_bucket{le="100"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="400"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="1600"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="6400"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="25600"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="102400"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="409600"} 0
prometheus_tsdb_compaction_chunk_range_bucket{le="1.6384e+06"} 260
prometheus_tsdb_compaction_chunk_range_bucket{le="6.5536e+06"} 780
prometheus_tsdb_compaction_chunk_range_bucket{le="2.62144e+07"} 780
prometheus_tsdb_compaction_chunk_range_bucket{le="+Inf"} 780
prometheus_tsdb_compaction_chunk_range_sum 1.1540798e+09
prometheus_tsdb_compaction_chunk_range_count 780
Histogram類型的樣本同樣會(huì)反應(yīng)當(dāng)前指標(biāo)的記錄的總數(shù)(以_count作為后綴)以及其值的總量(以_sum作為后綴)。不同在于Histogram指標(biāo)直接反應(yīng)了在不同區(qū)間內(nèi)樣本的個(gè)數(shù)。例如上面的指標(biāo)表示 tsdb_compaction_chunk 的值小于 1.6384e+06 的個(gè)數(shù)為260個(gè),小于 6.5536e+06 的個(gè)數(shù)為780,小于 2.62144e+07 的個(gè)數(shù)為780,小于最高值的個(gè)數(shù)為780。tsdb_compaction_chunk值得總量為 1.1540798e+09(_sum指標(biāo))。指標(biāo)記錄總數(shù)為 780(_count指標(biāo))。
注意后面的采樣點(diǎn)是包含前面的采用點(diǎn)的,例如xxx_bucket的值為30,而xxx_bucket的值為120,那么意味著這120個(gè)采用點(diǎn)中,有30個(gè)是小于10ms的,其余90個(gè)采樣點(diǎn)的響應(yīng)時(shí)間是介于10ms和50ms之間的。而+Inf是最高bucket的上限值,所以xxx_bucket是所有采樣點(diǎn)的數(shù)量,是Prometheus自動(dòng)增加的一個(gè)bucket。
同時(shí)對(duì)于Histogram的指標(biāo),我們還可以通過(guò)histogram_quantile()函數(shù)計(jì)算出其值的百分位數(shù)(quantile)。不同在于Histogram通過(guò)histogram_quantile函數(shù)是在服務(wù)器端計(jì)算的百分位數(shù)。 而Sumamry的百分位數(shù)則是直接在客戶端計(jì)算完成。因此對(duì)于百分位數(shù)的計(jì)算而言,Summary在通過(guò)PromQL進(jìn)行查詢時(shí)有更好的性能表現(xiàn),而Histogram則會(huì)消耗更多的資源。反之對(duì)于客戶端而言Histogram消耗的資源更少。在選擇這兩種方式時(shí)用戶應(yīng)該按照自己的實(shí)際場(chǎng)景進(jìn)行選擇。
更多關(guān)于百分位數(shù)(quantile)的討論,請(qǐng)參考:https://cloud.tencent.com/developer/news/319419
Job和instance
Prometheus 中,將任意一個(gè)獨(dú)立的數(shù)據(jù)源(target)稱之為實(shí)例(instance)。包含相同類型的實(shí)例的集合稱之為作業(yè)(job)。 如下是一個(gè)含有四個(gè)重復(fù)實(shí)例的作業(yè):
- job: api-server
- instance 1: 1.2.3.4:5670
- instance 2: 1.2.3.4:5671
- instance 3: 5.6.7.8:5670
- instance 4: 5.6.7.8:5671
這個(gè)job中包含了四個(gè)數(shù)據(jù)源,例如 1.2.3.4:5670 就是一個(gè)數(shù)據(jù)源(targe),Prometheus會(huì)定時(shí)從數(shù)據(jù)源中拉取數(shù)據(jù)存儲(chǔ)為metric。
對(duì)于每一個(gè)實(shí)例,Prometheus都會(huì)為其存儲(chǔ)以下metric:
up{job="<job-name>", instance="<instance-id>"}: 0 表示該實(shí)例故障,1 表示該實(shí)例正常工作
scrape_duration_seconds{job="<job-name>", instance="<instance-id>"} 表示拉取數(shù)據(jù)的時(shí)間間隔
scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"} 表示采用重定義標(biāo)簽(relabeling)操作后仍然剩余的樣本數(shù)
scrape_samples_scraped{job="<job-name>", instance="<instance-id>"} 表示從該數(shù)據(jù)源獲取的樣本數(shù)
其中 up metric可以有效應(yīng)用于監(jiān)控該實(shí)例是否正常工作。
PromQL使用
PromQL (Prometheus Query Language) 是 Prometheus 自己開發(fā)的數(shù)據(jù)查詢 DSL 語(yǔ)言,語(yǔ)言表現(xiàn)力非常豐富,內(nèi)置函數(shù)很多,在日常數(shù)據(jù)可視化以及rule 告警中都會(huì)使用到它。
Prometheus 存儲(chǔ)的是時(shí)序數(shù)據(jù),而它的時(shí)序是由名字和一組標(biāo)簽構(gòu)成的。一個(gè)簡(jiǎn)單的查詢相當(dāng)于是對(duì)各種標(biāo)簽的篩選,例如:
http_requests_total{code="200"} // 表示查詢名字為 http_requests_total,code 為 "200" 的數(shù)據(jù)
http_requests_total{code!="200"} // 表示查詢 code 不為 "200" 的數(shù)據(jù)
http_requests_total{code=~"2.."} // 表示查詢 code 為 "2xx" 的數(shù)據(jù)
http_requests_total{code!~"2.."} // 表示查詢 code 不為 "2xx" 的數(shù)據(jù)
http_requests_total[5m] 范圍區(qū)間查詢: 過(guò)去 5 分鐘數(shù)據(jù)
配置文件
Prometheus 啟動(dòng)的時(shí)候,可以加載運(yùn)行參數(shù) -config.file 指定配置文件,默認(rèn)為 prometheus.yml。下面是一個(gè)典型的配置文件樣例:
global:
scrape_interval: 15s # By default, scrape targets every 15 seconds.
evaluation_interval: 15s # By default, scrape targets every 15 seconds.
rule_files:
- "rules/node.rules"
scrape_configs:
- job_name: 'prometheus'
scrape_interval: 5s
static_configs:
- targets: ['localhost:9090']
- job_name: 'node'
scrape_interval: 8s
static_configs:
- targets: ['127.0.0.1:9100', '127.0.0.12:9100']
- job_name: 'mysqld'
static_configs:
- targets: ['127.0.0.1:9104']
- job_name: 'memcached'
static_configs:
- targets: ['127.0.0.1:9150']
Exporter
在 Prometheus 中負(fù)責(zé)數(shù)據(jù)匯報(bào)的程序統(tǒng)一叫做 Exporter, 而不同的 Exporter 負(fù)責(zé)不同的業(yè)務(wù)。 它們具有統(tǒng)一命名格式,即 xx_exporter, 例如負(fù)責(zé)主機(jī)信息收集的 node_exporter。
一個(gè) Exporter 本質(zhì)上就是將收集的數(shù)據(jù),轉(zhuǎn)化為對(duì)應(yīng)的文本格式,并提供 http 請(qǐng)求。Exporter 收集的數(shù)據(jù)轉(zhuǎn)化的文本內(nèi)容以行 (\n) 為單位,空行將被忽略, 文本內(nèi)容最后一行為空行。
下面是一個(gè)Exporter收集的樣本數(shù)據(jù)的例子:
# HELP node_cpu Seconds the cpus spent in each mode.
# TYPE node_cpu counter
node_cpu{cpu="cpu0",mode="idle"} 362812.7890625
# HELP node_load1 1m load average.
# TYPE node_load1 gauge
node_load1 3.0703125
- 以 # HELP 開頭表示 metric 幫助說(shuō)明。
- 以 # TYPE 開頭表示定義 metric 類型,包含 counter, gauge, histogram, summary, 和 untyped 類型。
- 其他表示一般注釋,供閱讀使用,將被 Prometheus 忽略。
告警
告警能力在Prometheus的架構(gòu)中被劃分成兩個(gè)獨(dú)立的部分。通過(guò)在Prometheus中定義AlertRule(告警規(guī)則),Prometheus會(huì)周期性的對(duì)告警規(guī)則進(jìn)行計(jì)算,如果滿足告警觸發(fā)條件就會(huì)向Alertmanager發(fā)送告警信息。
在 Prometheus 中告警分為兩部分:
- Prometheus 服務(wù)根據(jù)所設(shè)置的告警規(guī)則將告警信息發(fā)送給 Alertmanager。
- Alertmanager 對(duì)收到的告警信息進(jìn)行處理,包括去重,降噪,分組,策略路由告警通知。
使用告警服務(wù)主要的步驟如下:
- 下載配置 Alertmanager。
- 通過(guò)設(shè)置 -alertmanager.url 讓 Prometheus 服務(wù)與 Alertmanager 進(jìn)行通信。
- 在 Prometheus 服務(wù)中設(shè)置告警規(guī)則。
告警規(guī)則
在Prometheus中一條告警規(guī)則主要由以下幾部分組成:
- 告警名稱:用戶需要為告警規(guī)則命名,當(dāng)然對(duì)于命名而言,需要能夠直接表達(dá)出該告警的主要內(nèi)容。
- 告警規(guī)則:告警規(guī)則實(shí)際上主要由PromQL進(jìn)行定義,其實(shí)際意義是當(dāng)表達(dá)式(PromQL)查詢結(jié)果持續(xù)多長(zhǎng)時(shí)間(During)后出發(fā)告警。
一個(gè)典型的告警規(guī)則如下:
groups:
- name: example
rules:
- alert: HighErrorRate
expr: job:request_latency_seconds:mean5m{job="myjob"} > 0.5
for: 10m
labels:
severity: page
annotations:
summary: High request latency
description: description info
- alert:告警規(guī)則的名稱。
- expr:基于PromQL表達(dá)式告警觸發(fā)條件,用于計(jì)算是否有時(shí)間序列滿足該條件。
- for:評(píng)估等待時(shí)間,可選參數(shù)。用于表示只有當(dāng)觸發(fā)條件持續(xù)一段時(shí)間后才發(fā)送告警。在等待期間新產(chǎn)生告警的狀態(tài)為pending。
- labels:自定義標(biāo)簽,允許用戶指定要附加到告警上的一組附加標(biāo)簽。
- annotations:用于指定一組附加信息,比如用于描述告警詳細(xì)信息的文字等,annotations的內(nèi)容在告警產(chǎn)生時(shí)會(huì)一同作為參數(shù)發(fā)送到Alertmanager。
AlertManager
Alertmanager擁有以下特性:
- 分組:分組機(jī)制可以將詳細(xì)的告警信息合并成一個(gè)通知,避免一次性接受大量的告警通知,而無(wú)法對(duì)問(wèn)題進(jìn)行快速定位。
- 抑制:抑制是指當(dāng)某一告警發(fā)出后,可以停止重復(fù)發(fā)送由此告警引發(fā)的其它告警的機(jī)制。
- 靜默:提供了一個(gè)簡(jiǎn)單的機(jī)制可以快速根據(jù)標(biāo)簽對(duì)告警進(jìn)行靜默處理。如果接收到的告警符合靜默的配置,Alertmanager則不會(huì)發(fā)送告警通知。
Alertmanager主要負(fù)責(zé)對(duì)Prometheus產(chǎn)生的告警進(jìn)行統(tǒng)一處理,因此在Alertmanager配置中一般會(huì)包含以下幾個(gè)主要部分:
- 全局配置(global):用于定義一些全局的公共參數(shù),如全局的SMTP配置,Slack配置等內(nèi)容;
- 模板(templates):用于定義告警通知時(shí)的模板,如HTML模板,郵件模板等;
- 告警路由(route):根據(jù)標(biāo)簽匹配,確定當(dāng)前告警應(yīng)該如何處理;
- 接收人(receivers):接收人是一個(gè)抽象的概念,它可以是一個(gè)郵箱也可以是微信,Slack或者Webhook等,接收人一般配合告警路由使用;
- 抑制規(guī)則(inhibit_rules):合理設(shè)置抑制規(guī)則可以減少垃圾告警的產(chǎn)生