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