《為什么說 Prometheus 是足以取代 Zabbix 的監控神器?》


為什么說 Prometheus 是足以取代 Zabbix 的監控神器?

作者:陳曉宇
來源: dbaplus 社群
校對: Bot(才雲)、 星空下的文仔(才雲)

Kubernetes 自從 2012年開源以來便以不可阻擋之勢成為容器領域調度和編排的領頭羊。Kubernetes 是 Google Borg 系統的開源實現,於此對應,Prometheus 則是 Google BorgMon 的開源實現。

Prometheus 是由 SoundCloud 開發的開源監控報警系統和時序列數據庫。從字面上理解,Prometheus 由兩個部分組成,一個是監控報警系統,另一個是自帶的時序數據庫(TSDB)。

2016 年,由 Google 發起的 Linux 基金會旗下的雲原生計算基金會(CNCF)將 Prometheus 納入作為其第二大開源項目。Prometheus 在開源社區也十分活躍,在 GitHub 上擁有兩萬多 Star,並且系統每隔一兩周就會有一個小版本的更新。

各種監控工具對比

其實,在 Prometheus 之前,市面已經出現了很多的監控系統,如 Zabbix、Open-Falcon、Nagios 等。那么 Prometheus 和這些監控系統有啥異同呢?我們先簡單回顧一下這些監控系統。

Zabbix

Zabbix 是由 Alexei Vladishev 開源的分布式監控系統,支持多種采集方式和采集客戶端,同時支持 SNMP、IPMI、JMX、Telnet、SSH 等多種協議。它將采集到的數據存放到數據庫中,然后對其進行分析整理,如果符合告警規則,則觸發相應的告警。

Zabbix 核心組件主要是 Agent 和 Server。其中 Agent 主要負責采集數據並通過主動或者被動的方式將采集數據發送到 Server/Proxy。除此之外,為了擴展監控項,Agent 還支持執行自定義腳本。Server 主要負責接收 Agent 發送的監控信息,並進行匯總存儲、觸發告警等。

Zabbix Server 將收集的監控數據存儲到 Zabbix Database 中。Zabbix Database 支持常用的關系型數據庫,如 MySQL、PostgreSQL、Oracle 等(默認是 MySQL),並提供 Zabbix Web 頁面(PHP 編寫)數據查詢。

由於使用了關系型數據存儲時序數據,Zabbix在監控大規模集群時常常在數據存儲方面捉襟見肘。所以從 4.2 版本后 Zabbix開始支持 TimescaleDB 時序數據庫,不過目前成熟度還不高。

Open-Falcon

Open-Falcon 是小米開源的企業級監控工具,用 Go 語言開發而成。這是一款靈活、可擴展並且高性能的監控方案,包括小米、滴滴、美團等在內的互聯網公司都在使用它。它的主要組件包括:

Falcon-agent:這是用 Go 語言開發的 Daemon 程序,運行在每台 Linux 服務器上,用於采集主機上的各種指標數據,主要包括 CPU、內存、磁盤、文件系統、內核參數、Socket 連接等,目前已經支持 200 多項監控指標。並且,Agent 支持用戶自定義的監控腳本。

Hearthbeat server:簡稱 HBS 心跳服務。每個 Agent 都會周期性地通過 RPC 方式將自己的狀態上報給 HBS,主要包括主機名、主機 IP、Agent 版本和插件版本,Agent 還會從 HBS 獲取自己需要執行的采集任務和自定義插件。

Transfer:負責接收 Agent 發送的監控數據,並對數據進行整理,在過濾后通過一致性 Hash 算法發送到 Judge 或者 Graph。

Graph:這是基於 RRD 的數據上報、歸檔、存儲組件。Graph 在收到數據以后,會以 rrdtool 的數據歸檔方式來存儲,同時提供 RPC 方式的監控查詢接口。

Judge 告警模塊:Transfer 轉發到 Judge 的數據會觸發用戶設定的告警規則,如果滿足,則會觸發郵件、微信或者回調接口。這里為了避免重復告警引入了 Redis 暫存告警,從而完成告警的合並和抑制。

Dashboard:這是面向用戶的監控數據查詢和告警配置界面。

Nagios

 

Nagios 原名為 NetSaint,由 Ethan Galstad 開發並維護。Nagios 是一個老牌監控工具,由 C 語言編寫而成,主要針對主機監控(CPU、內存、磁盤等)和網絡監控(SMTP、POP3、HTTP 和 NNTP 等),當然也支持用戶自定義的監控腳本。

它還支持一種更加通用和安全的采集方式:NREP(Nagios Remote Plugin Executor)。它會先在遠端啟動一個 NREP 守護進程,用於在遠端主機上運行檢測命令,在 Nagios 服務端用 check nrep 的 plugin 插件通過 SSL 對接到 NREP 守護進程執行相應的監控行為。相比 SSH 遠程執行命令的方式,這種方式更加安全。4Prometheus

Prometheus 的基本原理是通過 HTTP 周期性抓取被監控組件的狀態。任意組件只要提供對應的 HTTP 接口並且符合 Prometheus 定義的數據格式,就可以接入 Prometheus 監控。

Prometheus Server 負責定時在目標上抓取 metrics(指標)數據並保存到本地存儲。它采用了一種 Pull(拉)的方式獲取數據,不僅降低客戶端的復雜度,客戶端只需要采集數據,無需了解服務端情況,也讓服務端可以更加方便地水平擴展。

如果監控數據達到告警閾值,Prometheus Server 會通過 HTTP 將告警發送到告警模塊 alertmanger,通過告警的抑制后觸發郵件或者 Webhook。Prometheus 支持 PromQL 提供多維度數據模型和靈活的查詢,通過監控指標關聯多個 tag 的方式,將監控數據進行任意維度的組合以及聚合。

綜合對比

綜合對比如上面的表格,從開發語言上看,為了應對高並發和快速迭代的需求,監控系統的開發語言已經慢慢從 C 語言轉移到 Go。不得不說,Go 憑借簡潔的語法和優雅的並發,在 Java 占據業務開發、C 占領底層開發的情況下,准確定位中間件開發需求,在當前開源中間件產品中被廣泛應用。

從系統成熟度上看,Zabbix 和 Nagios 都是老牌的監控系統:Nagios 是在 1999 年出現的,Zabbix 是在 1998 年出現的,系統功能比較穩定,成熟度較高。而 Prometheus 和 Open-Falcon 都是最近幾年才誕生的,雖然功能還在不斷迭代更新,但站在巨人的肩膀之上,在架構設計上借鑒了很多老牌監控系統的經驗。

從系統擴展性方面看,Zabbix 和 Open-Falcon 都可以自定義各種監控腳本,並且 Zabbix 不僅可以做到主動推送,還可以做到被動拉取。Prometheus 則定義了一套監控數據規范,並通過各種 exporter 擴展系統采集能力。

從數據存儲方面來看,Zabbix 采用關系數據庫保存,這極大限制了 Zabbix 的采集性能;Nagios 和 Open-Falcon 都采用 RDD 數據存儲,Open-Falcon 還加入了一致性 hash 算法分片數據,並且可以對接到 OpenTSDB;而 Prometheus 則自研了一套高性能的時序數據庫,在 V3 版本可以達到每秒千萬級別的數據存儲,通過對接第三方時序數據庫擴展歷史數據的存儲。

從配置復雜度上看,Prometheus 只有一個核心 server 組件,一條命令便可以啟動。相比而言,其他系統配置相對麻煩,尤其是 Open-Falcon。

從社區活躍度上看,目前 Zabbix 和 Nagios 的社區活躍度比較低,尤其是 Nagios;Open-Falcon 雖然也比較活躍,但基本都是國內公司在參與;Prometheus 在這方面占據絕對優勢,社區活躍度最高,並且受到 CNCF 的支持,后期的發展值得期待。

從容器支持角度看,由於 Zabbix 和 Nagios 出現得比較早,當時容器還沒有誕生,它們對容器的支持自然比較差;Open-Falcon 雖然提供了容器的監控,但支持力度有限;Prometheus 的動態發現機制,不僅可以支持 Swarm 原生集群,還支持 Kubernetes 容器集群的監控,是目前容器監控最好解決方案;Zabbix 在傳統監控系統中,尤其是在服務器相關監控方面,占據絕對優勢;而 Nagios 則在網絡監控方面有廣泛應用。伴隨着容器的發展,Prometheus 已開始成為主導及容器監控方面的標配,並且在未來可見的時間內將被廣泛應用。

