為什么我們放棄Zabbix采用Prometheus?
2017 年以前,我們運(yùn)維體系的監(jiān)控主要還是以 Zabbix 作為主流的解決方案。當(dāng)時(shí)數(shù)據(jù)庫這部分的監(jiān)控服務(wù)也是使用的監(jiān)控運(yùn)維團(tuán)隊(duì)提供的服務(wù)。
圖片來自 Pexels
總體來說,Zabbix 的功能還是非常強(qiáng)大的,而且使用也比較簡(jiǎn)單,基本上寫寫腳本就能實(shí)現(xiàn)指定應(yīng)用的監(jiān)控。
PS:目前已經(jīng)不是 Zabbix 了,運(yùn)維團(tuán)隊(duì)基于 Open-Falcon 定制開發(fā)了一套統(tǒng)一的運(yùn)維監(jiān)控系統(tǒng),當(dāng)然這是后話了。
我們?cè)?2016 年就已經(jīng)嘗試 MySQL 的容器化,2017 年開始大規(guī)模應(yīng)用。容器化以后 MySQL 數(shù)量大幅度上升,通過平臺(tái)化進(jìn)行管理。
原來使用的 Zabbix 已經(jīng)無法滿足需求:
- 監(jiān)控指標(biāo)太多,如果都接入到 Zabbix,服務(wù)器無法承受(當(dāng)時(shí)的服務(wù)器資源情況下)。
- 數(shù)據(jù)庫運(yùn)維平臺(tái)對(duì)監(jiān)控告警的管理需要聯(lián)動(dòng)處理。
- 數(shù)據(jù)庫運(yùn)維平臺(tái)上實(shí)例增刪時(shí)需要監(jiān)控系統(tǒng)自動(dòng)發(fā)現(xiàn)實(shí)例。
- 有趨勢(shì)預(yù)測(cè)、數(shù)據(jù)快速統(tǒng)計(jì)的需求。
- 對(duì)監(jiān)控指標(biāo)畫圖有自定義的需求。
所以我們 DB 團(tuán)隊(duì)內(nèi)部想選型一款監(jiān)控系統(tǒng)來支撐以上需求。
技術(shù)選型
關(guān)于數(shù)據(jù)庫的監(jiān)控,我們并不想投入太多人力去維護(hù),畢竟監(jiān)控系統(tǒng)不是我們的主要工作。
所以需要選一款部署簡(jiǎn)單、服務(wù)器資源占用低、同時(shí)又能結(jié)合告警功能的監(jiān)控系統(tǒng)。
雖然目前開源的監(jiān)控系統(tǒng)還是有不少的,但是最終評(píng)估下來,還是選擇了更輕量化的 Prometheus,能夠快速滿足我們數(shù)據(jù)庫監(jiān)控的需求。
①易用性
二進(jìn)制文件啟動(dòng)、輕量級(jí) Server,便于遷移和維護(hù)、PromQL 計(jì)算函數(shù)豐富,統(tǒng)計(jì)維度廣。
②高性能
監(jiān)控?cái)?shù)據(jù)以時(shí)間為維度統(tǒng)計(jì)情況較多,時(shí)序數(shù)據(jù)庫更適用于監(jiān)控?cái)?shù)據(jù)的存儲(chǔ),按時(shí)間索引性能更高,數(shù)百萬監(jiān)控指標(biāo),每秒處理數(shù)十萬的數(shù)據(jù)點(diǎn)。
③擴(kuò)展性
Prometheus 支持聯(lián)邦集群,可以讓多個(gè) Prometheus 實(shí)例產(chǎn)生一個(gè)邏輯集群,當(dāng)單實(shí)例 Prometheus Server 處理的任務(wù)量過大時(shí),通過使用功能分區(qū)(Sharding)+聯(lián)邦集群(Federation)可以對(duì)其進(jìn)行擴(kuò)展。
④易集成性
Prometheus 社區(qū)還提供了大量第三方實(shí)現(xiàn)的監(jiān)控?cái)?shù)據(jù)采集支持:JMX,EC2,MySQL,PostgresSQL,SNMP,Consul,Haproxy,Mesos,Bind,CouchDB,Django,Memcached,RabbitMQ,Redis,Rsyslog等等。
⑤可視化
自帶了 Prometheus UI,通過這個(gè) UI 可以直接對(duì)數(shù)據(jù)進(jìn)行查詢。結(jié)合 Grafana 可以靈活構(gòu)建精美細(xì)致的監(jiān)控趨勢(shì)圖。
⑥強(qiáng)大的聚合語法
內(nèi)置查詢語言,可以通過 PromQL 的函數(shù)實(shí)現(xiàn)對(duì)數(shù)據(jù)的查詢、聚合。同時(shí)基于 PromQL 可以快速定制告警規(guī)則。
實(shí)踐
監(jiān)控的目的
在做監(jiān)控系統(tǒng)之前,首先我們要明確監(jiān)控的目的。
在總結(jié)相關(guān)內(nèi)容的時(shí)候,正好在網(wǎng)上看到了 CNCF 基金會(huì) Certified Kubernetes Administrator 鄭云龍先生基于《SRE:Google 運(yùn)維解密》對(duì)監(jiān)控目的的總結(jié),總結(jié)很到位,所以就直接引用過來了。
引用來源:
- https://www.bookstack.cn/read/prometheus-book/AUTHOR.md
長(zhǎng)期趨勢(shì)分析:通過對(duì)監(jiān)控樣本數(shù)據(jù)的持續(xù)收集和統(tǒng)計(jì),對(duì)監(jiān)控指標(biāo)進(jìn)行長(zhǎng)期趨勢(shì)分析。
例如,通過對(duì)磁盤空間增長(zhǎng)率的判斷,我們可以提前預(yù)測(cè)在未來什么時(shí)間節(jié)點(diǎn)上需要對(duì)資源進(jìn)行擴(kuò)容。
告警:當(dāng)系統(tǒng)出現(xiàn)或者即將出現(xiàn)故障時(shí),監(jiān)控系統(tǒng)需要迅速反應(yīng)并通知管理員,從而能夠?qū)栴}進(jìn)行快速的處理或者提前預(yù)防問題的發(fā)生,避免出現(xiàn)對(duì)業(yè)務(wù)的影響。
故障分析與定位:當(dāng)問題發(fā)生后,需要對(duì)問題進(jìn)行調(diào)查和處理。通過對(duì)不同監(jiān)控監(jiān)控以及歷史數(shù)據(jù)的分析,能夠找到并解決根源問題。
數(shù)據(jù)可視化:通過可視化儀表盤能夠直接獲取系統(tǒng)的運(yùn)行狀態(tài)、資源使用情況、以及服務(wù)運(yùn)行狀態(tài)等直觀的信息。
一個(gè)監(jiān)控系統(tǒng)滿足了以上的這些點(diǎn),涉及采集、分析、告警、圖形展示,完善覆蓋了監(jiān)控系統(tǒng)應(yīng)該具備的功能。下面就講解我們是如何基于 Prometheus 來打造數(shù)據(jù)庫監(jiān)控系統(tǒng)的。
我們的監(jiān)控系統(tǒng)架構(gòu)簡(jiǎn)介
我們?cè)?2016 年底開始使用到現(xiàn)在,中間也經(jīng)歷過幾次架構(gòu)演進(jìn)。但是考慮到閱讀體驗(yàn),被替代的方案就不在這細(xì)說了,我們著重講一下目前的架構(gòu)設(shè)計(jì)和使用情況。
首先看一下總體的架構(gòu):
我們逐個(gè)介紹一下上面架構(gòu)圖中的內(nèi)容:
①Agent
這是我們用 Golang 開發(fā)的監(jiān)控信息采集 Agent,負(fù)責(zé)采集監(jiān)控指標(biāo)和實(shí)例日志。
監(jiān)控指標(biāo)包括了該宿主機(jī)的相關(guān)信息(實(shí)例、容器)。因?yàn)槲覀兪侨萜骰渴?,單機(jī)實(shí)例數(shù)量大概在 4-20 左右。
隨著運(yùn)維平臺(tái)的實(shí)例增刪,該宿主機(jī)上的實(shí)例信息可能會(huì)發(fā)生變化。所以我們需要 Agent 能夠感知到這個(gè)變化,從而決定采集哪些信息。
另外采集間隔時(shí)間做到了 10s,監(jiān)控顆粒度可以做的更細(xì),防止遺漏掉突發(fā)性的監(jiān)控指標(biāo)抖動(dòng)。
②Pushgateway
這是我們用的官方提供的組件,因?yàn)?Prometheus 是通過 Pull 的方式獲取數(shù)據(jù)的。
如果讓 Prometheus Server 去每個(gè)節(jié)點(diǎn)拉數(shù)據(jù),那么監(jiān)控服務(wù)的壓力就會(huì)很大。
我們是在監(jiān)控幾千個(gè)實(shí)例的情況下做到 10s 的采集間隔(當(dāng)然采用聯(lián)邦集群的模式也可以,但是這樣就需要部署 Prometheus Server。再加上告警相關(guān)的東西以后,整個(gè)架構(gòu)會(huì)變的比較復(fù)雜)。
所以 Agent 采取數(shù)據(jù)推送至 pushgateway,然后由 Prometheus Server 去 pushgateway 上面 Pull 數(shù)據(jù)。
這樣在 Prometheus Server 寫入性能滿足的情況下,單臺(tái)機(jī)器就可以承載整個(gè)系統(tǒng)的監(jiān)控?cái)?shù)據(jù)。
考慮到跨機(jī)房采集監(jiān)控?cái)?shù)據(jù)的問題,我們可以在每個(gè)機(jī)房都部署 pushgateway 節(jié)點(diǎn),同時(shí)還能緩解單個(gè) pushgateway 的壓力。
③Prometheus Server
將 Prometheus Server 去 pushgateway 上面拉數(shù)據(jù)的時(shí)間間隔設(shè)置為 10s。多個(gè) pushgateway 的情況下,就配置多個(gè)組即可。
為了確保 Prometheus Server 的高可用,可以再加一個(gè) Prometheus Server 放到異地容災(zāi)機(jī)房,配置和前面的 Prometheus Server 一樣。
如果監(jiān)控需要保留時(shí)間長(zhǎng)的話,也可以配置一個(gè)采集間隔時(shí)間較大的 Prometheus Server,比如 5 分鐘一次,數(shù)據(jù)保留 1 年。
④Alertmanager
使用 Alertmanager 前,需要先在 Prometheus Server 上面定義好告警規(guī)則。我們的監(jiān)控系統(tǒng)因?yàn)槭墙o DBA 用,所以告警指標(biāo)類型可以統(tǒng)一管理。
但是也會(huì)有不同集群或者實(shí)例定義的告警閾值是不同的,這里怎么實(shí)現(xiàn)靈活配置,我后面再講。
為了解決 Alertmanager 單點(diǎn)的問題(高可用見下圖),我們可以配置成 3 個(gè)點(diǎn),Alertmanager 引入了 Gossip 機(jī)制。
Gossip 機(jī)制為多個(gè) Alertmanager 之間提供了信息傳遞的機(jī)制。確保及時(shí)在多個(gè) Alertmanager 分別接收到相同告警信息的情況下,也只有一個(gè)告警通知被發(fā)送給 Receiver。
Alertmanager 支持多個(gè)類型的配置。自定義模板,比如發(fā)送 HTML 的郵件;告警路由,根據(jù)標(biāo)簽匹配確定如何處理告警;接收人,支持郵件、微信、Webhook 多種類型告警;inhibit_rules,通過合理配置,可以減少垃圾告警的產(chǎn)生(比如機(jī)器宕機(jī),該機(jī)器上面所有實(shí)例的告警信息就可以忽略掉,防止告警風(fēng)暴)。
我們告警是通過 Webhook 的方式,將觸發(fā)的告警推送至指定 API,然后通過這個(gè)接口的服務(wù)進(jìn)行二次加工。
Prometheus 和 Alertmanager 的高可用
⑤Filter&Rewrite模塊
這個(gè)模塊的功能就是實(shí)現(xiàn) MySQL 集群告警規(guī)則過濾功能和告警內(nèi)容改寫。
先說一下告警規(guī)則過濾,因?yàn)樯厦嫣岬绞墙y(tǒng)一設(shè)置了告警規(guī)則,那么如果有 DBA 需要對(duì)個(gè)別集群的告警閾值調(diào)整的話就會(huì)很麻煩,為了解決這個(gè)問題,我們?cè)? Alertmanager 后面做了 Filter 模塊。
這個(gè)模塊接收到告警內(nèi)容后,會(huì)判斷這條告警信息是否超過 DBA 針對(duì)集群或者實(shí)例(實(shí)例優(yōu)先級(jí)高于集群)設(shè)置閾值范圍,如果超過就觸發(fā)發(fā)送動(dòng)作。
告警發(fā)送按照等級(jí)不同,發(fā)送方式不同。比如我們定義了三個(gè)等級(jí),P0、P1、P2,依次由高到低:
- P0,任何時(shí)間都會(huì)觸發(fā),并且同時(shí)觸發(fā)電話和微信告警。
- P1,8:00-23:00 只發(fā)微信告警,其他時(shí)間觸發(fā)連續(xù)三次才觸發(fā)發(fā)送。
- P2,8:00-23:00 發(fā)送微信告警,其他時(shí)間觸發(fā)不發(fā)送。
下圖是集群和實(shí)例的告警閾值管理頁面(這是集成在數(shù)據(jù)庫運(yùn)維平臺(tái)內(nèi)部的一個(gè)功能),針對(duì)每個(gè)集群和實(shí)例可以獨(dú)立管理,新建集群的時(shí)候會(huì)根據(jù)所選 CPU 內(nèi)存配置,默認(rèn)給出一組與配置對(duì)應(yīng)的告警閾值。
集群告警規(guī)則管理入口
實(shí)例告警規(guī)則管理入口
告警規(guī)則管理
接著看一下告警內(nèi)容 Rewrite,比如上圖看到的額外接收人,除了 DBA 有些開發(fā)同學(xué)也想接收告警。
但是如果給他們發(fā)一個(gè) Thread_running 大于多少的告警,他們可能不明白是什么意思,或者什么情況下會(huì)出現(xiàn)這個(gè)告警,需要關(guān)注什么。
所有我們需要做一下告警內(nèi)容的重寫,讓開發(fā)也能看的明白。下圖就是我們改寫過后的內(nèi)容。
告警內(nèi)容 Rewrite
還有告警關(guān)聯(lián),比如某個(gè)宿主機(jī)的磁盤 IO 高了,但是可能需要定位是哪個(gè)實(shí)例導(dǎo)致的,那么我們就可以通過這個(gè)告警,然后去監(jiān)控系統(tǒng)里面分析可能導(dǎo)致 IO 高的實(shí)例,并且管理報(bào)警。
如圖所示:
IO 告警關(guān)聯(lián)實(shí)例信息
最后說一下告警收斂,比如宿主機(jī)宕機(jī),那么這個(gè)宿主機(jī)上面的 MySQL 實(shí)例都會(huì)觸發(fā)宕機(jī)告警(MySQL 實(shí)例連續(xù)三個(gè)指標(biāo)上報(bào)周期沒有數(shù)據(jù),則判定會(huì)為實(shí)例異常),大量的告警會(huì)淹沒掉重要告警,所以需要做一下告警收斂。
我們是這樣做的,宕機(jī)后由宿主機(jī)的告警信息來帶出實(shí)例的相關(guān)信息,一條告警就能看到所有信息,這樣就能通過一條告警信息的內(nèi)容,得知哪些集群的實(shí)例受影響。
如圖所示:
宿主機(jī)宕機(jī)關(guān)聯(lián)實(shí)例
⑥Graph(畫圖)
Prometheus 完美支持 Grafana,我們可以通過 PromQL 語法結(jié)合 Grafana,快速實(shí)現(xiàn)監(jiān)控圖的展示。
為了和運(yùn)維平臺(tái)關(guān)聯(lián),通過 URL 傳參的方式,實(shí)現(xiàn)了運(yùn)維平臺(tái)直接打開指定集群和指定實(shí)例的監(jiān)控圖。
實(shí)例監(jiān)控圖
集群監(jiān)控圖
⑦V-DBA
這是一個(gè) DBA 的自動(dòng)化程序,可以依賴告警信息實(shí)現(xiàn)一些指定操作,這里舉一個(gè)過載保護(hù)的例子,我們的過載保護(hù)不是一直開啟的,只有當(dāng)觸發(fā)了 thread_running 告警以后才會(huì)關(guān)聯(lián)過載保護(hù)的動(dòng)作。
具體方案見下圖:
⑧告警管理
在運(yùn)維平臺(tái)上,我們有專門的頁面用于管理告警,在手機(jī)端也做了適配,方便 DBA 隨時(shí)都能連接到平臺(tái)查看處理告警。
從下圖中可以看到當(dāng)前觸發(fā)的告警列表,無顏色標(biāo)注的標(biāo)識(shí)該告警已經(jīng)被回復(fù)(屬于維護(hù)性告警,回復(fù)以后不發(fā)送),有顏色的這個(gè)代表未被回復(fù)告警(圖中的這個(gè)屬于 P2 等級(jí)告警)。
另外可以注意到,這里的告警內(nèi)容因?yàn)槭墙o DBA 看,所以沒有做改寫。
PC 端
手機(jī)端
基于告警日志,我們結(jié)合 ES 和 Kibana 實(shí)現(xiàn)了告警數(shù)據(jù)分析的功能,這種交互式的數(shù)據(jù)分析展示,能夠幫助 DBA 輕松完成大規(guī)模數(shù)據(jù)庫運(yùn)維下的日常巡檢,快速定位有問題的集群并及時(shí)優(yōu)化。
告警分析
基于 Prometheus 的其他實(shí)踐
基于 Prometheus 的方案,我們還做了其他監(jiān)控告警相關(guān)功能擴(kuò)展。
①集群評(píng)分
由于我們做了告警分級(jí),大部分的告警都是 P2 等級(jí),也就是白天發(fā)送,以此來降低夜間的告警數(shù)量。
但是這樣一來可能會(huì)錯(cuò)過一些告警,導(dǎo)致問題不能及時(shí)暴露,所以就做了集群評(píng)分的功能來分析集群健康狀況。
并且針對(duì)一個(gè)月的評(píng)分做了趨勢(shì)展示,方便 DBA 能夠快速判斷該集群是否需要優(yōu)化。
如下圖所示:
集群評(píng)分
點(diǎn)擊詳情,可以進(jìn)入該集群的詳情頁面??梢圆榭?CPU、內(nèi)存、磁盤的使用情況(這里磁盤空間達(dá)到了 262%,意思是超過配額了)。
另外還有 QPS、TPS、Thread_running 昨日和 7 日前的同比曲線,用來觀察集群請(qǐng)求量的變化情況。最下面的注意事項(xiàng)還會(huì)標(biāo)出扣分項(xiàng)是哪幾個(gè),分別是哪些實(shí)例。
詳情頁
②指標(biāo)預(yù)測(cè)
針對(duì)磁盤空間做了 7 日內(nèi)小于 200G 的預(yù)測(cè),因?yàn)槎鄬?shí)例部署,所以需要針對(duì)當(dāng)前宿主機(jī)上的實(shí)例進(jìn)行當(dāng)前數(shù)據(jù)大小、日志大小、日增長(zhǎng)趨勢(shì)的計(jì)算。
DBA 可以快速定位需要遷移擴(kuò)容的節(jié)點(diǎn)實(shí)例。實(shí)現(xiàn)方法就是用了 Prometheus 的 predict_linear 來實(shí)現(xiàn)的(具體用法可以參照官方文檔)。
磁盤空間預(yù)警
日志相關(guān)
①SlowLog
SlowLog 管理,我們是通過一套系統(tǒng)來進(jìn)行收集、分析的,因?yàn)橐玫皆罩荆跃蜎]有采用 pt-query-digest 的方式。
架構(gòu)如下:
通過 Agent 收集,然后將原始的日志格式化以后以 LPUSH 方式寫入 Redis(由于數(shù)據(jù)量并不大,所以就沒有用 Kafka 或者 MQ),然后再由 slow_log_reader 這個(gè)程序通過 BLPOP 的方式讀出,并且處理以后寫入 ES。
這個(gè)步驟主要是實(shí)現(xiàn)了 SQL 指紋提取、分片庫庫名重寫為邏輯庫名的操作。
寫入 ES 以后就可以用 Kibana 去查詢數(shù)據(jù)。
對(duì)接到面向開發(fā)的數(shù)據(jù)庫一站式平臺(tái),業(yè)務(wù)開發(fā)的同學(xué)可以查詢自己有權(quán)限的數(shù)據(jù)庫,同時(shí)我們也集成了小米開源的 SOAR,可以用這個(gè)工具來查看 SQL 的優(yōu)化建議。
通過 ES 進(jìn)行聚合,可以給用戶訂閱慢查詢的報(bào)表,有選擇性的查看相關(guān)庫的 TOP 慢 SQL 信息信息,有針對(duì)性的鏡像優(yōu)化。
②Processlist,InnoDBStatus 數(shù)據(jù)采集
為了能夠在故障回溯或者故障時(shí)查看當(dāng)時(shí)的會(huì)話快照和 InnoDBStatus,我們?cè)诒O(jiān)控 Agent 中內(nèi)置了這個(gè)功能,也是每 10 秒一次,區(qū)別是會(huì)判斷當(dāng)前 ThreadRunning 是否到達(dá)閾值,如果到達(dá)才會(huì)采集數(shù)據(jù),否則不采集。
這樣的設(shè)定既解決了無用日志太多的問題,又解決了性能異常時(shí)能夠獲取到狀態(tài)信息。
下圖是日志采集處理的邏輯,其中日志處理模塊是和慢查詢處理在一個(gè)程序中,會(huì)話快照的處理邏輯和慢查詢類似,這里就不贅述了。
總結(jié)
監(jiān)控系統(tǒng)沒有絕對(duì)的誰好誰不好,最重要的是適合自己的團(tuán)隊(duì),能夠合理利用最小的成本解決問題。
我們從 2016 年開始使用 1.x 版本到線下的 2.x 版本,目前基于 Prometheus 的監(jiān)控系統(tǒng),承載了整個(gè)平臺(tái)所有實(shí)例、宿主機(jī)、容器的監(jiān)控。
采集周期 10秒,Prometheus 1 分鐘內(nèi)每秒平均攝取樣本數(shù) 9-10W。
1 臺(tái)物理機(jī)(不包括高可用容災(zāi)資源)就可以承載當(dāng)前的流量,并且還有很大的容量空間(CPU\Memory\Disk)。如果未來單機(jī)無法支撐的情況下,可以擴(kuò)容成聯(lián)邦集群模式。
另外本文中提到的監(jiān)控系統(tǒng)只是我們運(yùn)維平臺(tái)中的一個(gè)模塊,并不是一個(gè)獨(dú)立的系統(tǒng),從我們實(shí)踐經(jīng)驗(yàn)來看,最好是可以集成到運(yùn)維平臺(tái)中去,實(shí)現(xiàn)技術(shù)棧收斂和系統(tǒng)產(chǎn)品化、平臺(tái)化,降低使用的復(fù)雜的。
最后說說在監(jiān)控方面我們未來想做的事情,目前我們監(jiān)控?cái)?shù)據(jù)有了,但是告警只是發(fā)送了指標(biāo)的內(nèi)容,具體的根因還需要 DBA 分析監(jiān)控信息。
我們計(jì)劃在第一階段實(shí)現(xiàn)告警指標(biāo)相關(guān)性分析后,可以給出一個(gè)綜合多個(gè)監(jiān)控指標(biāo)得出的結(jié)論,幫助 DBA 快速定位問題;第二階段能夠更加分析結(jié)果給出處理建議。
最終依賴整個(gè)監(jiān)控體系,降低運(yùn)維的復(fù)雜度,打通運(yùn)維與業(yè)務(wù)開發(fā)直接的溝通壁壘,提升運(yùn)維效率和服務(wù)質(zhì)量。
作者:閆曉宇
簡(jiǎn)介:同程藝龍數(shù)據(jù)庫技術(shù)專家,具有多年互聯(lián)網(wǎng)行業(yè) DB 運(yùn)維經(jīng)驗(yàn),在游戲、O2O 及電商行業(yè)從事過 DBA 運(yùn)維工作。2016 年加入同程藝龍,目前在團(tuán)隊(duì)負(fù)責(zé)數(shù)據(jù)庫架構(gòu)設(shè)計(jì)及優(yōu)化、運(yùn)維自動(dòng)化、MySQL 監(jiān)控體系建設(shè)、DB 私有云平臺(tái)設(shè)計(jì)及開發(fā)工作。