一、監控系統概論
監控系統在這里特指對數據中心的監控,主要針對數據中心內的硬件和軟件進行監控和告警。企業的 IT 架構逐步從傳統的物理服務器,遷移到以虛擬機為主導的 IaaS 雲。無論基礎架構如何調整,都離不開監控系統的支持。
不僅如此。越來越復雜的數據中心環境對監控系統提出了更越來越高的要求:需要監控不同的對象,例如容器,分布式存儲,SDN網絡,分布式系統。各種應用程序等,種類繁多,還需要采集和存儲大量的監控數據,例如每天數TB數據的采集匯總。以及基於這些監控數據的智能分析,告警及預警等。
在每個企業的數據中心內,或多或少都會使用一些開源或者商業的監控系統。從監控對象的角度來看,可以將監控分為網絡監控,存儲監控,服務器監控和應用監控等,因為需要監控數據中心的各個方面。所以監控系統需要做到面面俱到,在數據中心中充當“天眼“角色。
二、基礎資源監控
2.1、網絡監控
網絡性能監控:主要涉及網絡監測,網絡實時流量監控(網絡延遲、訪問量、成功率)和歷史數據統計、匯總和歷史數據分析等功能。
網絡檢測*:主要針對內網或者外網的網絡***。如DDoS的。通過分析異常流量來確定網絡行為。
設備監控:主要針對數據中心內的多種網絡設備進行監控。包括路由器,防火牆和交換機等硬件設備,可以通過snmp等協議收集數據。
2.2、存儲監控
存儲性能監控方面:存儲通常監控塊的讀寫速率,IOPS。讀寫延遲,磁盤用量等;文件存儲通常監控文件系統inode。讀寫速度、目錄權限等。
存儲系統監控方面:不同的存儲系統有不同的指標,例如,對於ceph存儲需要監控OSD, MON的運行狀態,各種狀態pg的數量以及集群IOPS等信息。
存儲設備監控方面:對於構建在x86服務器上的存儲設備,設備監控通過每個存儲節點上的采集器統一收集磁盤、SSD、網卡等設備信息;存儲廠商以黑盒方式提供商業存儲設備,通常自帶監控功能,可監控設備的運行狀態,性能和容量的。
2.3、服務器監控
CPU:涉及整個 CPU 的使用量、用戶態百分比、內核態百分比,每個 CPU 的使用量、等待隊列長度、I/O 等待百分比、CPU 消耗最多的進程、上下文切換次數、緩存命中率等。
內存:涉及內存的使用量、剩余量、內存占用最高的進程、交換分區大小、缺頁異常等。
網絡 I/O:涉及每個網卡的上行流量、下行流量、網絡延遲、丟包率等。
磁盤 I/O:涉及硬盤的讀寫速率、IOPS、磁盤用量、讀寫延遲等。
2.4、中間件監控
消息中間件: RabbitMQ、Kafka
Web 服務中間件:Tomcat、Jetty
緩存中間件:Redis、Memcached
數據庫中間件:MySQL、PostgreSQL
2.5、應用程序監控(APM)
APM主要是針對應用程序的監控,包括應用程序的運行狀態監控,性能監控,日志監控及調用鏈跟蹤等。調用鏈跟蹤是指追蹤整個請求過程(從用戶發送請求,通常指瀏覽器或者應用客戶端)到后端API服務以及API服務和關聯的中間件,或者其他組件之間的調用,構建出一個完整的調用拓撲結構,不僅如此,APM 還可以監控組件內部方法的調用層次(Controller–>service–>Dao)獲取每個函數的執行耗時,從而為性能調優提供數據支撐。
應用程序監控工具除了有 Pinpoint,還有 Twitter 開源的 Zipkin,Apache SkyWalking,美團開源的 CAT等。
調用鍵監控
幾款產品對比
Pinpoint
通過 APM 除了可以截獲方法調用,還可以截獲TCP、HTTP網絡請求,從而獲得執行耗時最長的方法和 SQL 語句、延遲最大的 API 的信息。
三、Prometheus 簡介
3.1、什么是 Prometheus
Prometheus 是一套開源的系統監控報警框架。它啟發於 Google 的 borgmon 監控系統,由工作在 SoundCloud 的 google 前員工在 2012 年創建,作為社區開源項目進行開發,並於 2015 年正式發布。2016 年,Prometheus 正式加入 Cloud Native Computing Foundation,成為受歡迎度僅次於 Kubernetes 的項目。
3.2、優點
-
強大的多維度數據模型:
- 時間序列數據通過 metric 名和鍵值對來區分。
- 所有的 metrics 都可以設置任意的多維標簽。
- 數據模型更隨意,不需要刻意設置為以點分隔的字符串。
- 可以對數據模型進行聚合,切割和切片操作。
- 支持雙精度浮點類型,標簽可以設為全 unicode。
-
靈活而強大的查詢語句(PromQL):在同一個查詢語句,可以對多個 metrics 進行乘法、加法、連接、取分數位等操作。
-
易於管理: Prometheus server 是一個單獨的二進制文件,可直接在本地工作,不依賴於分布式存儲。
-
高效:平均每個采樣點僅占 3.5 bytes,且一個 Prometheus server 可以處理數百萬的 metrics。
-
使用 pull 模式采集時間序列數據,這樣不僅有利於本機測試而且可以避免有問題的服務器推送壞的 metrics。
-
可以采用 push gateway 的方式把時間序列數據推送至 Prometheus server 端。
-
可以通過服務發現或者靜態配置去獲取監控的 targets。
-
有多種可視化圖形界面。
-
易於伸縮。
3.3、組件
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 等。
- 一些其他的工具。
3.4、架構
從這個架構圖,也可以看出 Prometheus 的主要模塊包含, Server, Exporters, Pushgateway, PromQL, Alertmanager, WebUI 等。
它大致使用邏輯是這樣:
- Prometheus server 定期從靜態配置的 targets 或者服務發現的 targets 拉取數據。
- 當新拉取的數據大於配置內存緩存區的時候,Prometheus 會將數據持久化到磁盤(如果使用 remote storage 將持久化到雲端)。
- Prometheus 可以配置 rules,然后定時查詢數據,當條件觸發的時候,會將 alert 推送到配置的 Alertmanager。
- Alertmanager 收到警告的時候,可以根據配置,聚合,去重,降噪,最后發送警告。
- 可以使用 API, Prometheus Console 或者 Grafana 查詢和聚合數據。
3.5、適用於什么場景
Prometheus 適用於記錄文本格式的時間序列,它既適用於以機器為中心的監控,也適用於高度動態的面向服務架構的監控。在微服務的世界中,它對多維數據收集和查詢的支持有特殊優勢。Prometheus 是專為提高系統可靠性而設計的,它可以在斷電期間快速診斷問題,每個 Prometheus Server 都是相互獨立的,不依賴於網絡存儲或其他遠程服務。當基礎架構出現故障時,你可以通過 Prometheus 快速定位故障點,而且不會消耗大量的基礎架構資源。
3.6、不適合什么場景
Prometheus 非常重視可靠性,即使在出現故障的情況下,你也可以隨時查看有關系統的可用統計信息。如果你需要百分之百的准確度,例如按請求數量計費,那么 Prometheus 不太適合你,因為它收集的數據可能不夠詳細完整。這種情況下,你最好使用其他系統來收集和分析數據以進行計費,並使用 Prometheus 來監控系統的其余部分。
四、數據模型
4.1、數據模型
Prometheus 所有采集的監控數據均以指標(metric)的形式保存在內置的時間序列數據庫當中(TSDB):屬於同一指標名稱,同一標簽集合的、有時間戳標記的數據流。除了存儲的時間序列,Prometheus 還可以根據查詢請求產生臨時的、衍生的時間序列作為返回結果。
指標名稱和標簽
每一條時間序列由指標名稱(Metrics Name)以及一組標簽(鍵值對)唯一標識。其中指標的名稱(metric name)可以反映被監控樣本的含義(例如,http_requests_total
— 表示當前系統接收到的 HTTP 請求總量),指標名稱只能由 ASCII 字符、數字、下划線以及冒號組成,同時必須匹配正則表達式 [a-zA-Z_:][a-zA-Z0-9_:]*
。
[info] 注意
冒號用來表示用戶自定義的記錄規則,不能在 exporter 中或監控對象直接暴露的指標中使用冒號來定義指標名稱。
通過使用標簽,Prometheus 開啟了強大的多維數據模型:對於相同的指標名稱,通過不同標簽列表的集合,會形成特定的度量維度實例(例如:所有包含度量名稱為 /api/tracks
的 http 請求,打上 method=POST
的標簽,就會形成具體的 http 請求)。該查詢語言在這些指標和標簽列表的基礎上進行過濾和聚合。改變任何度量指標上的任何標簽值(包括添加或刪除指標),都會創建新的時間序列。
標簽的名稱只能由 ASCII 字符、數字以及下划線組成並滿足正則表達式 [a-zA-Z_][a-zA-Z0-9_]*
。其中以 __
作為前綴的標簽,是系統保留的關鍵字,只能在系統內部使用。標簽的值則可以包含任何 Unicode
編碼的字符。
時序樣本
在時間序列中的每一個點稱為一個樣本(sample),樣本由以下三部分組成:
- 指標(metric):指標名稱和描述當前樣本特征的 labelsets;
- 時間戳(timestamp):一個精確到毫秒的時間戳;
- 樣本值(value): 一個 folat64 的浮點型數據表示當前樣本的值。
格式
通過如下表達方式表示指定指標名稱和指定標簽集合的時間序列:
例如,指標名稱為 api_http_requests_total
,標簽為 method="POST"
和 handler="/messages"
的時間序列可以表示為:
這與 OpenTSDB 中使用的標記法相同。
4.2、指標類型
Prometheus 的客戶端庫中提供了四種核心的指標類型。但這些類型只是在客戶端庫(客戶端可以根據不同的數據類型調用不同的 API 接口)和在線協議中,實際在 Prometheus server 中並不對指標類型進行區分,而是簡單地把這些指標統一視為無類型的時間序列。不過,將來我們會努力改變這一現狀的。
Counter
- 一種累加的 metric,典型的應用如:請求的個數,結束的任務數, 出現的錯誤數等等。
例如 Prometheus server 中 http_requests_total
, 表示 Prometheus 處理的 http 請求總數,我們可以使用 delta
, 很容易得到任意區間數據的增量,這個會在 PromQL 一節中細講。
Gauge
- 一種常規的 metric,典型的應用如:溫度,運行的 goroutines 的個數。
- 可以任意加減。
例如 Prometheus server 中 go_goroutines
, 表示 Prometheus 當前 goroutines 的數量。
Histogram
- 可以理解為柱狀圖,典型的應用如:請求持續時間,響應大小。
- 可以對觀察結果采樣,分組及統計。
例如,查詢 prometheus_http_request_duration_seconds_sum{handler=“/api/v1/query”,instance=“localhost:9090”,job=“prometheus”}時,返回結果如下:
Summary
- 類似於 Histogram, 典型的應用如:請求持續時間,響應大小。
- 提供觀測值的 count 和 sum 功能。
- 提供百分位的功能,即可以按百分比划分跟蹤結果。
4.3、instance 和 jobs
Prometheus 中,將任意一個獨立的數據源(target)稱之為實例(instance)。包含相同類型的實例的集合稱之為作業(job)。 如下是一個含有四個重復實例的作業:
自生成標簽和時序
Prometheus 在采集數據的同時,會自動在時序的基礎上添加標簽,作為數據源(target)的標識,以便區分:
job
: The configured job name that the target belongs to.instance
: The<host>:<port>
part of the target’s URL that was scraped.
如果其中任一標簽已經在此前采集的數據中存在,那么將會根據 honor_labels
設置選項來決定新標簽。詳見官網解釋: scrape configuration documentation
對每一個實例而言,Prometheus 按照以下時序來存儲所采集的數據樣本:
-
up{job="<job-name>", instance="<instance-id>"}
: 1 表示該實例正常工作 -
up{job="<job-name>", instance="<instance-id>"}
: 0 表示該實例故障 -
scrape_duration_seconds{job="<job-name>", instance="<instance-id>"}
表示拉取數據的時間間隔 -
scrape_samples_post_metric_relabeling{job="<job-name>", instance="<instance-id>"}
表示采用重定義標簽(relabeling)操作后仍然剩余的樣本數 -
scrape_samples_scraped{job="<job-name>", instance="<instance-id>"}
表示從該數據源獲取的樣本數
其中 up
時序可以有效應用於監控該實例是否正常工作。
五、其他監控工具
在前言中,簡單介紹了我們選擇 Prometheus 的理由,以及使用后給我們帶來的好處。
在這里主要和其他監控方案對比,方便大家更好的了解 Prometheus。
Prometheus vs Zabbix
- Zabbix 使用的是 C 和 PHP, Prometheus 使用 Golang, 整體而言 Prometheus 運行速度更快一點。
- Zabbix 屬於傳統主機監控,主要用於物理主機,交換機,網絡等監控,Prometheus 不僅適用主機監控,還適用於 Cloud, SaaS, Openstack,Container 監控。
- Zabbix 在傳統主機監控方面,有更豐富的插件。
- Zabbix 可以在 WebGui 中配置很多事情,但是 Prometheus 需要手動修改文件配置。
Prometheus vs Graphite
- Graphite 功能較少,它專注於兩件事,存儲時序數據, 可視化數據,其他功能需要安裝相關插件,而 Prometheus 屬於一站式,提供告警和趨勢分析的常見功能,它提供更強的數據存儲和查詢能力。
- 在水平擴展方案以及數據存儲周期上,Graphite 做的更好。
Prometheus vs InfluxDB
- InfluxDB 是一個開源的時序數據庫,主要用於存儲數據,如果想搭建監控告警系統, 需要依賴其他系統。
- InfluxDB 在存儲水平擴展以及高可用方面做的更好, 畢竟核心是數據庫。
Prometheus vs OpenTSDB
- OpenTSDB 是一個分布式時序數據庫,它依賴 Hadoop 和 HBase,能存儲更長久數據, 如果你系統已經運行了 Hadoop 和 HBase, 它是個不錯的選擇。
- 如果想搭建監控告警系統,OpenTSDB 需要依賴其他系統。
Prometheus vs Nagios
- Nagios 數據不支持自定義 Labels, 不支持查詢,告警也不支持去噪,分組, 沒有數據存儲,如果想查詢歷史狀態,需要安裝插件。
- Nagios 是上世紀 90 年代的監控系統,比較適合小集群或靜態系統的監控,顯然 Nagios 太古老了,很多特性都沒有,相比之下Prometheus 要優秀很多。
Prometheus vs Sensu
- Sensu 廣義上講是 Nagios 的升級版本,它解決了很多 Nagios 的問題,如果你對 Nagios 很熟悉,使用 Sensu 是個不錯的選擇。
- Sensu 依賴 RabbitMQ 和 Redis,數據存儲上擴展性更好。
總結
- Prometheus 屬於一站式監控告警平台,依賴少,功能齊全。
- Prometheus 支持對雲或容器的監控,其他系統主要對主機監控。
- Prometheus 數據查詢語句表現力更強大,內置更強大的統計函數。
- Prometheus 在數據存儲擴展性以及持久性上沒有 InfluxDB,OpenTSDB,Sensu 好。
六、Export
6.1、文本格式
在討論 Exporter 之前,有必要先介紹一下 Prometheus 文本數據格式,因為一個 Exporter 本質上就是將收集的數據,轉化為對應的文本格式,並提供 http 請求。
Exporter 收集的數據轉化的文本內容以行 (\n
) 為單位,空行將被忽略, 文本內容最后一行為空行
注釋
文本內容,如果以 #
開頭通常表示注釋。
- 以
# HELP
開頭表示 metric 幫助說明。 - 以
# TYPE
開頭表示定義 metric 類型,包含counter
,gauge
,histogram
,summary
, 和untyped
類型。 - 其他表示一般注釋,供閱讀使用,將被 Prometheus 忽略。
采樣數據
內容如果不以 #
開頭,表示采樣數據。它通常緊挨着類型定義行,滿足以下格式:
下面是一個完整的例子:
需要特別注意的是,假設采樣數據 metric 叫做 x
, 如果 x
是 histogram
或 summary
類型必需滿足以下條件:
- 采樣數據的總和應表示為
x_sum
。 - 采樣數據的總量應表示為
x_count
。 summary
類型的采樣數據的 quantile 應表示為x{quantile="y"}
。histogram
類型的采樣分區統計數據將表示為x_bucket{le="y"}
。histogram
類型的采樣必須包含x_bucket{le="+Inf"}
, 它的值等於x_count
的值。summary
和historam
中quantile
和le
必需按從小到大順序排列。
6.2、常用查詢
收集到 node_exporter 的數據后,我們可以使用 PromQL 進行一些業務查詢和監控,下面是一些比較常見的查詢。
注意:以下查詢均以單個節點作為例子,如果大家想查看所有節點,將 instance="xxx"
去掉即可。
CPU 使用率
CPU 各 mode 占比率
機器平均負載
內存使用率
磁盤使用率
或者你也可以直接使用 {fstype=“xxx”} 來指定想查看的磁盤信息