總體來說,對比各種監控系統的優劣,Prometheus 可以說是目前監控領域最鋒利的“瑞士軍刀”了。

Prometheus 功能介紹

下圖是 Prometheus 的整體架構圖。左側是各種數據源,主要是各種符合 Prometheus 數據格式的 exporter。除此之外,為了支持推送數據的 Agent,你可以通過 Pushgateway 組件,將 Push 轉化為 Pull。Prometheus 甚至可以從其它的 Prometheus 獲取數據,這點在后面介紹聯邦的時候詳細解釋。

圖片的上側是服務發現。Prometheus 支持監控對象的自動發現機制,從而可以動態獲取監控對象。雖然 Zabbix 和 Open-Falcon 也支持動態發現機制,但 Prometheus 的支持最完善。

圖片中間是核心:通過 Retrieval 模塊定時拉取數據,通過 Storage 模塊保存數據。PromQL 是 Prometheus 提供的查詢語法,PromQL 通過解析語法樹,查詢 Storage 模塊獲取監控數據。圖片右側是告警和頁面展現,頁面查看除了 Prometheus 自帶的 WebUI,還可以通過 Grafana 等組件查詢 Prometheus 監控數據。

Prometheus 指標格式分為兩個部分:一是指標名稱,另一個是指標標簽。格式如下:

標簽可體現指標的維度特征。例如,對於指標 http_request_total,可以有 {status="200", method="POST"} 和 {status="200", method="GET"} 這兩個標簽。在需要分別獲取 GET 和 POST 返回 200 的請求時,可分別使用上述兩種指標;在需要獲取所有返回 200 的請求時,可以通過 http_request_total{status="200"} 完成數據的聚合,非常便捷和通用。Prometheus 指標類型有四種:

  • Counter(計數器):計數統計,累計多長或者累計多少次等。它的特點是只增不減,譬如 HTTP 訪問總量;
  • Gauge(儀表盤):數據是一個瞬時值,如果當前內存用量,它隨着時間變化忽高忽低;
  • Histogram(直方圖):服務端分位,不同區間內樣本的個數,譬如班級成績,低於 60 分的 9 個,低於 70 分的 10 個,低於 80 分的 50 個。
  • Summary(摘要):客戶端分位,直接在客戶端通過分位情況,還是用班級成績舉例:0.8 分位的是,80 分,0.9 分位的是 85 分,0.99 分位的是 98 分。

*注:關於 Gauge:如果需要了解某個時間段內請求的響應時間,通常做法是使用平均響應時間,但這樣做無法體現數據的長尾效應。例如,一個 HTTP 服務器的正常響應時間是 30ms,但有很少幾次請求耗時 3s,通過平均響應時間很難甄別長尾效應,所以 Prometheus 引入了 Histogram 和 Summary。

Prometheus 通過 HTTP 接口的方式從各種客戶端獲取數據,這些客戶端必須符合 Prometheus 監控數據格式。通常它有兩種方式,一種是侵入式埋點監控,通過在客戶端引入Prometheus go client,提供 /metrics 接口查詢 Kubernetes API 各種指標。另一種是通過 exporter 方式,在外部將原來各種中間件的監控支持轉化為 Prometheus 的監控數據格式,如 Redis Exporter 將 Redis 指標轉化為 Prometheus 能夠識別的 HTTP 請求。Prometheus 並沒有采用 JSON 的數據格式,而是采用 text/plain 純文本的方式 ,這是它的特殊之處。HTTP 返回 Header 和 Body 如上圖所示,指標前面兩行 # 是注釋,標識指標的含義和類型。指標和指標的值通過空格分割,開發者通常不需要自己拼接這種個數的數據, Prometheus 提供了各種語言的 SDK 支持。

