Prometheus 的核心功能仰賴 YAML 設定檔驅動,其結構包含全域設定、警示設定、規則檔案和抓取組態等重要區塊。全域設定定義抓取間隔和規則評估間隔,警示設定則組態 Alertmanager 的連線資訊,規則檔案用於存放記錄和警示規則,而抓取組態則指定 Prometheus 抓取目標的資訊。理解這些設定對於有效監控至關重要。Prometheus 提供了內建的表示式瀏覽器和 PromQL 查詢語言,方便使用者查詢和分析指標資料。透過 sum()、rate() 等函式,可以對時間序列資料進行聚合和計算,例如計算每個任務的 HTTP 請求總數或速率。此外,容量規劃也是佈署 Prometheus 的關鍵環節,透過監控每秒新增的樣本數量和 Prometheus 行程的記憶體佔用,可以預估所需的記憶體資源並進行調整,確保監控系統穩定執行。
設定 Prometheus
現在我們已經安裝了 Prometheus,接下來看看它的設定。Prometheus 是透過 YAML 設定檔來組態的。當我們執行 prometheus 二進位制檔案(或在 Windows 上的 prometheus.exe 可執行檔)時,我們需要指定一個設定檔。Prometheus 預設附帶了一個設定檔:prometheus.yml。該檔案位於我們剛剛解壓縮的目錄中。讓我們來看看它。
YAML 設定注意事項
YAML 設定可能很繁瑣且容易出錯。您可以在 YAML Lint 網站上驗證 YAML,或使用命令列工具進行驗證。
預設的 Prometheus 設定檔
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
rule_files:
# - "first_rules.yml"
# - "second_rules.yml"
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
內容解密:
global區塊包含控制 Prometheus 伺服器行為的全域設定。scrape_interval指定了抓取任何應用程式或服務的時間間隔,在本例中為 15 秒。這將是您時間序列的解析度,即序列中每個資料點所涵蓋的時間段。evaluation_interval告訴 Prometheus 多久評估一次規則。規則有兩種主要型別:記錄規則和警示規則。
alerting區塊組態了 Prometheus 的警示功能。Alertmanager 是一個獨立的警示管理工具,可以進行叢集組態。rule_files區塊指定了包含記錄或警示規則的檔案列表。scrape_configs區塊指定了 Prometheus 將抓取的所有目標。
全域設定
第一個區塊 global,包含控制 Prometheus 伺服器行為的全域設定。
scrape_interval引數指定了抓取任何應用程式或服務的時間間隔,在本例中為 15 秒。evaluation_interval告訴 Prometheus 多久評估一次規則。
內容解密:
- 設定
scrape_interval時,應保持全域一致,以確保所有時間序列資料具有相同的解析度,並且可以一起合併和計算。 - 警告:只組態全域的抓取間隔,並保持解析度的一致性!
警示設定
第二個區塊 alerting,組態了 Prometheus 的警示功能。
alerting:
alertmanagers:
- static_configs:
- targets:
# - alertmanager:9093
內容解密:
alertmanagers區塊列出了此 Prometheus 伺服器使用的每個 Alertmanager。static_configs區塊表示我們將手動指定 Alertmanager,這些 Alertmanager 已在targets陣列中列出。- Prometheus 也支援 Alertmanager 的服務發現,例如,可以查詢外部來源(如 Consul 伺服器)以傳回可用的 Alertmanager 列表。
規則檔案
第三個區塊 rule_files,指定了包含記錄或警示規則的檔案列表。
抓取組態
最後一個區塊 scrape_configs,指定了 Prometheus 將抓取的所有目標。
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
內容解密:
- 在預設組態中,有一個名為
prometheus的作業被定義。在這個作業中,有一個static_config區塊,列出了該作業將抓取的目標。 static_config區塊表示我們將手動列出要抓取的目標,而不是使用任何自動化的服務發現方法。- Prometheus 假設指標將在路徑
/metrics上傳回,因此它將此路徑附加到目標並抓取地址http://localhost:9090/metrics。
Prometheus 組態結構
@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle
title Prometheus 設定檔詳解與監控實戰
package "資料庫架構" {
package "應用層" {
component [連線池] as pool
component [ORM 框架] as orm
}
package "資料庫引擎" {
component [查詢解析器] as parser
component [優化器] as optimizer
component [執行引擎] as executor
}
package "儲存層" {
database [主資料庫] as master
database [讀取副本] as replica
database [快取層] as cache
}
}
pool --> orm : 管理連線
orm --> parser : SQL 查詢
parser --> optimizer : 解析樹
optimizer --> executor : 執行計畫
executor --> master : 寫入操作
executor --> replica : 讀取操作
cache --> executor : 快取命中
master --> replica : 資料同步
note right of cache
Redis/Memcached
減少資料庫負載
end note
@enduml
此圖示展示了 Prometheus 組態檔的主要結構,包括全域設定、警示設定、規則檔案和抓取組態等關鍵元素。
圖表內容解密:
- 圖表展示了 Prometheus 組態檔的主要組成部分及其之間的關係。
- 每個區塊都有其特定的功能和組態選項,用於控制 Prometheus 的行為和功能。
總之,Prometheus 的設定檔是其運作的核心,透過 YAML 組態檔案,可以對其進行靈活且詳細的設定,以滿足不同的監控需求。
第3章:安裝與入門
啟動Prometheus伺服器
首先,讓我們啟動Prometheus伺服器,看看會發生什麼。在此之前,我們需要將設定檔移到更合適的位置。
將設定檔移到指定目錄
$ sudo mkdir -p /etc/prometheus
$ sudo cp prometheus.yml /etc/prometheus/
這裡我們建立了一個名為/etc/prometheus的目錄來存放設定檔,並將設定檔移動到該目錄下。
啟動Prometheus伺服器
$ prometheus --config.file "/etc/prometheus/prometheus.yml"
level=info ts=2017-10-23T14:03:02.274562Z caller=main.go:216 msg="Starting prometheus"...
我們執行Prometheus二進位檔案,並透過--config.file命令列引數指定設定檔。現在,Prometheus伺服器已經啟動並開始抓取prometheus任務的例項資料。
如果出現問題,可以使用promtool(Prometheus內建的組態檢查工具)來驗證設定檔。
$ promtool check config prometheus.yml
Checking prometheus.yml
SUCCESS: 0 rule files found
內容解密:
- 建立
/etc/prometheus目錄是為了存放Prometheus的設定檔,這是一種常見的Linux系統組態檔案的存放位置。 - 將
prometheus.yml複製到/etc/prometheus/目錄下是為了讓Prometheus伺服器能夠讀取到正確的設定檔。 - 使用
prometheus --config.file "/etc/prometheus/prometheus.yml"命令來啟動Prometheus伺服器,並指定設定檔的位置。 promtool check config prometheus.yml命令用於檢查設定檔是否有語法錯誤或其他問題。
使用Docker執行Prometheus
使用Docker執行Prometheus也很簡單。Prometheus團隊在Docker Hub上提供了官方的Docker映像。你可以使用docker命令來執行它。
$ docker run -p 9090:9090 prom/prometheus
這將在本機執行一個Prometheus伺服器,並將本機的9090埠對映到容器內的9090埠。你可以透過瀏覽器存取本機的9090埠來檢視Prometheus伺服器。伺服器使用預設組態啟動,你需要提供自定義組態和資料儲存。
將設定檔掛載到Docker容器中
$ docker run -p 9090:9090 -v /tmp/prometheus.yml:/etc/prometheus/prometheus.yml prom/prometheus
這將把本機的/tmp/prometheus.yml檔案掛載到容器內的/etc/prometheus/prometheus.yml位置,作為Prometheus伺服器的設定檔。
內容解密:
docker run -p 9090:9090 prom/prometheus命令啟動了一個Prometheus容器,並將容器的9090埠對映到主機的9090埠。- 使用
-v引數可以將主機上的檔案或目錄掛載到容器內,這裡我們將/tmp/prometheus.yml掛載為容器的設定檔。 - 這種方式使得我們可以在不修改容器內部檔案的情況下,自定義Prometheus的組態。
初識指標資料
現在Prometheus伺服器已經執行,讓我們看看被抓取的端點,觀察原始的Prometheus指標資料。瀏覽到http://localhost:9090/metrics,你會看到傳回的資料。
原始指標資料範例
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 1.6166e-05
go_gc_duration_seconds{quantile="0.25"} 3.8655e-05
go_gc_duration_seconds{quantile="0.5"} 5.3416e-05
...
這裡展示了我們的第一個Prometheus指標。這些資料看起來和我們之前討論的資料模型相似。
單一指標資料範例
go_gc_duration_seconds{quantile="0.5"} 1.6166e-05
指標名稱是go_gc_duration_seconds,帶有一個標籤quantile="0.5",表示這是測量第50百分位的資料,以及指標的值。
內容解密:
go_gc_duration_seconds是一個指標名稱,表示Go語言垃圾回收(GC)持續時間的秒數。{quantile="0.5"}是一個標籤,表示這是第50百分位的資料,即中位數。- 指標的值表示垃圾回收持續的時間,以秒為單位。
使用Prometheus表示式瀏覽器
直接檢視指標資料並不友好,因此我們使用Prometheus內建的表示式瀏覽器。存取http://localhost:9090/graph即可使用。
使用表示式瀏覽器查詢指標
在查詢框中輸入go_gc_duration_seconds,然後點選“Execute”按鈕,即可查詢到相關指標。
查詢結果會顯示多個帶有不同標籤的指標,例如:
go_gc_duration_seconds{instance="localhost:9090",job="prometheus",quantile="0.5"}
這裡,我們可以看到兩個額外的標籤:instance和job,它們是由Prometheus在抓取過程中自動新增的。這些標籤為我們的指標提供了維度,使得我們可以查詢或處理多個或特定的指標。
內容解密:
instance標籤表示抓取指標的目標例項。job標籤表示執行抓取任務的名稱。- 這些額外的標籤使得指標具有了多維度,可以進行更靈活的查詢和分析。
使用PromQL查詢語言
Prometheus具有一個高度靈活的表示式語言,稱為PromQL,可以用來查詢和聚合指標。在查詢輸入框中,可以使用PromQL進行各種查詢操作。
例如,查詢所有帶有quantile="0.5"標籤的指標:
go_gc_duration_seconds{quantile="0.5"}
這將傳回一個即時向量(instant vector),包含多個時間序列,每個序列都有一個樣本值,並且分享相同的時間戳。
內容解密:
- PromQL允許使用者以靈活的方式查詢和處理指標資料。
- 即時向量是一種特殊的資料型別,表示在同一時間戳上的多個時間序列樣本。
- 可以使用各種運算元和函式對指標進行聚合、過濾等操作。
第3章:安裝與入門
使用 Prometheus 的查詢語言:PromQL
在 Prometheus 中,查詢標籤(labels)類別似於解析帶有點分隔字串的指標名稱。對於熟悉 Graphite 等工具的使用者來說,這種查詢方式並不陌生。有篇部落格文章提供了 Graphite、InfluxDB 和 Prometheus 在處理各種查詢時的比較。
接下來,讓我們看看另一個名為 prometheus_build_info 的指標,該指標包含了有關 Prometheus 伺服器構建的資訊。將 prometheus_build_info 輸入到運算式瀏覽器的查詢框中,然後點選「執行」以傳回該指標。你將看到類別似以下的條目:
清單 3.22:prometheus_build_info 指標
prometheus_build_info{branch="HEAD",goversion="go1.9.1",instance="localhost:9090",job="prometheus",revision="5ab8834befbd92241a88976c790ace7543edcd59",version="2.3.0"}
可以看出,該指標被大量裝飾了標籤,並且其值為 1。這是使用指標向 Prometheus 伺服器傳遞資訊的常見模式。它使用一個值始終為 1 的指標,並透過標籤附加相關資訊。我們將在後面的章節中看到更多這型別的資訊指標。
時間序列聚合
Prometheus 的介面也支援對指標進行複雜的聚合運算。讓我們選擇另一個名為 http_requests_total 的指標,該指標代表了 Prometheus 伺服器中各個處理器所處理的 HTTP 請求總數。現在透過指定其名稱並點選「執行」來查詢它。
圖 3.4:查詢總 HTTP 請求
我們得到了一份 HTTP 請求指標的清單。但我們真正想要的是每個任務(job)的 HTTP 請求總數。為了實作這一點,我們需要透過查詢建立一個新的指標。Prometheus 的查詢語言 PromQL 具有大量的運算式和函式,可以幫助我們完成這項任務。
首先,讓我們嘗試透過任務來匯總 HTTP 請求。在查詢框中輸入以下內容並點選「執行」:
sum(http_requests_total)
這個新的查詢使用了 sum() 運算元對 http_requests_total 指標進行了匯總。它把所有的請求加了起來,但沒有按照任務進行區分。要實作這一點,我們需要按照特定的標籤維度進行聚合。PromQL 有一個名為 by 的子句,可以讓我們按照特定的維度進行聚合。在查詢框中輸入以下內容並點選「執行」:
sum(http_requests_total) by (job)
圖 3.5:按任務計算總 HTTP 請求
你應該會看到類別似以下的輸出結果。現在點選「圖表」標籤,可以看到這個指標以繪圖的形式呈現。
sum(rate(http_requests_total[5m])) by (job)
在這裡,我們新增了一個名為 rate() 的函式,並將其巢狀在 sum() 函式內部。
rate(http_requests_total[5m])
rate() 函式計算了一個範圍內時間序列的每秒平均增長率。該函式只適用於計數器(counters)。它非常聰明,可以自動調整斷點(如資源重啟時計數器被重置),並推斷出時間序列中的間隙(如錯過的抓取)。rate() 函式最適合用於較慢變化的計數器或警示目的。
內容解密:
sum(http_requests_total) by (job):此查詢先對所有http_requests_total指標的值進行求和,然後按照job標籤進行分組。這樣,我們可以得到每個任務的 HTTP 請求總數。rate(http_requests_total[5m]):此函式計算過去 5 分鐘內http_requests_total的每秒平均增長率。它考慮了時間序列中的斷點和間隙,確保計算結果的準確性。sum(rate(http_requests_total[5m])) by (job):此查詢結合了上述兩個操作,先計算每個時間序列的速率,然後按job標籤進行匯總。這樣,我們可以得到每個任務在過去 5 分鐘內的平均每秒 HTTP 請求數。
容量規劃
Prometheus 的效能很難估計,因為它取決於你的組態、收集的時間序列數量以及伺服器上規則的複雜度。有兩個主要的容量問題:記憶體和磁碟。
記憶體
Prometheus 在記憶體中做了很多工作。它為每個收集的時間序列以及查詢、記錄規則等消耗程式記憶體。對於 Prometheus 的容量規劃,特別是自 2.0 版本發布以來,相關的資料並不多,但一個粗略的經驗法則是將每秒收集的樣本數量乘以樣本的大小。我們可以使用以下查詢來檢視樣本收集的速率:
rate(prometheus_tsdb_head_samples_appended_total[1m])
這個查詢顯示了過去一分鐘內每秒新增到資料函式庫中的樣本數量。
圖 3.6:我們的速率查詢結果
假設我們每秒收集 100,000 個樣本,持續 12 小時,我們可以按以下方式計算記憶體使用量:
100,000 * 2 位元組 * 43200 秒
大約需要 8.64 GB 的 RAM。
你還需要考慮查詢和記錄規則的記憶體使用量。這是一個非常粗略的估計,取決於許多其他變數。建議根據實際情況調整記憶體使用量。你可以透過檢查 process_resident_memory_bytes 指標來檢視 Prometheus 行程的記憶體使用量。
內容解密:
rate(prometheus_tsdb_head_samples_appended_total[1m]):此查詢用於監控 Prometheus 每秒追加到資料函式庫中的樣本數量,用於評估記憶體需求。- 記憶體使用量估算:根據每秒樣本數量和樣本大小,可以粗略估算所需的記憶體容量。例如,每秒 100,000 個樣本,持續 12 小時,大約需要 8.64 GB RAM。
process_resident_memory_bytes:此指標用於監控 Prometheus 行程實際佔用的記憶體大小,有助於動態調整資源分配。