從0開始學微服務:15 如何搭建一個可靠的監控系統?

從0開始學微服務:15 如何搭建一個可靠的監控系統?

專欄第 7 期我給你講解了監控系統的實現原理,先來簡單回顧一下,一個監控系統的組成主要涉及四個環節:數據收集、數據傳輸、數據處理和數據展示。不同的監控系統實現方案,在這四個環節所使用的技術方案不同,適合的業務場景也不一樣。

目前,比較流行的開源監控系統實現方案主要有兩種:以ELK為代表的集中式日誌解決方案,以及Graphite、TICK和Prometheus等為代表的時序數據庫解決方案。接下來我就以這幾個常見的監控系統實現方案,談談它們的實現原理,分別適用於什麼場景,以及具體該如何做技術選型。

ELK

ELK 是 Elasticsearch、Logstash、Kibana 三個開源軟件產品首字母的縮寫,它們三個通常配合使用,所以被稱為 ELK Stack,它的架構可以用下面的圖片來描述。

從0開始學微服務:15 如何搭建一個可靠的監控系統?

這三個軟件的功能也各不相同。

  • Logstash 負責數據收集和傳輸,它支持動態地從各種數據源收集數據,並對數據進行過濾、分析、格式化等,然後存儲到指定的位置。
  • Elasticsearch 負責數據處理,它是一個開源分佈式搜索和分析引擎,具有可伸縮、高可靠和易管理等特點,基於 Apache Lucene 構建,能對大容量的數據進行接近實時的存儲、搜索和分析操作,通常被用作基礎搜索引擎。
  • Kibana 負責數據展示,也是一個開源和免費的工具,通常和 Elasticsearch 搭配使用,對其中的數據進行搜索、分析並且以圖表的方式展示。

這種架構因為需要在各個服務器上部署 Logstash 來從不同的數據源收集數據,所以比較消耗 CPU 和內存資源,容易造成服務器性能下降,因此後來又在 Elasticsearch、Logstash、Kibana 之外引入了 Beats 作為數據收集器。相比於 Logstash,Beats 所佔系統的 CPU 和內存幾乎可以忽略不計,可以安裝在每臺服務器上做輕量型代理,從成百上千或成千上萬臺機器向 Logstash 或者直接向 Elasticsearch 發送數據。

其中,Beats 支持多種數據源,主要包括:

  • Packetbeat,用來收集網絡流量數據。
  • Topbeat,用來收集系統、進程的 CPU 和內存使用情況等數據。
  • Filebeat,用來收集文件數據。
  • Winlogbeat,用來收集 Windows 事件日誌收據。

Beats 將收集到的數據發送到 Logstash,經過 Logstash 解析、過濾後,再將數據發送到 Elasticsearch,最後由 Kibana 展示,架構就變成下面這張圖裡描述的了。

從0開始學微服務:15 如何搭建一個可靠的監控系統?

Graphite

Graphite 的組成主要包括三部分:Carbon、Whisper、Graphite-Web,它的架構可以用下圖來描述。

  • Carbon:主要作用是接收被監控節點的連接,收集各個指標的數據,將這些數據寫入 carbon-cache 並最終持久化到 Whisper 存儲文件中去。
  • Whisper:一個簡單的時序數據庫,主要作用是存儲時間序列數據,可以按照不同的時間粒度來存儲數據,比如 1 分鐘 1 個點、5 分鐘 1 個點、15 分鐘 1 個點三個精度來存儲監控數據。
  • Graphite-Web:一個 Web App,其主要功能繪製報表與展示,即數據展示。為了保證 Graphite-Web 能及時繪製出圖形,Carbon 在將數據寫入 Whisper 存儲的同時,會在 carbon-cache 中同時寫入一份數據,Graphite-Web 會先查詢 carbon-cache,如果沒有再查詢 Whisper 存儲。
從0開始學微服務:15 如何搭建一個可靠的監控系統?

也就是說 Carbon 負責數據處理,Whisper 負責數據存儲,Graphite-Web 負責數據展示,可見 Graphite 自身並不包含數據採集組件,但可以接入StatsD等開源數據採集組件來採集數據,再傳送給 Carbon。

其中 Carbon 對寫入的數據格式有一定的要求,比如:

servers.www01.cpuUsage 42 1286269200
products.snake-oil.salesPerMinute 123 1286269200
[one minute passes]
servers.www01.cpuUsageUser 44 1286269260
products.snake-oil.salesPerMinute 119 1286269260

其中“servers.www01.cpuUsage 42 1286269200”是“key” + 空格分隔符 + “value + 時間戳”的數據格式,“servers.www01.cpuUsage”是以“.”分割的 key,代表具體的路徑信息,“42”是具體的值,“1286269200”是當前的 Unix 時間戳。