Prometheus 為了支持各種中間件以及第三方的監控提供了 exporter,大家可以把它理解成監控適配器,將不同指標類型和格式的數據統一轉化為 Prometheus 能夠識別的指標類型。譬如 Node Exporter 主要通過讀取 Linux 的 /proc 以及 /sys 目錄下的系統文件獲取操作系統運行狀態,Redis Exporter 通過 Redis 命令行獲取指標,MySQL Exporter 通過讀取數據庫監控表獲取 MySQL 的性能數據。他們將這些異構的數據轉化為標准的 Prometheus 格式,並提供 HTTP 查詢接口。

Prometheus 提供了兩種數據持久化方式:一種是本地存儲,通過 Prometheus 自帶的 TSDB(時序數據庫),將數據保存到本地磁盤,為了性能考慮,建議使用 SSD。但本地存儲的容量畢竟有限,建議不要保存超過一個月的數據。Prometheus 本地存儲經過多年改進,自 Prometheus 2.0 后提供的 V3 版本,TSDB 的性能已經非常高,可以支持單機每秒 1000 萬個指標的收集。另一種是遠端存儲,適用於大量歷史監控數據的存儲和查詢。通過中間層的適配器的轉化,Prometheus 將數據保存到遠端存儲。適配器實現 Prometheus 存儲的 remote write 和 remote read 接口,並把數據轉化為遠端存儲支持的數據格式。目前,遠端存儲主要包括 OpenTSDB、InfluxDB、Elasticsearch、M3db、Kafka 等,其中 M3db 是目前非常受歡迎的后端存儲。

和關系型數據庫的 SQL 類似,Prometheus 也內置了數據查詢語言 PromQL,它提供對時間序列數據豐富的查詢,聚合以及邏輯運算的能力。一條 PromQL 主要包括指標名稱、過濾器以及函數和參數。指標可以進行數據運算,包括 +(加)、-(減)、*(乘)、/(除)、%(求余)、^(冪運算),聚合函數包括 sum(求和)、min(最小值)、max(最大值)、avg(平均值)、stddev(標准差)、count(計數)、topk(前 n 條)、quantile(分布統計)等。查詢數據通過 HTTP GET 請求發送 PromQL 查詢語句。形式如下:

其中 query 參數就是一條 PromQL 表達式。除此之外還支持范圍查詢 query_range,需要額外添加 start(起始時間)、end(結束時間)、step(查詢步長)這三個參數。無論是 Prometheus 自帶的 WebUI 還是通過 Grafana,它們本質上都是通過 HTTP 發送 PromQL 的方式查詢 Prometheus 數據。整個解析流程如下所示:

當 Prometheus 接收請求后,通過 PromQL 引擎解析 PromQL,確定查詢時間序列和查詢時間范圍,通過 TSDB 接口獲取對應數據塊,最后根據聚合函數處理監控數據並返回。

Prometheus 告警配置也是通過 YAML 文件配置,核心是上面的 expr 參數(告警規則),和查詢一樣,這也是一個 PromQL 表達式。for 代表持續時間,如果在 for 時間內持續觸發,Prometheus 才發出告警至 alertmanger。告警組件 alertmanger 地址是在 Prometheus 的配置文件中指定,告警經過 alertmanger 去重、抑制等操作,最后執行告警動作,目前支持郵件、Slack、微信和 Webhook,如果是對接釘釘,可以通過 Webhook 方式觸發釘釘的客戶端發送告警。

Prometheus 配置監控對象有兩種方式,一種是通過靜態文件配置,另一種是動態發現機制,自動注冊監控對象。Prometheus 動態發現目前已經支持 K8s、etcd、Consul 等多種服務發現機制。動態發現機制可以減少運維人員手動配置,在容器運行環境中尤為重要:容器集群通常在幾千甚至幾萬的規模,如果每個容器都需要單獨配置監控項不僅需要大量工作量,而且容器經常變動,后續維護更是異常麻煩。針對 K8s 環境的動態發現,Prometheus 通過 watch Kubernetes API 動態獲取當前集群所有服務和容器情況,從而動態調整監控對象。

為了擴展單個 Prometheus 的采集能力和存儲能力,Prometheus 引入了“聯邦”的概念。多個 Prometheus 節點組成兩層聯邦結構,如圖所示,上面一層是聯邦節點,負責定時從下面的 Prometheus 節點獲取數據並匯總,部署多個聯邦節點是為了實現高可用。下層的 Prometheus 節點又分別負責不同區域的數據采集,在多機房的事件部署中,下層的每個 Prometheus 節點可以被部署到單獨的一個機房,充當代理。K8sMeetup

總結

最后我想表達,Prometheus 也並非銀彈。

首先,Prometheus 只針對性能和可用性監控,並不具備日志監控等功能,並不能通過 Prometheus 解決所有監控問題。

其次,Prometheus 認為只有最近的監控數據才有查詢的需要,所有 Prometheus 本地存儲的設計初衷只是保持短期(一個月)的數據,並非針對大量的歷史數據的存儲。如果需要報表之類的歷史數據,則建議使用 Prometheus 的遠端存儲,如 OpenTSDB、M3db 等。

Prometheus 還有一個小瑕疵是沒有定義單位,這里需要使用者自己去區分或者事先定義好所有監控數據單位,避免數據缺少單位問題。

Q & A

Q1:Prometheus 能替代 Zabbix 嗎?

A:在我們的實際生產環境中,Prometheus 完全可以替代 Zabbix。並且由於我個人主要負責容器雲的建設,我對 Prometheus 更加青睞。

Q2:如何對 Prometheus 進行權限限制?類似於 Zabbix 的用戶密碼校驗。A:其實 Prometheus 本身沒有任何的權限限制,因為作為一套監控系統,它認為這種權限的管理應該屬於上面管理權限的系統去維護,而不應該在它這樣一套監控系統里做,所以 Prometheus 本身在設計上就沒有做任何的權限管理。Q3:Prometheus 可以監控 Web 地址嗎?類似於 Zabbix 的 Web 場景。

A:Prometheus 結合 blockbox 可以去監控一些 Web 站點是不是健康,它會定時去調用一些你們提供的 Web 接口,然后通過分析接口返回碼或者是返回體,判斷 Web 服務是否健康,可以作為站點監控。除此之外它還支持 TCP、DNS、ICMP 以及 HTTPS。

Q4:Prometheus 和 Ansible 有相同作用么?

A:我理解的 Ansible 其實還是一種自動化運維工具,它雖然有一些簡單監控,但是核心並不在監控上面,而是自動化部署和運維上的一些能力,而 Prometheus 本身只是一個單純的監控和告警的組件。

Q5:請對比下 InfluxDB 和 Prometheus,個人覺得 InfluxDB 易用性更好。

A:InfluxDB 本身沒有任何監控數據的能力,InfluxDB 的商業版本是集群的,可以存儲大量的數據,但是開源版本是單機的,不建議使用。Prometheus 不但具有數據存儲能力,還有數據指標采集能力,而單純的 InfluxDB 只有數據存儲能力。

Q6:老師你們公司內部只用 Prometheus 做監控嗎?還用其他產品配合嗎?

A:我們公司內部之前使用的是 Zabbix 監控,目前正在從 Zabbix 監控切換到 Prometheus 監控。

Q7:哪種監控工具更適合做業務指標監控?

A:我個人接觸過的業務指標監控主要是通過 Graphite、Prometheus 以及 UAV 監控,通常的業務指標監控都是通過埋點完成,大同小異。

Q8:Prometheus 監控 Oracle、MySQL 數據庫方便嗎?A:現在由於各種 Prometheus export 非常豐富,針對這些中間件,如 Oracle、MySQL 這種監控是非常方便的,目前支持得也比較好。在我們自己的環境里面,我們通過 Kafka 的 export、MySQL 的 export、Redis 的 export 分別去監控我們自己的組件狀態,如果你有一些自己定制的監控指標,也可以去定制一些 export,這些東西都比較簡單,並不是很困難。Q9:Prometheus 用什么存儲比較好?本地存儲容量有限。

A:在我們實際生產環境中,本地存儲只保留一個月數據,歷史數據都放到 M3db 中保存。

Q10:我目前監控一種類型的對象,就需要一個 exporter,對象越多 exporter 的量也不斷增長,怎么解決?

A:大部分監控對象都需要特定類型 exporter,因為每種類型的監控指標的數據格式不一樣,都要特定的 exporter 去解析這種指標,並且轉換為 Prometheus 識別的指標類型。至於說 exporter 的量非常多,exporter 本身是很輕量級的,雖然多,但是在我們自己部署的環境里面,有的時候就和我們的應用捆綁到一個 Pod 去部署,其實非常方便維護,本身也不會有什么負載壓力。exporter 本身很穩定,維護起來也非常簡單。

Q11:非容器化部署的中間件也能監控嗎?

A:其實 Prometheus 采集數據的時候,只看采集數據的監控格式是否滿足它的需求,它本身並不關心被監控對象是不是在容器里面,沒有任何關系。只要對外暴露的監控數據格式符合 Prometheus 的要求就可以。

Q12:Prometheus 能把時序數據實時發送到 Kafka 嗎?

A:可以的,目前社區已經有一個 Kafka 的 exporter,可以把監控數據寫到 Kafka 里。

Q13:Prometheus 除了聯邦集群的方式,是否存在心跳或者類似集群化的部署?

A:Improbable 開源的 Thanos 提供了 Prometheus 集群化能力,感興趣的朋友可以深入了解一下。

Q14:Prometheus 配置網絡設備時,有什么簡易方式嗎?設備類型跟 OID 有一定差異的情況下,有什么簡易方式?

A:Prometheus 通過 SNMP exporter 監控網絡設備時,OID 也需要單獨配置,目前沒有啥好辦法。

Q15:如何更好地閱讀 Prometheus 的源碼?Prometheus 的源碼質量如何?

A:Prometheus 代碼包結構清晰,學習 Go 語言的朋友可以深度讀一遍。建議首先看數據采集和 PromQL 解析,最后看 TSDB。

Q16:Prometheus 未來會向哪個方向發展?

A:Prometheus 目前正在慢慢成為基於 HTTP 監控的規范,目前在容器領域和 Kubernetes 一起,已經確定了領導地位,越來越多的中間件也開始原生支持 Prometheus 監控。Prometheus 3.x 即將發布,主要增強集群能力、數據存儲能力以及安全性。

作者簡介

陳曉宇

宜信容器雲架構師

  • 負責宜信 PaaS 平台的設計和推廣,幫助企業從傳統應用遷移至雲原生;
  • 在雲計算相關行業具有豐富的研發與架構經驗,參與多個社區開源項目,如 Openstack、Kubernetes、Harbor 等;
  • 曾參與編寫《深入淺出 Prometheus》一書。
編輯於 2019-11-11
 
 
 

 
 
 
Branch:  master  New pull request
Upload files Find file
Clone or download 
Type Name Latest commit message Commit time
  alert fix the error of prometheus.yml 4 months ago
  draft update grafana last year
  examples use operator deploy alertmanager last year
  exporter typo fix 8 months ago
  grafana Update use-console-template.md 2 months ago
  ha Update scale-prometheus-with-federation.md 2 months ago
  kubernetes 修正獲取節點容器一節部分代碼和圖片描述錯亂 6 months ago
  operator Update use-operator-manage-prometheus.md 11 months ago
  prometheus update compose 2 years ago
  promql Update what-is-prometheus-metrics-and-labels.md 2 months ago
  quickstart Merge branch 'master' of github.com:yunlzheng/prometheus-book 11 months ago
  rancher refactor struct 2 years ago
  samples/client_java_samples add client java example 2 years ago
  sd Merge pull request #44 from riverbuilding/patch-5 16 days ago
  sources update static image resoures last year
  .gitignore update gitognore last year
  .nvmrc init struct 2 years ago
  AUTHOR.md 重構 2 years ago
  CHANGELOGS.md clean language 2 years ago
  CHECKLIST.md fixed feedback 2 years ago
  Introduction.md Update Introduction.md 6 months ago
  PLACE_HOLDER.md adjust summary last year
  README.md Update README.md 6 months ago
  REFERENCES.md add mysqld exporter 2 years ago
  SUMMARY.md clean repo 6 months ago
  TODO.md add grafana table panel 2 years ago
  Vagrantfile update summary 2 years ago
  book.json clean content 2 years ago
  docker-compose.yml update 2 years ago
  package.json refactor sd with prometheus 2 years ago

 README.md

目錄

Part I - Prometheus基礎

Part II - Prometheus進階

Part III - Prometheus實戰


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM