Prometheus
Prometheus是一套開源的監(jiān)控&報警&時間序列數據庫的組合,起始是由SoundCloud公司開發(fā)的。成立于2012年,之后許多公司和組織接受和采用prometheus,他們便將它獨立成開源項目,并且有公司來運作.該項目有非?;钴S的社區(qū)和開發(fā)人員,目前是獨立的開源項目,任何公司都可以使用它,2016年,Prometheus加入了云計算基金會,成為kubernetes之后的第二個托管項目.google SRE的書內也曾提到跟他們BorgMon監(jiān)控系統(tǒng)相似的實現是Prometheus。現在最常見的Kubernetes容器管理系統(tǒng)中,通常會搭配Prometheus進行監(jiān)控。
特性
prometheus的主要特點
- 自定義多維數據模型(時序列數據由metric名和一組key/value標簽組成)
- 非常高效的存儲 平均一個采樣數據占 ~3.5 bytes左右,320萬的時間序列,每30秒采樣,保持60天,消耗磁盤大概228G。
- 在多維度上靈活且強大的查詢語言(PromQl)
- 不依賴分布式存儲,支持單主節(jié)點工作
- 通過基于HTTP的pull方式采集時序數據
- 可以通過push gateway進行時序列數據推送(pushing)
- 可以通過服務發(fā)現或者靜態(tài)配置去獲取要采集的目標服務器
- 多種可視化圖表及儀表盤支持
pull方式
Prometheus采集數據是用的pull也就是拉模型,通過HTTP協(xié)議去采集指標,只要應用系統(tǒng)能夠提供HTTP接口就可以接入監(jiān)控系統(tǒng),相比于私有協(xié)議或二進制協(xié)議來說開發(fā)、簡單。
push方式
對于定時任務這種短周期的指標采集,如果采用pull模式,可能造成任務結束了,Prometheus還沒有來得及采集,這個時候可以使用加一個中轉層,客戶端推數據到Push Gateway緩存一下,由Prometheus從push gateway pull指標過來。(需要額外搭建Push Gateway,同時需要新增job去從gateway采數據)
prometheus適用于監(jiān)控所有時間序列的項目
目前其生態(tài)中已經有很多exporter實現,例如:
- Node/system metrics exporter
- AWS CloudWatch exporter
- Blackbox exporter
- Collectd exporter
- Consul exporter
- Graphite exporter
- HAProxy exporter
- InfluxDB exporter
- JMX exporter
- Memcached exporter
- Mesos task exporter
- MySQL server exporter
- SNMP exporter
- StatsD exporter
組成及架構
Prometheus生態(tài)系統(tǒng)由多個組件組成。其中許多組件都是可選的
-
Prometheus server
主要負責數據采集和存儲,提供PromQL查詢語言的支持
-
客戶端sdk官方提供的客戶端類庫:
go、java、scala、python、ruby,其他還有很多第三方開發(fā)的類庫,支持nodejs、php、erlang等
-
Push Gateway
支持臨時性Job主動推送指標的中間網關
-
PromDash
使用rails開發(fā)的dashboard,用于可視化指標數據
-
exporters
支持其他數據源的指標導入到Prometheus,支持數據庫、硬件、消息中間件、存儲系統(tǒng)、http服務器、jmx等
-
alertmanager
實驗性組件、用來進行報警
-
prometheus_cli
命令行工具
其他輔助性工具
prometheus大多數組件都是用Go編寫的,他們可以非常輕松的基于二進制文件部署和構建
它的服務過程是這樣的 Prometheus Server 負責定時去目標上抓取 metrics(指標) 數據,每個抓取目標需要暴露一個http服務的接口給它定時抓取。
Prometheus支持通過配置文件、kubernetes、zookeeper、Consul、DNS SRV lookup等方式指定抓取目標。
Alertmanager 是獨立于Prometheus的一個組件,可以支持Prometheus的查詢語句編寫規(guī)則,提供十分靈活的報警方式。
Prometheus支持很多方式的圖表可視化,例如十分精美的Grafana,自帶的Promdash,以及自身提供的模版引擎等等,還提供HTTP API的查詢方式,自定義所需要的輸出。
PushGateway這個組件是支持Client主動推送 metrics 到PushGateway,而Prometheus只是定時去Gateway上抓取數據。
如果有使用過statsd的用戶,則會覺得這十分相似,只是statsd是直接發(fā)送給服務器端,而Prometheus主要還是靠進程主動去抓取。
概念
Prometheus 的數據模型
Prometheus 從根本上所有的存儲都是按時間序列去實現的,相同的 metrics(指標名稱) 和 label(一個或多個標簽) 組成一條時間序列,不同的label表示不同的時間序列。為了支持一些查詢,有時還會臨時產生一些時間序列存儲。
metrics name & label 指標名稱和標簽
每條時間序列是由唯一的 指標名稱 和 一組 標簽 (key=value)的形式組成。
-
指標名稱
一般是給監(jiān)測對像起一名字,例如 http_requests_total 這樣,它有一些命名規(guī)則,可以包字母數字之類的的。通常是以應用名稱開頭監(jiān)測對像數值類型單位這樣。例如:
- push_total - userlogin_mysql_duration_seconds - app_memory_usage_bytes
-
標簽
就是對一條時間序列不同維度的識別了,例如 一個http請求用的是POST還是GET,它的endpoint是什么,這時候就要用標簽去標記了。最終形成的標識便是這樣了http_requests_total{method="POST",endpoint="/api/tracks"}
記住,針對http_requests_total這個metrics name 無論是增加標簽還是刪除標簽都會形成一條新的時間序列。
查詢語句就可以跟據上面標簽的組合來查詢聚合結果了。
如果以傳統(tǒng)數據庫的理解來看這條語句,則可以考慮 http_requests_total是表名,標簽是字段,而timestamp是主鍵,還有一個float64字段是值了。(Prometheus里面所有值都是按float64存儲)
Prometheus 的四種數據類型
Counter
Counter 用于累計值,例如 記錄 請求次數、任務完成數、錯誤發(fā)生次數。
一直增加,不會減少。
-
重啟進程后,會被重置。
例如:http_response_total{method="GET",endpoint="/api/tracks"} 10 10秒后抓取 http_response_total{method="GET",endpoint="/api/tracks"} 100
Gauge
Gauge 常規(guī)數值,例如 溫度變化、CPU,內存,網絡使用變化。
可變大,可變小。
-
重啟進程后,會被重置
例如: memory_usage_bytes{host="master-01"} 100 < 抓取值 memory_usage_bytes{host="master-01"} 30 memory_usage_bytes{host="master-01"} 50 memory_usage_bytes{host="master-01"} 80 < 抓取值
Histogram
Histogram 可以理解為柱狀圖的意思,常用于跟蹤事件發(fā)生(通常是請求持續(xù)時間或響應大小)的規(guī)模,例如:請求耗時、響應大小。它特別之處是可以對記錄的內容進行分組,提供 count 和 sum 全部值的功能。
例如:{小于10=5次,小于20=1次,小于30=2次},count=7次,sum=7次的求和值