Graphite-Web 對外提供了 HTTP API 可以查詢某個 key 的數據以繪圖展示,查詢方式如下。

http://graphite.example.com/render?target=servers.www01.cpuUsage&
width=500&height=300&from=-24h

這個 HTTP 請求意思是查詢 key“servers.www01.cpuUsage”在過去 24 小時的數據,並且要求返回 500*300 大小的數據圖。

除此之外,Graphite-Web 還支持豐富的函數,比如:

target=sumSeries(products.*.salesPerMinute)

代表了查詢匹配規則“products.*.salesPerMinute”的所有 key 的數據之和。

TICK

TICK 是 Telegraf、InfluxDB、Chronograf、Kapacitor 四個軟件首字母的縮寫,是由 InfluxData 開發的一套開源監控工具棧,因此也叫作 TICK Stack,它的架構可以看用下面這張圖來描述。

從0開始學微服務:15 如何搭建一個可靠的監控系統?

從這張圖可以看出,其中 Telegraf 負責數據收集,InfluxDB 負責數據存儲,Chronograf 負責數據展示,Kapacitor 負責數據告警。

這裡面,InfluxDB 對寫入的數據格式要求如下。

<measurement>[,<tag-key>=<tag-value>...] <field-key>=<field-value>[,<field2-key>=<field2-value>...] [unix-nano-timestamp]
/<field2-value>/<field2-key>/<field-value>/<field-key>/<tag-value>/<tag-key>/<measurement>

下面我用一個具體示例來說明它的格式。

cpu,host=serverA,region=us_west value=0.64 1434067467100293230

其中,“cpu,host=serverA,region=us_west value=0.64 1434067467100293230”代表了 host 為 serverA、region 為 us_west 的服務器 CPU 的值是 0.64,時間戳是 1434067467100293230,時間精確到 nano。

Prometheus

還有一種比較有名的時間序數據庫解決方案 Prometheus,它是一套開源的系統監控報警框架,受 Google 的集群監控系統 Borgmon 啟發,由工作在 SoundCloud 的 Google 前員工在 2012 年創建,後來作為社區開源項目進行開發,並於 2015 年正式發佈,2016 年正式加入 CNCF(Cloud Native Computing Foundation),成為受歡迎程度僅次於 Kubernetes 的項目,它的架構可以用下圖來描述。

從0開始學微服務:15 如何搭建一個可靠的監控系統?

從這張圖可以看出,Prometheus 主要包含下面幾個組件:

  • Prometheus Server:用於拉取 metrics 信息並將數據存儲在時間序列數據庫。
  • Jobs/exporters:用於暴露已有的第三方服務的 metrics 給 Prometheus Server,比如 StatsD、Graphite 等,負責數據收集。
  • Pushgateway:主要用於短期 jobs,由於這類 jobs 存在時間短,可能在 Prometheus Server 來拉取 metrics 信息之前就消失了,所以這類的 jobs 可以直接向 Prometheus Server 推送它們的 metrics 信息。
  • Alertmanager:用於數據報警。
  • Prometheus web UI:負責數據展示。

它的工作流程大致是:

  • Prometheus Server 定期從配置好的 jobs 或者 exporters 中拉取 metrics 信息,或者接收來自 Pushgateway 發過來的 metrics 信息。
  • Prometheus Server 把收集到的 metrics 信息存儲到時間序列數據庫中,並運行已經定義好的 alert.rules,向 Alertmanager 推送警報。
  • Alertmanager 根據配置文件,對接收的警報進行處理,發出告警。
  • 通過 Prometheus web UI 進行可視化展示。

Prometheus 存儲數據也是用的時間序列數據庫,格式如下。

<metric>{<label>=<label>, …}
/<label>/<label>/<metric>

比如下面這段代碼代表了位於集群 cluster 1 上,節點 IP 為 1.1.1.1,端口為 80,訪問路徑為“/a”的 http 請求的總數為 100。

http_requests_total{instance="1.1.1.1:80",job="cluster1",location="/a"} 100

講到這裡,四種監控系統的解決方案都已經介紹完了,接下來我們對比一下這四種方案,看看如何選型。

選型對比

我們從監控系統的四個環節來分別對比。

1. 數據收集

ELK 是通過在每臺服務器上部署 Beats 代理來採集數據;Graphite 本身沒有收據採集組件,需要配合使用開源收據採集組件,比如 StatsD;TICK 使用了 Telegraf 作為數據採集組件;Prometheus 通過 jobs/exporters 組件來獲取 StatsD 等採集過來的 metrics 信息。

2. 數據傳輸

