Prometheus 技術解析

 
在政大修分散式系統的期中技術報告,感謝同組組員們一同完成
 
 

1. Introduction

1.1 主要功能

Prometheus是一套用於監控與警報的開源軟體,主要目的是為了更方便地監控高度動態的容器環境。 Prometheus 透過持續收集和統計監控樣本的 metrics 資料,對監控指標進行趨勢分析,同時提供資料搜尋的 API ,並結合示警功能及視覺化工具,幫助使用者實時監控系統運行的狀態,快速定位問題和排除故障,提高系統的穩定性和可靠性。
Prometheus可以大致分為以下五個功能:
  1. 趨勢分析:透過持續收集和統計監控數據,可以對監控指標進行趨勢分析,以便提前預測未來可能出現的問題。
  1. 對照分析:透過監控數據對於系統進行跟蹤和比較。例如比較兩個版本的系統在運行中的資源使用情況差異,或是在不同容量情況下系統的負載變化。
  1. 示警功能:在系統出現或即將出現故障時通知管理員,以便對問題進行快速處理或提前預防問題的發生。
  1. 故障分析和定位:通過對監控數據和歷史數據的分析,找到並解決系統問題的根源,以便對問題進行調查和處理。
  1. 數據可視化:透過 Prometheus的儀錶盤功能,能夠直觀地獲取系統的運行狀態、資源使用情況和服務運行狀態等訊息。

1.2 The Overall Approach (Core Idea)

Prometheus的核心理念是透過pull-based架構進行指標數據的收集。在pull-based架構中,Prometheus會定期向目標系統發出請求(pull request),從而獲取目標系統的數據。透過此做法可以有效地控制數據的流量和頻率,避免不必要的數據傳輸和資源浪費。同時,透過pull監控目標存活性相較push較為簡單,直接在pull的中心端就能知道是否請求到目標端的指標,如果失敗也能知道一些簡單的錯誤,比如網絡超時、對方拒絕連接等。
此外,對於短時間執行的腳本任務或不好直接 pull 指標的服務,Prometheus也提供了 Pushgateway 讓任務主動推送指標推到網關,再由 Prometheus從Pushgateway中 pull 指標。

2. 架構解析

2.1 系統架構圖


notion image

2.2 Retrieval

在Prometheus當中,由retrieval負責蒐集或是拉取 (pull) metrics資料,並將資料儲存於時間序列資料庫 (Time Series Database) 中,以供PromQL queries取出資料,並放到瀏覽器上產生資料視覺化結果。

2.2.1 Prometheus監控的對象

監控的對象分為許多種,有可能是一個Linux server、一個應用程式,也可能是一個資料庫服務。

2.2.2 Prometheus監控對象的什麼

Prometheus監控對象可以分為許多種,可能是CPU狀態、request要求次數、記憶體空間使用量等等,這些監控對象當中欲監控的數值,我們稱之為metrics。

2.2.3 Metrics

Metric是一種描述系統狀態的量度,通常會用文字格式來表達,裡面包含Name, Label和Value,Name記錄了metric的名稱,Label記錄了metric的特性,Value則記錄了該metric的值。
每個metrics都有HELP / TYPE兩種attribute,用來增加可讀性:
  • HELP:有關metrics的簡短敘述。
  • TYPE:會是以下三種型態的其中一種:
    • Counter:「發生了多少次」
    • Gauge:「現在的值是多少」
    • Histogram:「多久 / 多大」
      • 在有些時候,也存在Summary這個第四種選項。

2.2.4 Collect Metrics from Target

Prometheus可能會從一個Server / Application或Service當中取得metrics,而取得metrics的必要條件是要由target方對外提供endpoint。Endpoint是一個對外的接口,prometheus主要透過該接口來跟target取得metrics。

2.2.5 Pushgateway

Client可以將metrics推進Pushgateway 中,再由Prometheus定期從Pushgateway收集數據,這樣便不用透過endpoint取得資料。
這種方式適用於無法提供 endpoint的目標,像是執行時間很短的資料。

2.2.6 Exporter Endpoint

Exporter是一種script/service,會從目標當中取得metrics,並將其轉換為Prometheus可讀懂的格式,再將metrics對外公開於endpoint,讓Prometheus能夠取得該資料。

2.3 Storage

在Prometheus當中,storage負責儲存從監控對象取得的metrics資料。Storage是一個時間序列資料庫 (time series database),資料在經過壓縮成特定格式後才會儲存進資料庫,用以增進效能並節省空間。

2.3.1 Time Series Database

時間序列資料 (Time series data) 是會隨著時間持續產生變動的資料,由於Prometheus取得的資料多為時間序列資料,因此Prometheus Server也採用時間序列資料庫來蒐集資料。
時間序列資料庫能夠相較於一般的資料庫更善於處理時間序列資料,其提供了有效率的儲存技術、快速的查詢方式和足夠的擴展性,使得資料能夠被妥善處理和運用。
由於Prometheus當中的資料會轉成符合時間序列資料庫的格式,因此資料不能直接地放進其他類型的資料庫當中。

2.3.2 Data Compression

Prometheus Server使用一個稱作block compression的技術來壓縮取得的資料。
這種技術將資料拆分為多個區塊 (block) ,每個區塊都會分別進行壓縮,這麼做使得壓縮時可根據個別區塊中資料的特性來做更有效率的處理。
Prometheus使用Snappy壓縮函式庫來協助進行壓縮,其為Google旗下的一款產品。

2.4 PromQL

Prometheus的網頁UI可以透過PromQL跟Prometheus Server取得資料,並將可視化結果呈現在網頁上。
除了網頁UI,其他的資料可視化工具  (Ex: Grafana) 也可以使用PromQL來向 Server取得資料。

2.4.1 Use Case of PromQL

Prometheus Query Language (PromQL) 是用於查詢Prometheus Server當中儲存的metrics資料的語言,支援許多不同的功能。主要如下:
  • 查詢特定數據:
可以向Prometheus Server指定欲取得的特定時間範圍內的資料。
  • 聚合與分組 (Aggregation and Grouping):
PromQL讓使用者可以依照指定條件為metrics資料進行分組,例如可以將工作內容相似 / 作用相似的數據分組在一起。分組後的資料能夠進行進一步的函式操作,像是取加總、平均值等等,協助使用者進一步觀察多個不同instances / jobs之間資料的關係和系統表現。
  • 警示 (Alerting):
使用者可以透過PromQL對Prometheus Server下達一系列的警示條件,當特定數據滿足條件時,便會觸發警示。
  • 找出規則 / 數據特性:
讓使用者能夠找到metrics數據的一些特定模式 (pattern),並根據使用者需求產生特定的dashboard,觀察這些特性。

2.4.2 Examples of PromQL

以下是PromQL的一些操作範例:
  • http_requests_total{status!~”4..”}
查詢除了狀態數字為4開頭的所有HTTP status code
  • rate(http_requests_total[5m])
查詢五分鐘內的平均每秒數據
PromQL有三種主要的查詢結果:
  • 瞬時數據 (Instant vector)
    • 包含一組數據,給定一個時間戳(timestamp),回傳一時間點下的結果
    • 例如:http_requests_total
  • 區間數據 (Range vector)
    • 包含一組數據,有一個特定的時間範圍,回傳該範圍內的結果
    • 例如:http_requests_total[5m]
  • 純量數據 (Scalar)
    • 只會有一個數字,常出現於計算結果
    • 例如:count(http_requests_total)

2.5 Alertmanager

Alertmanager 處理客戶端應用程序(例如Prometheus Server)發送的警報。它負責重複數據刪除 (Deduplicating) 、分組 (Grouping) 並將它們路由 (Routing) 到正確的接收器集成,例如Email, PagerDuty, OpsGenie 或通過通用 webhook 接口的自定義集成。Alertmanager還負責警報的靜音 (Slience) 和抑制 (Inhibition) 。

2.5.1 Use Case of Alertmanager

  1. 當Server端發生異常或即將發生異常的話,就會發生Alert,Alermanager就會發送訊息到Client端,以下為幾個會發生警報的情況。
  1. 在檢查每台server的內存使用狀態時,如果其中一台server的內存使用量超過70%超過一個小時,就會觸發警報通知該服務器上的內存可能很快就會耗盡。
  1. 當Elasticsearch不接受新的logs時,因為server的disk space不足或Elasticsearch達到存儲空間分配的存儲限制。此時,監視工具將觸發警報,通知維護人員可能的存儲問題,並且可以設置警報的臨界值。
  1. 當一個服務出現故障,開始在整個網路中循環發送數百條錯誤訊息,導致高網路流量並減慢其他服務的速度。這時,有一個工具可以檢測網路負載中的此類峰值並告訴我們哪個服務導致了這個問題,從而觸發警報以通知維護人員。

2.5.2 Functions

  1. Deduplicating:
透過計算 “groupkey” 來判斷警報是否為重複的。將重複的警報(具有相同的標籤(label) 和值 (value) 的警報)刪除,避免將多次相同的警報發送給同一個接收器。
  1. Grouping:
利用 “group_by” 將類似性質的警報歸類到同一通知中。在系統發生大型故障時特別有用,當許多系統同時出現故障並可能觸發數以百計的警報時,Grouping可以有效地處理和通知這些警報。
  1. Routing:
Routing是向各種接收器發送警報的能力。例如,Slack、Pagerduty、Opsgenie 和電子郵件。
  1. Inhibition:
當某些警報已經觸發時,抑制其他警報的通知。這樣可以防止接收到與實際問題無關的警報通知。
  1. Silences:
可以暫停警報發送,在特定時間內不再收到通知。Silence 配置文件中的 matchers 定義了要禁止通知的警報的標籤和標籤值。只有當傳入的警報匹配所有的 matchers 時,Alertmanager 才會將其靜音,並不再發送通知。Silence 的時間可以在配置中指定,也可以通過 API 進行設置。

3. 相近技術比較:InfluxDB vs Prometheus

InfluxDB 為儲存時間序列的資料庫,只要套用其插件 Kapacitor 便可對資料進行更進一步的數據轉換、執行異常偵測與警報通知等等,達到系統監控的功能,與 Prometheus的用途相似,因此本節將比較兩者架構上的不同,並敘述兩者分別適用的使用情境。

3.1 相同之處

InfluxDB 在儲存資料上與 Prometheus 相同,皆是以 key-value pair 的型態針對多維度的時間序列資料進行儲存和處理。更深入探究,InfluxDB 以 Bucket 作為區隔不同資料儲存policy的單位,每個 Bucket 下則會有許多 Measurement,即為一個序列資料的基本單位。在 Measurement 下則可定義 tag, field。查詢語言上,InfluxDB可搭配 InfluxQL進行資料查詢,而Prometheus使用PromQL。兩者都可以接到 Grafana 上。

3.2 儲存引擎差異

InfluxDB的時間精度可達奈秒,並支援浮點數、字串的輸入;而 Prometheus 則是毫秒,並只支援浮點數。再者,InfluxDB 底層用於儲存資料的結構為 TSM (Time-Structured Merge Tree),一種基於 LSM 的變形,在資料壓縮的表現較佳;而 Prometheus 則是使用 append-only 的方式儲存資料,在資料操作的靈活性上沒有前者佳,因此 InfluxDB 較適合 event logging,而 Prometheus 主要設計於metrics recording。

3.3 系統架構差異

InfluxDB 的商業版本是分散式的cluster,資料的儲存、queries都是由許多nodes 共同處理,並確保 Eventually Consistency,因為這樣的架構,InfluxDB比較容易進行水平擴增,因此非常適合用來儲存長期資料,且滿足高可用性的系統需求。相對地 Prometheus 則是運行在單節點上,水平擴增的能力較差,若達到流量上限產生擴增需求,Prometheus需透過其他開源項目來達成高可用性、儲存長期資料的目的,如Thanos或Cortex。

3.4 其他差異

在警報系統上,Prometheus偵測到異常資料後會由Alertmanger發送警報通知,兩者緊密集成;而InfluxDB沒有支援警報系統,只能透過Kapacitor對資料做進一步計算後發送警報。再者,Prometheus是用pull的方式接收資料,更適合用來監控靜態的資源分佈;而InfluxDB採用push的模式,由使用者主動推送資料,能夠動態地處理使用者希望監控的資源,但對於微服務這類更複雜的環境則需要進行額外的系統配置與管理。最後,Prometheus是CNCF認可的開源項目,和K8s有非常高度的集成性。
根據上述整理,若今天使用情境主要是做 event logging、系統有大量擴增需求、需要長期儲存資料、或是希望能自行動態地調整監控的目標資源,較適合使用InfluxDB;反之,若今天主要做 metrics recording、不會有頻繁的水平擴增需求、或使用k8s作為資源配置的工具、採用微服務框架,則適合使用Prometheus。順帶一提,若希望對Prometheus進行水平擴增,使其滿足高可用性、儲存長期資料,則需要透過Thanos或Cortex這類開源項目,以實現更高規模的資源監控。以Thanos為例,它會將集群的長期資料存放在目標儲存空間上 (支援Amazon S3、Google Cloud Storage等等),並透過Store Gateway讀取至本地端,由Thanos Query串接、查詢資料,並可採用Ruler設定警報規則。
  1. 參考資料
  1. Prometheus
  1. InfluxDB TSM
  1. Prometheus vs InfluxDB
  1. Thanos