天天看點

5分鐘了解Prometheus

Prometheus(譯:普羅米修斯)用領先的開源監控解決方案為你的名額和警報提供動力(賦能)。

5分鐘了解Prometheus

1.  概述

1.1.  Prometheus是什麼?

Prometheus是一個開源的系統監控和警報工具包。自2012年啟動以來,許多公司群組織都采用了Prometheus,該項目擁有非常活躍的開發人員和使用者社群。它現在是一個獨立的開源項目,獨立于任何公司進行維護。Prometheus于2016年加入雲原生計算基金會,成為繼Kubernetes之後的第二個托管項目。

1.1.1.  Prometheus的主要特性:

  • 一個多元資料模型,包含由名額名稱和鍵/值對(Tag)辨別的時間序列資料
  • PromQL是一種靈活的查詢語音,用于查詢并利用這些次元資料
  • 不依賴分布式存儲,單個伺服器節點是自治的
  • 時間序列收集是通過HTTP上的pull模型進行的(支援Pull)
  • 推送時間序列是通過一個中間網關來支援的(也支援Push)
  • 目标是通過服務發現或靜态配置發現的
  • 多種模式的圖形和儀表盤支援

總結一下,就是多元資料模型、PromQL查詢語言、節點自治、HTTP主動拉取或者網關主動推送的方式擷取時間序列資料、自動發現目标、多種儀表盤支援

1.1.2.  元件:

  • Prometheus server,它負責抓取和存儲時間序列資料,是最主要的元件
  • client libraries,用于檢測應用程式代碼的用戶端庫
  • push gateway,用于支援短期的jobs
  • exporters,用于支援HAProxy等第三方
  • alertmanager,用于處理告警
  • 各種支援工具

大多數Prometheus元件都是用Go編寫的,這使得它們易于作為靜态二進制檔案建構和部署

1.1.3.  架構:

這張圖展示了架構及其生态系統的一些組成部分:

5分鐘了解Prometheus

Prometheus從工具化的作業中擷取名額,要麼直接擷取,要麼通過中介推送網關擷取短期作業。它在本地存儲所有抓取的樣本,并對這些資料應用規則将這些資料進行聚合,并記錄新的時間序列,或者生成警報。可以用Grafana或其他API來可視化收集的資料。

1.2.  什麼時候用它合适

Prometheus可以很好地記錄任何純數字時間序列。它既适合以機器為中心的監視,也适合高度動态的面向服務的體系結構的監視。在微服務的世界中,它對多元資料收集和查詢的支援是一個特别的優勢。

Prometheus是為可靠性而設計的,在你的服務當機的時候,你可以快速診斷問題。每台Prometheus伺服器都是獨立的,不依賴于網絡存儲或其他遠端服務。

1.3.  什麼時候用它不合适

Prometheus的值的可靠性。你總是可以檢視有關系統的統計資訊,即使在出現故障的情況下也是如此。如果你需要100%的準确性,例如按請求計費,Prometheus不是一個好的選擇,因為收集的資料可能不夠詳細和完整。在這種情況下,最好使用其他系統來收集和分析用于計費的資料,并使用Prometheus來完成剩下的監視工作。

1.4.  Prometheus VS InfluxDB

InfluxDB是一個開源的時間序列資料庫,具有擴充和叢集的商業選項。InfluxDB項目是在Prometheus開發開始将近一年後釋出的,是以當時無法考慮将其作為替代方案。盡管如此,Prometheus和fluxdb之間仍然存在顯著的差異。二者有許多相似之處。兩者都有标簽(在InfluxDB中稱為tags)來有效地支援多元度度量。它們基本上使用相同的資料壓縮算法。兩者都具有廣泛的內建,包括彼此之間的內建。兩者都有挂鈎,允許進一步擴充它們,例如在統計工具中分析資料或執行自動化操作。

下列情況,用InfluxDB更好:

  • 如果你正在進行事件日志記錄
  • 商業選項為InfluxDB提供叢集,這對于長期資料存儲也更好
  • 最終實作副本之間資料的一緻性

下列情況,用Prometheus更好:

  • 如果你主要做的是度量
  • 如果你需要更強大的查詢語言、警報和通知功能
  • 更高的可用性和正常運作時間,用于繪圖和報警

InfluxDB由一家遵循開放核心模型的商業公司維護,提供進階特性,如閉源叢集、托管和支援。

Prometheus是一個完全開源和獨立的項目,由許多公司和個人維護,其中一些還提供商業服務和支援。

2.  基本概念

2.1.  資料模型