ELK 是 Beats 採集的數據傳輸給 Logstash,經過 Logstash 清洗後再傳輸給 Elasticsearch;Graphite 是通過第三方採集組件採集的數據,傳輸給 Carbon;TICK 是 Telegraf 採集的數據,傳輸給 InfluxDB;而 Prometheus 是 Prometheus Server 隔一段時間定期去從 jobs/exporters 拉取數據。可見前三種都是採用“推數據”的方式,而 Prometheus 是採取拉數據的方式,因此 Prometheus 的解決方案對服務端的侵入最小,不需要在服務端部署數據採集代理。

3. 數據處理

ELK 可以對日誌的任意字段索引,適合多維度的數據查詢,在存儲時間序列數據方面與時間序列數據庫相比會有額外的性能和存儲開銷。除此之外,時間序列數據庫的幾種解決方案都支持多種功能的數據查詢處理,功能也更強大。

Graphite 通過 Graphite-Web 支持正則表達式匹配、sumSeries 求和、alias 給監控項重新命名等函數功能,同時還支持這些功能的組合,比如下面這個表達式的意思是,要查詢所有匹配路徑“stats.open.profile.*.API._comments_flow”的監控項之和,並且把監控項重命名為 Total QPS。

alias(sumSeries(stats.openapi.profile.*.API._comments_flow.total_count,"Total QPS")

InfluxDB 通過類似 SQL 語言的 InfluxQL,能對監控數據進行復雜操作,比如查詢一分鐘 CPU 的使用率,用 InfluxDB 實現的示例是:

SELECT 100 - usage_idel FROM "autogen"."cpu" WHERE time > now() - 1m and "cpu"='cpu0'

Prometheus 通過私有的 PromQL 查詢語言,如果要和上面 InfluxDB 實現同樣的功能,PromQL 語句如下,看起來更加簡潔。

100 - (node_cpu{job="node",mode="idle"}[1m]) 

4. 數據展示

Graphite、TICK 和 Prometheus 自帶的展示功能都比較弱,界面也不好看,不過好在它們都支持Grafana來做數據展示。Grafana 是一個開源的儀表盤工具,它支持多種數據源比如 Graphite、InfluxDB、Prometheus 以及 Elasticsearch 等。ELK 採用了 Kibana 做數據展示,Kibana 包含的數據展示功能比較強大,但只支持 Elasticsearch,而且界面展示 UI 效果不如 Grafana 美觀。

總結

以上幾種監控系統實現方式,所採用的技術均為開源的,其中:

  • ELK 的技術棧比較成熟,應用範圍也比較廣,除了可用作監控系統外,還可以用作日誌查詢和分析。
  • Graphite 是基於時間序列數據庫存儲的監控系統,並且提供了功能強大的各種聚合函數比如 sum、average、top5 等可用於監控分析,而且對外提供了 API 也可以接入其他圖形化監控系統如 Grafana。
  • TICK 的核心在於其時間序列數據庫 InfluxDB 的存儲功能強大,且支持類似 SQL 語言的複雜數據處理操作。
  • Prometheus 的獨特之處在於它採用了拉數據的方式,對業務影響較小,同時也採用了時間序列數據庫存儲,而且支持獨有的 PromQL 查詢語言,功能強大而且簡潔。

從對實時性要求角度考慮,時間序列數據庫的實時性要好於 ELK,通常可以做到 10s 級別內的延遲,如果對實時性敏感的話,建議選擇時間序列數據庫解決方案。

從使用的靈活性角度考慮,幾種時間序列數據庫的監控處理功能都要比 ELK 更加豐富,使用更靈活也更現代化。

所以如果要搭建一套新的監控系統,我建議可以考慮採用 Graphite、TICK 或者 Prometheus 其中之一。不過 Graphite 還需要搭配數據採集系統比如 StatsD 或者 Collectd 使用,而且界面展示建議使用 Grafana 接入 Graphite 的數據源,它的效果要比 Graphite Web 本身提供的界面美觀很多。TICK 提供了完整的監控系統框架,包括從數據採集、數據傳輸、數據處理再到數據展示,不過在數據展示方面同樣也建議用 Grafana 替換掉 TICK 默認的數據展示組件 Chronograf,這樣展示效果更好。Prometheus 因為採用拉數據的方式,所以對業務的侵入性最小,比較適合 Docker 封裝好的雲原生應用,比如 Kubernetes 默認就採用了 Prometheus 作為監控系統。

思考題

通過我今天的講解,你應該知道了 Graphite、TICK 以及 Prometheus 存儲監控數據都採用了時間序列數據庫,它們在存儲和性能上有什麼不同之處嗎?

歡迎你在留言區寫下自己的思考,與我一起討論。


分享到:


相關文章: