時序性數據庫Prometheus

時序性數據庫Prometheus

Author: Lijbnode

Emali: lijb1121@163.comlinux

Prometheus 簡介

Prometheus 是一套開源的系統監控報警框架。它啓發於 Google 的 borgmon 監控系統,由工做在 SoundCloud 的 google 前員工在 2012 年建立,做爲社區開源項目進行開發,並於 2015 年正式發佈。2016 年,Prometheus 正式加入 Cloud Native Computing Foundation,成爲受歡迎度僅次於 Kubernetes 的項目。git

做爲新一代的監控框架,Prometheus 具備如下特色:github

  • 強大的多維度數據模型:
    1. 時間序列數據經過 metric 名和鍵值對來區分。
    2. 全部的 metrics 均可以設置任意的多維標籤。
    3. 數據模型更隨意,不須要刻意設置爲以點分隔的字符串。
    4. 能夠對數據模型進行聚合,切割和切片操做。
    5. 支持雙精度浮點類型,標籤能夠設爲全 unicode。
  • 靈活而強大的查詢語句(PromQL):在同一個查詢語句,能夠對多個 metrics 進行乘法、加法、鏈接、取分數位等操做。
  • 易於管理: Prometheus server 是一個單獨的二進制文件,可直接在本地工做,不依賴於分佈式存儲。
  • 高效:平均每一個採樣點僅佔 3.5 bytes,且一個 Prometheus server 能夠處理數百萬的 metrics。
  • 使用 pull 模式採集時間序列數據,這樣不只有利於本機測試並且能夠避免有問題的服務器推送壞的 metrics。
  • 能夠採用 push gateway 的方式把時間序列數據推送至 Prometheus server 端。
  • 能夠經過服務發現或者靜態配置去獲取監控的 targets。
  • 有多種可視化圖形界面。
  • 易於伸縮。

須要指出的是,因爲數據採集可能會有丟失,因此 Prometheus 不適用對採集數據要 100% 準確的情形。但若是用於記錄時間序列數據,Prometheus 具備很大的查詢優點,此外,Prometheus 適用於微服務的體系架構。web

Prometheus 組成及架構

Prometheus 生態圈中包含了多個組件,其中許多組件是可選的:正則表達式

  • Prometheus Server: 用於收集和存儲時間序列數據。
  • Client Library: 客戶端庫,爲須要監控的服務生成相應的 metrics 並暴露給 Prometheus server。當 Prometheus server 來 pull 時,直接返回實時狀態的 metrics。
  • Push Gateway: 主要用於短時間的 jobs。因爲這類 jobs 存在時間較短,可能在 Prometheus 來 pull 以前就消失了。爲此,此次 jobs 能夠直接向 Prometheus server 端推送它們的 metrics。這種方式主要用於服務層面的 metrics,對於機器層面的 metrices,須要使用 node exporter。
  • Exporters: 用於暴露已有的第三方服務的 metrics 給 Prometheus。
  • Alertmanager: 從 Prometheus server 端接收到 alerts 後,會進行去除重複數據,分組,並路由到對收的接受方式,發出報警。常見的接收方式有:電子郵件,pagerduty,OpsGenie, webhook 等。
  • 一些其餘的工具。

圖 1 爲 Prometheus 官方文檔中的架構圖:docker

圖 1. Prometheus 架構圖數據庫

img

從上圖能夠看出,Prometheus 的主要模塊包括:Prometheus server, exporters, Pushgateway, PromQL, Alertmanager 以及圖形界面。ubuntu

其大概的工做流程是:vim

  1. Prometheus server 按期從配置好的 jobs 或者 exporters 中拉 metrics,或者接收來自 Pushgateway 發過來的 metrics,或者從其餘的 Prometheus server 中拉 metrics。
  2. Prometheus server 在本地存儲收集到的 metrics,並運行已定義好的 alert.rules,記錄新的時間序列或者向 Alertmanager 推送警報。
  3. Alertmanager 根據配置文件,對接收到的警報進行處理,發出告警。
  4. 在圖形界面中,可視化採集數據。

Prometheus 相關概念

下面將對 Prometheus 中的數據模型,metric 類型以及 instance 和 job 等概念進行介紹,以便讀者在 Prometheus 的配置和使用中能夠有一個更好的理解。

數據模型

Prometheus 中存儲的數據爲時間序列,是由 metric 的名字和一系列的標籤(鍵值對)惟一標識的,不一樣的標籤則表明不一樣的時間序列。

  • metric 名字:該名字應該具備語義,通常用於表示 metric 的功能,例如:http_requests_total, 表示 http 請求的總數。其中,metric 名字由 ASCII 字符,數字,下劃線,以及冒號組成,且必須知足正則表達式 [a-zA-Z_:][a-zA-Z0-9_:]*。
  • 標籤:使同一個時間序列有了不一樣維度的識別。例如 http_requests_total{method="Get"} 表示全部 http 請求中的 Get 請求。當 method="post" 時,則爲新的一個 metric。標籤中的鍵由 ASCII 字符,數字,以及下劃線組成,且必須知足正則表達式 [a-zA-Z_:][a-zA-Z0-9_:]*。
  • 樣本:實際的時間序列,每一個序列包括一個 float64 的值和一個毫秒級的時間戳。
  • 格式:<metric name>{<label name>=<label value>, …},例如:http_requests_total{method="POST",endpoint="/api/tracks"}。

四種 Metric 類型

Prometheus 客戶端庫主要提供四種主要的 metric 類型:

Counter

  • 一種累加的 metric,典型的應用如:請求的個數,結束的任務數, 出現的錯誤數等等。

例如,查詢 http_requests_total{method="get", job="Prometheus", handler="query"} 返回 8,10 秒後,再次查詢,則返回 14。

Gauge

  • 一種常規的 metric,典型的應用如:溫度,運行的 goroutines 的個數。
  • 能夠任意加減。

例如:go_goroutines{instance="172.17.0.2", job="Prometheus"} 返回值 147,10 秒後返回 124。

Histogram

  • 能夠理解爲柱狀圖,典型的應用如:請求持續時間,響應大小。
  • 能夠對觀察結果採樣,分組及統計。

例如,查詢 http_request_duration_microseconds_sum{job="Prometheus", handler="query"} 時,返回結果以下:

圖 2. Histogram metric 返回結果圖

img

Summary

  • 相似於 Histogram, 典型的應用如:請求持續時間,響應大小。
  • 提供觀測值的 count 和 sum 功能。
  • 提供百分位的功能,便可以按百分比劃分跟蹤結果。

instance 和 jobs

instance: 一個單獨 scrape 的目標, 通常對應於一個進程。

jobs: 一組同種類型的 instances(主要用於保證可擴展性和可靠性),例如:

1. job 和 instance 的關係
`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`

當 scrape 目標時,Prometheus 會自動給這個 scrape 的時間序列附加一些標籤以便更好的分別,例如: instance,job。

下面以實際的 metric 爲例,對上述概念進行說明。

圖 3. Metrics 示例

img

如上圖所示,這三個 metric 的名字都同樣,他們僅憑 handler 不一樣而被標識爲不一樣的 metrics。這類 metrics 只會向上累加,是屬於 Counter 類型的 metric,且 metrics 中都含有 instance 和 job 這兩個標籤。

Node exporter 安裝

爲了更好的演示 Prometheus 從配置,到監控,到報警的功能,本實例將引入本機 ubuntu server 的監控。因爲 Prometheus 主要用於監控 web 服務,若是須要監控 ubuntu server,則須要在本機上安裝 node exporter。 Node exporter 主要用於暴露 metrics 給 Prometheus,其中 metrics 包括:cpu 的負載,內存的使用狀況,網絡等。

安裝 node export 首先須要從 github 中下載最新的 node exporter 包,放在指定的目錄並解壓安裝包,在本實例中,放在 /home/lilly/prom/exporters/ 中。

2. 安裝 Node exporter
`cd /home/lilly/prom/exporters/``wget https://github.com/prometheus/node_exporter/releases/download/v0.14.0/node_exporter-0.14.0.linux-amd64.tar.gz``tar -xvzf node_exporter-0.14.0.linux-amd64.tar.gz`

爲了更好的啓動和中止 node exporter,能夠把 node exporter 轉換爲一個服務。

3. 配置 node exporter 爲服務
`vim /etc/init/node_exporter.conf``#Prometheus Node Exporter Upstart script`` ``start on startup`` ``script`` ``/home/lilly/prom/exporters/node_exporter/node_exporter`` ``end script`

此時,node exporter 已是一個服務,能夠直接用 service 命令進行啓停和查看。

4. 查看 node exporter 狀態
`root@ubuntu1404-dev:~/alertmanager# service node_exporter start``node_exporter start/running, process 11017``root@ubuntu1404-dev:~/alertmanager# service node_exporter status``node_exporter start/running, process 11017``此時,node exporter 已經監聽在 9100 端口。``root@ubuntu1404-dev:~/prom# netstat -anp | grep 9100``tcp6       0      0 :::9100                 :::*                    LISTEN      155/node_exporter`

當 node exporter 啓動時,能夠經過 curl http://localhost:9100/metrics 或者在瀏覽器中查看 ubuntu server 裏面的 metrics,部分 metrics 信息以下:

5. 驗證 node exporter
`root@ubuntu1404-dev:~/prom# curl http://localhost:9100/metrics``……``# HELP node_cpu Seconds the cpus spent in each mode.``# TYPE node_cpu counter``node_cpu{cpu="cpu0",mode="guest"} 0``node_cpu{cpu="cpu0",mode="idle"} 30.02``node_cpu{cpu="cpu0",mode="iowait"} 0.5``node_cpu{cpu="cpu0",mode="irq"} 0``node_cpu{cpu="cpu0",mode="nice"} 0``node_cpu{cpu="cpu0",mode="softirq"} 0.34``node_cpu{cpu="cpu0",mode="steal"} 0``node_cpu{cpu="cpu0",mode="system"} 5.38``node_cpu{cpu="cpu0",mode="user"} 11.34``# HELP node_disk_bytes_read The total number of bytes read successfully.``# TYPE node_disk_bytes_read counter``node_disk_bytes_read{device="sda"} 5.50009856e+08``node_disk_bytes_read{device="sr0"} 67584``# HELP node_disk_bytes_written The total number of bytes written successfully.``# TYPE node_disk_bytes_written counter``node_disk_bytes_written{device="sda"} 2.0160512e+07``node_disk_bytes_written{device="sr0"} 0``# HELP node_disk_io_now The number of I/Os currently in progress.``# TYPE node_disk_io_now gauge``node_disk_io_now{device="sda"} 0``node_disk_io_now{device="sr0"} 0``# HELP node_disk_io_time_ms Total Milliseconds spent doing I/Os.``# TYPE node_disk_io_time_ms counter``node_disk_io_time_ms{device="sda"} 3484``node_disk_io_time_ms{device="sr0"} 12``……``# HELP node_memory_MemAvailable Memory information field MemAvailable.``# TYPE node_memory_MemAvailable gauge``node_memory_MemAvailable 1.373270016e+09``# HELP node_memory_MemFree Memory information field MemFree.``# TYPE node_memory_MemFree gauge``node_memory_MemFree 9.2403712e+08``# HELP node_memory_MemTotal Memory information field MemTotal.``# TYPE node_memory_MemTotal gauge``node_memory_MemTotal 2.098388992e+09``……``# HELP node_network_receive_drop Network device statistic receive_drop.``# TYPE node_network_receive_drop gauge``node_network_receive_drop{device="docker0"} 0``node_network_receive_drop{device="eth0"} 0``node_network_receive_drop{device="eth1"} 0``node_network_receive_drop{device="lo"} 0`

Prometheus 安裝和配置

Prometheus 能夠採用多種方式安裝,本文直接用官網的 docker image(prom/prometheus)啓動一個 Prometheus server, 並配置相應的靜態監控 targets,jobs 和 alert.rules 文件。

啓動 Prometheus 容器,並把服務綁定在本機的 9090 端口。命令以下:

6. 安裝 Prometheus
`docker run -d -p 9090:9090 \``            ``-v $PWD/prometheus.yml:/etc/prometheus/prometheus.yml \``            ``-v $PWD/alert.rules:/etc/prometheus/alert.rules \``            ``--name prometheus \``            ``prom/prometheus \``            ``-config.file=/etc/prometheus/prometheus.yml \``            ``-alertmanager.url=http://10.0.2.15:9093`

其中 Prometheus 的配置文件 prometheus.yml 內容爲:

7. Prometheus.yml 配置文件
global:                  # 全局設置,能夠被覆蓋  scrape_interval:     15s # 默認值爲 15s,用於設置每次數據收集的間隔
 
  external_labels:   # 全部時間序列和警告與外部通訊時用的外部標籤    monitor: 'codelab-monitor'
 
rule_files: # 警告規則設置文件  - '/etc/prometheus/alert.rules'
 
# 用於配置 scrape 的 endpoint  配置須要 scrape 的 targets 以及相應的參數 scrape_configs:   # The job name is added as a label `job=<job_name>` to any timeseries scraped from this config.  - job_name: 'prometheus'  # 必定要全局惟一, 採集 Prometheus 自身的 metrics
 
    # 覆蓋全局的 scrape_interval    scrape_interval: 5s
 
    static_configs:  # 靜態目標的配置      - targets: ['172.17.0.2:9090']
 
  - job_name: 'node'  # 必定要全局惟一, 採集本機的 metrics,須要在本機安裝 node_exporter
 
    scrape_interval: 10s
 
    static_configs:      - targets: ['10.0.2.15:9100']  # 本機 node_exporter 的 endpoint

alert 規則文件的內容以下:

8. alert.rules 配置文件
# Alert for any instance that is unreachable for >5 minutes. 
ALERT InstanceDown   # alert 名字  
	IF up == 0           # 判斷條件  
	FOR 5m             # 條件保持 5m 纔會發出 alert  
	LABELS { severity = "critical" }  # 設置 alert 的標籤  
	ANNOTATIONS {             # alert 的其餘標籤,但不用於標識 alert    
		summary = "Instance {{ $labels.instance }} down",    
		description = "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes.",  }

當 Prometheus server 起來時,能夠在 Prometheus 容器的日誌中看到:

9. Prometheus 日誌
time="2017-09-05T08:18:02Z" level=info msg="Starting prometheus (version=1.7.1, branch=master, 
revision=3afb3fffa3a29c3de865e1172fb740442e9d0133)" source="main.go:88" 
time="2017-09-05T08:18:02Z" level=info msg="Build context (go=go1.8.3, user=root@0aa1b7fc430d, date=20170612-
11:44:05)" source="main.go:89" 
time="2017-09-05T08:18:02Z" level=info msg="Host details (Linux 3.19.0-75-generic #83~14.04.1-Ubuntu SMP Thu Nov 
10 10:51:40 UTC 2016 x86_64 71984d75e6a1 (none))" source="main.go:90" 
time="2017-09-05T08:18:02Z" level=info msg="Loading configuration file /etc/prometheus/prometheus.yml" 
source="main.go:252" 
time="2017-09-05T08:18:03Z" level=info msg="Loading series map and head chunks..." source="storage.go:428" 
time="2017-09-05T08:18:03Z" level=info msg="0 series loaded." source="storage.go:439" 
time="2017-09-05T08:18:03Z" level=info msg="Starting target manager..." source="targetmanager.go:63" 
time="2017-09-05T08:18:03Z" level=info msg="Listening on :9090" source="web.go:259"

在瀏覽器中訪問 Prometheus 的主頁 http://localhost:9091, 能夠看到 Prometheus 的信息以下:

圖 4. Prometheus 狀態信息

img

爲了保證 Prometheus 確實從 node exporter 中收集數據,能夠在 Graph 頁面中搜索 metric 名字,如 node_cpu 並點擊 Execute,能夠在 console 中看到 metric 以下。

圖 5. Prometheus 中 metric 查詢結果 console 輸出示例

img

其中第一條爲來自 node exporter 的 metric,此時 ubuntu server 上 goroutines 的個數爲 13。點擊 Graph 能夠觀察 metrics 的歷史數據。以下圖所示:

圖 6. Prometheus 中 metric 查詢結果 Graph 輸出示例

img

Alertmanager 安裝和配置

當接收到 Prometheus 端發送過來的 alerts 時,Alertmanager 會對 alerts 進行去重複,分組,路由到對應集成的接受端,包括:slack,電子郵件,pagerduty,hitchat,webhook。

在 Alertmanager 的配置文件中,須要進行以下配置:

10. Alermanager 中 config.yml 文件
root@ubuntu1404-dev:~/alertmanager# cat config.yml
global:
    resolve_timeout: 5m
route:
    receiver: 'default-receiver'
    group_wait: 30s
    group_interval: 1m
    repeat_interval: 1m
    group_by: ['alertname']
 
    routes:
    - match:
        severity: critical
      receiver: my-slack
 
receivers:
- name: 'my-slack'
  slack_configs:
  - send_resolved: true
    api_url: https://hooks.slack.com/services/***
    channel: '#alertmanager-critical'
    text: "{{ .CommonAnnotations.description }}"
 
 
- name: 'default-receiver'
  slack_configs:
  - send_resolved: true
    api_url: https://hooks.slack.com/services/***
    channel: '#alertmanager-default'
    text: "{{ .CommonAnnotations.description }}"

建立好 config.yml 文件後,能夠直接用 docker 啓動一個 Alertmanager 的容器,以下:

11. 安裝 Alertmanager

當 Alertmanager 服務起來時,能夠經過瀏覽器訪 Alertmanager 的主頁 http://localhost:9093,其狀態信息以下:

圖 7. Alertmanager 狀態信息

img

在 alerts 的頁面中,咱們能夠看到從 Prometheus sever 端發過來的 alerts,此外,還能夠作 alerts 搜索,分組,靜音等操做。

圖 8. Alertmanager 報警頁面

img

Prometheus 實例演示

下面將經過一個具體的實例來演示 Prometheus 的使用。在 alert.ruels 中定義了 alert 觸發的條件是 up 爲 0。下面,手動中止 node exporter 服務。

清單 12. 中止 node exporter 服務
`root@ubuntu1404-dev:~/prom# service node_exporter stop``node_exporter stop/waiting``root@ubuntu1404-dev:~/prom# service node_exporter status``node_exporter stop/waiting`

此時,Prometheus 中查詢 metric up,能夠看到此時 up{instance="10.0.2.15",job="node"} 的值爲 0,以下所示:

圖 9. Metric up 的返回值(停)

img

此時,Alerts 頁面中顯示 InstanceDown,狀態爲 PENDING。由於 alert 規則中定義須要保持 5 分鐘,因此在這以前,alerts 尚未發送至 Alertmanager。

圖 10. Alert Pending 界面

img

5 分鐘後,狀態由 PENDING 變爲 FIRING,於此同時,在 Alertmanager 中能夠看到有一個 alert。

圖 11. Alert Firing 界面

img

圖 12. Alertmanager 警報界面

img

在 Alertmanager 的配置文件中定義,黨 severity 爲 critical 的時候,往 Alertmanager-critical channel 中發送警告,且每隔兩分鐘重複發送。以下圖所示。

圖 13. Slack 告警界面

img

由上可知,當目標失敗時,不只能夠在 Prometheus 的主頁上實時的查看目標和 alerts 的狀態,還可使用 Alertmanager 發送警告,以便運維人員儘快解決問題。

當問題解決後,Prometheus 不只會實時更新 metrics 的狀態,Alertmanager 也會在 slack 通知 resolved 的消息。如下演示問題解決後的,Prometheus 的操做。

手動啓動 node exporter。首先 metric 在 Graph 中恢復至正常值 1。

圖 14. Metric up 的返回值(啓)

img

targets 中現實 node 這個 job 是 up 的狀態。

圖 15. Targets 界面

img

Alerts 爲綠色,顯示有 0 個激活態的警告。

圖 16. Alers resolved 界面

img

而在 Alertmanager 剛剛的 alert 也被清空,顯示 No alerts found。

圖 17. Alertmanager resolved 界面

img

在 slack 端,在屢次紅色 FRING 報警後,也收到了綠色了 RESOLVED 消息。

圖 18. Slack resolved 界面

img

總結

本文對 Prometheus 的組成,架構和基本概念進行了介紹,並實例演示了 node exporter, Prometheus 和 Alermanager 的配置和運行。最後,以一個監控的 target 的啓停爲例,演示 Prometheus 的一系列響應以及如何在 Prometheus 和 Alertmanager 中查看服務,警報和告警的狀態。對於 Prometheus 中更高級的使用,如查詢函數的使用,更多圖形界面的集成,請參考官方文檔。

參考資源

相關文章
相關標籤/搜索