Prometheus基本上将所有資料存儲為時間序列:屬于同一名額和同一組标記次元的時間戳值流。除了存儲時間序列外,Prometheus還可以根據查詢結果生成臨時派生的時間序列。

(PS:這裡對時間序列的解釋是這樣的,

time series: streams of timestamped values belonging to the same metric and the same set of labeled dimensions

2.1.1.  Metric names and labels

Every time series is uniquely identified by its metric name and optional key-value pairs called labels.

(每個時間序列都由其名額名稱和稱為标簽的可選鍵值對唯一辨別)

名額名稱指定要度量的系統的一般特性(例如,http_requests_total表示接收的HTTP請求的總數)。它可能包含ASCII字母和數字,以及下劃線和冒号。它必須比對正規表達式[a-zA-Z_:][a-zA-Z0-9_:]*

标簽名稱可以包含ASCII字母、數字和下劃線。它們必須比對正規表達式[a-zA-Z_][a-zA-Z0-9_]*。以__開頭的标簽名稱保留内部使用。

标簽值可以包含任何Unicode字元。

2.1.2.  Sample(樣本)

樣本構成實際的時間序列資料。每個樣本包括:

  • a float64 value
  • a millisecond-precision timestamp

2.1.3.  notation(記法) 

給定一個度量名稱和一組标簽,時間序列通常使用以下符号辨別:

<metric name>{<label name>=<label value>,...}      

例如,有這樣一個時間序列,名額名稱是api_http_requests_total,有兩個标簽method="POST"和handler="/messages",那麼這個時間序列可以這樣寫:

api_http_requests_total{method="POST", handler="/messages"}      

2.2.  metric types(名額類型)

2.2.1.  Counter(計數器)

計數器是一個累積名額,它表示一個單調遞增的計數器,其值隻能在重新開機時遞增或重置為零。例如,可以使用計數器來表示已服務的請求數、已完成的任務數或錯誤數。不要使用計數器來反映一個可能會減小的值。例如,不要使用計數器表示目前正在運作的程序的數量,這種情況下,你應該用gauge。 

2.2.2.  Gauge(計量器)

計量器表示一個可以任意上下移動的數值。 

計量器通常用于測量溫度或目前記憶體使用量等,也用于“計數”,比如并發請求的數量。

2.2.3.  Histogram(直方圖、柱狀圖)

直方圖對觀察結果(通常是請求持續時間或響應大小之類的東西)進行采樣,并在可配置的桶中計數。它還提供了所有觀測值的和。

直方圖用一個基本的名額名<basename>暴露在一個抓取期間的多個時間序列:

  • 觀察桶的累積計數器,格式為<basename>_bucket{le="<upper inclusive bound>"}
  • 所有觀測值的總和,格式為<basename>_sum
  • 已觀察到的事件的計數,格式為<basename>_count

2.2.4.  Summary(摘要)

與柱狀圖類似,摘要樣例觀察結果(通常是請求持續時間和響應大小之類的内容)。雖然它還提供了觀測值的總數和所有觀測值的總和,但它計算了一個滑動時間視窗上的可配置分位數。

2.3.  Jobs AND Instances(作業與執行個體)

在Prometheus的術語中,可以抓取的端點稱為執行個體,通常對應于單個程序。具有相同目的的執行個體集合稱為作業。

例如,一個API Server job 有4個副本instances:

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

2.3.1.  自動生成标簽和時間序列

當Prometheus抓取目标時,它會自動在抓取的時間序列上附加一些标簽,用來識别被抓取的目标:

  • job:目标所屬的已配置作業名稱
  • instance:<host>:<port>是被抓取的目标URL的一部分

3.  快速開始

Prometheus是一個開源的系統監控和警報工具包,具有活躍的生态系統。

3.1.  下載下傳與安裝

Prometheus是一個監控平台,它通過抓取這些目标上的HTTP端點來收集被監控目标的名額。

需要下載下傳、安裝并運作Prometheus。還需要下載下傳并安裝一個exporter,它是将主機和服務上的時間序列資料導出的工具。

https://prometheus.io/download/

5分鐘了解Prometheus

在運作Prometheus之前,我們先配置一下

3.1.1.  配置Prometheus監視它自己

Prometheus通過抓取目标上的HTTP端點資料來從被監控的目标收集資料。由于Prometheus也以同樣的方式公開自己的資料,是以它還可以抓取和監測自己的健康狀況。

雖然Prometheus伺服器在實踐中隻收集關于自己的資料不是很有用,但是它是一個很好的開始示例。将以下基本的Prometheus配置儲存為一個名為Prometheus.yml的檔案:

1 global:
 2   scrape_interval:     15s # By default, scrape targets every 15 seconds.
 3 
 4   # Attach these labels to any time series or alerts when communicating with
 5   # external systems (federation, remote storage, Alertmanager).
 6   external_labels:
 7     monitor: 'codelab-monitor'
 8 
 9 # A scrape configuration containing exactly one endpoint to scrape:
10 # Here it's Prometheus itself.
11 scrape_configs:
12   # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.
13   - job_name: 'prometheus'
14 
15     # Override the global default and scrape targets from this job every 5 seconds.
16     scrape_interval: 5s
17 
18     static_configs:
19       - targets: ['localhost:9090']
      

3.1.2.  啟動Prometheus 

1 # Start Prometheus.
2 # By default, Prometheus stores its database in ./data (flag --storage.tsdb.path).
3 ./prometheus --config.file=prometheus.yml
      
5分鐘了解Prometheus
5分鐘了解Prometheus
5分鐘了解Prometheus

3.2.  配置

Prometheus可以通過指令行和配置檔案進行配置。配置檔案定義了與抓取作業及其執行個體相關的所有内容,以及要加載哪些規則檔案。

運作./prometheus -h可以檢視所有支援的指令

5分鐘了解Prometheus

為了指定要加載哪個配置檔案,請使用--config選項

配置檔案是YAML格式的

配置項太多,不一一列舉,自行檢視

https://prometheus.io/docs/prometheus/latest/configuration/configuration/

global:
   # How frequently to scrape targets by default.
   [ scrape_interval: <duration> | default = 1m ]
 
   # How long until a scrape request times out.
   [ scrape_timeout: <duration> | default = 10s ]
 
   # How frequently to evaluate rules.
   [ evaluation_interval: <duration> | default = 1m ]
 
   # The labels to add to any time series or alerts when communicating with
   # external systems (federation, remote storage, Alertmanager).
   external_labels:
     [ <labelname>: <labelvalue> ... ]
 
 # Rule files specifies a list of globs. Rules and alerts are read from
 # all matching files.
 rule_files:
   [ - <filepath_glob> ... ]
 
 # A list of scrape configurations.
 scrape_configs:
   [ - <scrape_config> ... ]
 
 # Alerting specifies settings related to the Alertmanager.
 alerting:
   alert_relabel_configs:
     [ - <relabel_config> ... ]
   alertmanagers:
     [ - <alertmanager_config> ... ]
 
 # Settings related to the remote write feature.
 remote_write:
   [ - <remote_write> ... ]
 
 # Settings related to the remote read feature.
 remote_read:
   [ - <remote_read> ... ]       

這裡有一個有效的示例配置檔案 

3.3.  查詢 

Prometheus提供了一種名為PromQL(Prometheus查詢語言)的函數式查詢語言,允許使用者實時選擇和聚合時間序列資料。表達式的結果既可以顯示為圖形,也可以在Prometheus的表達式浏覽器中作為表格資料檢視,或者通過HTTP API由外部系統使用。

3.3.1.  表達式資料類型

在Prometheus的表達式語言中,表達式或子表達式可以計算為以下四種類型之一:

  • Instant vector(瞬時向量):一組時間序列,每個時間序列包含一個樣本,所有樣本共享相同的時間戳
  • Range vector(範圍向量):一組時間序列,其中包含每個時間序列随時間變化的資料點範圍
  • Scalar(标量):一個簡單的數值浮點值
  • String(字元串):一個簡單的字元串值,目前未使用 

3.3.2.  字面值

字元串字面值

字元串可以指定為單引号、雙引号或反引号中的文字。例如:

1 "this is a string"
2 'these are unescaped: \n \\ \t'
3 `these are not unescaped: \n ' " \t`       

浮點數字面值

例如:-2.34

3.3.3.  時間序列選擇器

瞬時向量選擇器

瞬時向量選擇器允許在給定的時間戳(瞬時)上為每個時間序列選擇一組時間序列和一個樣本值:在最簡單的形式中,隻指定一個度量名稱。這樣一個向量就會包含這個度量名稱的所有時間序列元素。 

下面的例子,選擇名額名稱是http_requests_total的所有時間序列:

http_requests_total
      

通過在花括号({ })中添加一組比對的标簽,可以進一步過濾這些時間序列。 

下面的例子,選擇名額名稱是http_requests_total,并且有job标簽值是prometheus,并且group标簽值是canary的時間序列:

http_requests_total{job="prometheus",group="canary"}       

标簽比對操作符:

  • = : 選擇與提供的字元串完全相同的标簽(等于)
  • != :選擇不等于提供的字元串的标簽(不等于)
  • =~ :正則比對
  • !~ : 非正則比對 

下面的例子,選擇所有staging, testing, development環境,并且HTTP請求方式不是GET的http_requests_total時間序列 

http_requests_total{environment=~"staging|testing|development",method!="GET"}       

不要比對空标簽

{job=~".+"}              # Good!
 {job=~".*",method="get"} # Good!
      

3.3.4.  範圍向量選擇器

範圍向量字面量的工作原理與瞬時向量字面量類似,隻是它們從目前瞬時量中選擇一個樣本範圍。從文法上講,範圍持續時間被添加到向量選擇器末尾的方括号([ ])中,以指定應該為每個結果範圍向量元素擷取多少時間值。 

時間期限指定為一個數字,緊接其後的是下列機關之一:s(秒)、m(分鐘)、h(小時)、d(天) 、w(周)、y(年)

下面的例子,選擇名額名是http_requests_total,且job标簽值是prometheus的已經記錄的最近5分鐘内的時間序列:

http_requests_total{job="prometheus"}[5m]      

Offset修飾符

下面的表達式傳回http_requests_total在過去5分鐘相對于目前查詢計算時間的值:

http_requests_total offset 5m       

注意,offset總是緊跟在選擇器後面的

sum(http_requests_total{method="GET"} offset 5m)       

下面的例子,傳回一周前的最近5分鐘http_requests_total的時間序列

rate(http_requests_total[5m] offset 1w)
      

3.3.5.  子查詢

Syntax: <instant_query> '[' <range> ':' [<resolution>] ']' [ offset <duration> ]
      

3.3.5.  運算符 

Prometheus的查詢語言支援基本的邏輯運算符和算術運算符。

算術二進制運算符

+(加)、-(減)、*(乘)、/(除)、%(餘數)、^(指數)

二進制算術運算符定義在标量/标量、向量/标量和向量/向量值對之間

比較二進制運算符

== 、!= 、> 、< 、>= 、<=

邏輯運算符

and 、or 、unless

聚合運算符

sum(求和)、min(最小值)、max(最大值)、avg(求平均)、stddev(标準偏差)、stdvar(方差)、count(個數)、count_values(相同值的元素個數)、bottomk(樣本值的最小元素)、topk(樣本值的最大元素)、quantile(0 ≤ φ ≤ 1)

這些操作符既可以用于聚合所有标簽次元,也可以通過包含without子句或by子句來儲存不同的次元。

1 <aggr-op>([parameter,] <vector expression>) [without|by (<label list>)]
      

例如,假設http_requests_total有application 、 instance 、 group三個标簽,那麼下面兩個是等價的:

1 sum(http_requests_total) without (instance)
2 sum(http_requests_total) by (application, group)
      

3.3.6.  函數

https://prometheus.io/docs/prometheus/latest/querying/functions/

3.3.7.  示例

1 # 傳回http_requests_total的所有時間序列
 2 http_requests_total
 3 
 4 # 傳回http_requests_total的且限定了job和handler标簽的時間序列
 5 http_requests_total{job="apiserver", handler="/api/comments"}
 6 http_requests_total{job="apiserver", handler="/api/comments"}[5m]
 7 
 8 # 正規表達式
 9 http_requests_total{job=~".*server"}
10 http_requests_total{status!~"4.."}
11 
12 # 過去的5分鐘内每秒HTTP請求速率
13 rate(http_requests_total{job="api-server"}[5m])
14 # 過去的30分鐘内每5分鐘
15 rate(http_requests_total[5m])[30m:1m]
16 # 過去5分鐘的所有請求速率求和,保留job次元
17 sum(rate(http_requests_total[5m])) by (job)
18 # cpu使用率最高的前3個
19 topk(3, sum(rate(instance_cpu_time_ns[5m])) by (app, proc))
      

4.  Grafana支援 

Grafana支援查詢Prometheus

下面是Grafana dashboard查詢Prometheus資料的例子:

5分鐘了解Prometheus

使用 

預設情況下,Grafana監聽http://localhost:3000,預設用admin/admin登入

建立一個Prometheus資料源,接着建立面闆并定義查詢的名額

5分鐘了解Prometheus
5分鐘了解Prometheus
5分鐘了解Prometheus
5分鐘了解Prometheus
5分鐘了解Prometheus
5分鐘了解Prometheus

剛開始,如果不知道PromeQL怎麼寫,可以去Prometheus上去找  http://localhost:9090/graph

5分鐘了解Prometheus
5分鐘了解Prometheus
5分鐘了解Prometheus

https://prometheus.io/docs/introduction/overview/

https://prometheus.io/docs/alerting/overview/