Summary
Summary和Histogram十分相似,常用于跟蹤事件(通常是要求持續(xù)時間和響應大小)發(fā)生的規(guī)模,例如:請求耗時、響應大小。同樣提供 count 和 sum 全部值的功能。
例如:count=7次,sum=7次的值求值
它提供一個quantiles的功能,可以按%比劃分跟蹤的結果。例如:quantile取值0.95,表示取采樣值里面的95%數據。
Jobs and Instances
在prometheus中,任何被采集的目標被稱為instance,通常對應于單個進程,而相同類型(可擴展性和可靠性的復制)的instance集合被稱為Job。例如:Api server job由4個復制instance組成:
- job: api-server
- instance1: 1.2.3.4:5670
- instance2: 1.2.3.4:5671
- instance3: 5.6.7.8:5670
- instance3: 5.6.7.8:5671
自動生成標簽和時間序列
當prometheus采集目標時,它會自動附加某些標簽,用于識別被采集的目標。
- job: 配置目標所屬的job名稱
- instance: 目標 HTTP URL<host>:<port>部分
如果任何一個標簽已經存在于采集的數據中,則此行為依賴honor_labels 配置選項。
對于每個被采集的instance,prometheus存儲如下的時間序列樣本:
- up{job="<job-name>",instance="<instance-id>"}:1 如果實例處于health,為1,否則為0
- scrape_duration_seconds{job="<job-name>",instance="<instance-id>"} 持續(xù)采集時間
“up”時間序列metric對于instance可用性監(jiān)控是有效的。