10.22 從Zabbix到Prometheus,同程藝龍數據庫監控系統的實踐

從Zabbix到Prometheus,同程藝龍數據庫監控系統的實踐

閆曉宇,同程藝龍數據庫技術專家,具有多年互聯網行業DB運維經驗,在遊戲、O2O及電商行業從事過DBA運維工作。2016年加入同程藝龍,目前在團隊負責數據庫架構設計及優化、運維自動化、MySQL監控體系建設、DB私有云平臺設計及開發工作。

一、背景

2017年以前我們運維體系的監控主要還是以Zabbix作為主流的解決方案(目前已經不是Zabbix了,運維團隊基於Open-Falcon定製開發了一套統一的運維監控系統,當然這是後話了)。當時數據庫這部分的監控服務也是使用的監控運維團隊提供的服務。總體來說Zabbix的功能還是非常強大的,而且使用也比較簡單,基本上寫寫腳本就能實現指定應用的監控。

我們在2016年就已經嘗試MySQL的容器化,2017年開始大規模應用。容器化以後MySQL數量大幅度上升,通過平臺化進行管理。原來使用的Zabbix已經無法滿足需求:

  • 監控指標太多,如果都接入到Zabbix,服務器無法承受(當時的服務器資源情況下);

  • 數據庫運維平臺對監控告警的管理需要聯動處理;

  • 數據庫運維平臺上實例增刪時需要監控系統自動發現實例;

  • 有趨勢預測、數據快速統計的需求;

  • 對監控指標畫圖有自定義的需求。

所以我們DB團隊內部想選型一款監控系統來支撐以上需求。

二、技術選型

關於數據庫的監控,我們並不想投入太多人力去維護,畢竟監控系統不是我們的主要工作。所以需要選一款部署簡單、服務器資源佔用低、同時又能

結合告警功能的監控系統。雖然目前開源的監控系統還是有不少的,但是最終評估下來,還是選擇了更輕量化的Prometheus,能夠快速滿足我們數據庫監控的需求。

1、易用性

二進制文件啟動、輕量級server,便於遷移和維護、PromQL計算函數豐富,統計維度廣。

2、高性能

監控數據以時間為維度統計情況較多,時序數據庫更適用於監控數據的存儲,按時間索引性能更高,數百萬監控指標,每秒處理數十萬的數據點。

3、擴展性

Prometheus支持聯邦集群,可以讓多個Prometheus實例產生一個邏輯集群,當單實例Prometheus Server處理的任務量過大時,通過使用功能分區(sharding)+聯邦集群(federation)可以對其進行擴展。

4、易集成性

Prometheus社區還提供了大量第三方實現的監控數據採集支持:JMX, EC2, MySQL, PostgresSQL, SNMP, Consul, Haproxy, Mesos, Bind, CouchDB, Django, Memcached, RabbitMQ, Redis, Rsyslog等等。

5、可視化

自帶了Prometheus UI,通過這個UI可以直接對數據進行查詢。

結合Grafana可以靈活構建精美細緻的監控趨勢圖。

6、強大的聚合語法

內置查詢語言,可以通過PromQL的函數實現對數據的查詢、聚合。同時基於PromQL可以快速定製告警規則。

三、實踐

1、監控的目的

在做監控系統之前,首先我們要明確監控的目的。在總結相關內容的時候,正好在網上看到了CNCF基金會Certified Kubernetes Administrator 鄭雲龍先生基於《SRE: Google運維解密》對監控目的的總結,總結很到位,所以就直接引用過來了。

引用來源:https://www.bookstack.cn/read/prometheus-book/AUTHOR.md

1)長期趨勢分析:通過對監控樣本數據的持續收集和統計,對監控指標進行長期趨勢分析。例如,通過對磁盤空間增長率的判斷,我們可以提前預測在未來什麼時間節點上需要對資源進行擴容。

2)告警:當系統出現或者即將出現故障時,監控系統需要迅速反應並通知管理員,從而能夠對問題進行快速的處理或者提前預防問題的發生,避免出現對業務的影響。

3)故障分析與定位:當問題發生後,需要對問題進行調查和處理。通過對不同監控監控以及歷史數據的分析,能夠找到並解決根源問題。

4)數據可視化:通過可視化儀表盤能夠直接獲取系統的運行狀態、資源使用情況、以及服務運行狀態等直觀的信息。

一個監控系統滿足了以上的這些點,涉及採集、分析、告警、圖形展示,完善覆蓋了監控系統應該具備的功能。下面就將近我們是如何基於Prometheus來打造數據庫監控系統的。

2、我們的監控系統架構簡介

其實我們在16年底開始使用到現在,中間也經歷過幾次架構演進。但是考慮到閱讀體驗,被替代的方案就不在這細說了,我們著重講一下目前的架構設計和使用情況。首先看一下總體的架構。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

我們逐個介紹一下上面架構圖中的內容。

1)Agent

這是我們用golang開發的監控信息採集agent,負責採集監控指標和實例日誌。監控指標包括了該宿主機的相關信息(實例、容器)。因為我們是容器化部署,單機實例數量大概在4-20左右。隨著運維平臺的實例增刪,該宿主機上的實例信息可能會發生變化。所以我們需要agent能夠感知到這個變化,從而決定採集哪些信息。另外採集間隔時間做到了10s,監控顆粒度可以做的更細,防止遺漏掉突發性的監控指標抖動。

2)Pushgateway

這是我們用的官方提供的組件,因為Prometheus是通過pull的方式獲取數據的,如果讓Prometheus Server去每個節點拉數據,那麼監控服務的壓力就會很大,我們是在監控幾千個實例的情況下做到10s的採集間隔(當然採用聯邦集群的模式也可以,但是這樣就要需要部署Prometheus Server。再加上告警相關的東西以後,整個架構會變的比較複雜。)。所以agent採取數據推送至pushgateway,然後由Prometheus Server去pushgateway上面pull數據。這樣在Prometheus Server在寫入性能滿足的情況下,單臺機器就可以承載整個系統的監控數據。考慮到跨機房採集監控數據的問題,我們可以在每個機房都部署pushgateway節點,同時還能緩解單個pushgateway的壓力。

3)Prometheus Server

Prometheus Server去pushgateway上面拉數據的時間間隔設置為10s。多個pushgateway的情況下,就配置多個組即可。為了確保Prometheus Server的高可用,可以再加一個Prometheus Server放到異地容災機房,配置和前面的Prometheus Server一樣。如果監控需要保留時間長的話,也可以配置一個採集間隔時間較大的Prometheus Server,比如5分鐘一次,數據保留1年。

4)Alertmanager

使用Alertmanager前,需要先在Prometheus Server上面定義好告警規則。我們的監控系統因為是給DBA用,所以告警指標類型可以統一管理。但是也會有不同集群或者實例定義的告警閾值是不同的,這裡怎麼實現靈活配置,我後面再講。為了解決Alertmanager單點的問題(高可用見下圖),我們可以配置成3個點,Alertmanager引入了Gossip機制。Gossip機制為多個Alertmanager之間提供了信息傳遞的機制。確保及時在多個Alertmanager分別接收到相同告警信息的情況下,也只有一個告警通知被髮送給Receiver。Alertmanager支持多個類型的配置。自定義模板,比如發送HTML的郵件;告警路由,根據標籤匹配確定如何處理告警;接收人,支持郵件、微信、webhook多種類型告警;inhibit_rules,通過合理配置,可以減少垃圾告警的產生(比如機器宕機,該機器上面所有實例的告警信息就可以忽略掉,防止告警風暴)。我們告警是通過webhook的方式,將觸發的告警推送至指定API,然後通過這個接口的服務進行二次加工。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

Prometheus和Alertmanager的高可用

5)filter&rewrite模塊

這個模塊的功能就是實現MySQL集群告警規則過濾功能和告警內容改寫。

先說一下告警規則過濾,因為上面提到是統一設置了告警規則,那麼如果有DBA需要對個別集群的告警閾值調整的話就會很麻煩,為了解決這個問題,我們在Alertmanager後面做了filter模塊,這個模塊接收到告警內容後,會判斷這條告警信息是否超過DBA針對集群或者實例(實例優先級高於集群)設置閾值範圍,如果超過就觸發發送動作。告警發送按照等級不同,發送方式不同。比如我們定義了三個等級,P0、P1、P2,依次由高到低。P0,任何時間都會觸發,並且同時觸發電話和

微信告警;P1,8:00-23:00只發微信告警,其他時間觸發連續三次才觸發發送;P2,8:00-23:00發送微信告警,其他時間發送不發送。

下圖是集群和實例的告警閾值管理頁面(這是集成在數據庫運維平臺內部的一個功能),針對每個集群和實例可以獨立管理,新建集群的時候會根據所選CPU內存配置,默認給出一組與配置對應的告警閾值。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

集群告警規則管理入口

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

實例告警規則管理入口

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

告警規則管理

接著看一下告警內容rewrite,比如上圖看到的額外接收人,除了DBA有些開發同學也想接收告警,但是如果給他們發一個Thread_running大於多少的告警,他們可能不明白是什麼意思,或者什麼情況下會出現這個告警,需要關注什麼。所有我們需要做一下告警內容的重寫,讓開發也能看的明白。下圖就是我們改寫過後的內容。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

告警內容rewrite

還有告警關聯,比如某個宿主機的磁盤IO高了,但是可能需要定位是哪個實例導致的,那麼我們就可以通過這個告警,然後去監控系統裡面分析可能導致IO高的實例,並且管理報警。如圖所示:

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

IO告警關聯實例信息

最後說下一告警收斂,比如宿主機機宕機,那麼這個宿主機上面的MySQL實例都會觸發宕機告警(MySQL實例連續三個指標上報週期沒有數據,則判定會為實例異常),大量的告警會淹沒掉重要告警,所以需要做一下告警收斂。我們是這樣做的,宕機後由宿主機的告警信息來帶出實例的相關信息,一條告警就能看到所有信息,這樣就能通過一條告警信息的內容,得知哪些集群的實例受影響。如圖所示:

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

宿主機宕機關聯實例

6)Graph(畫圖)

Prometheus完美支持Grafana,我們可以通過PromQL語法結合Grafana,快速實現監控圖的展示。為了和運維平臺關聯,通過url傳參的方式,實現了運維平臺直接打開指定集群和指定實例的監控圖。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

實例監控圖

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

集群監控圖

7)V-DBA

這是一個DBA的自動化程序,可以依賴告警信息實現一些指定操作,這裡舉一個過載保護的例子,我們的過載保護不是一直開啟的,只有當觸發了thread_running告警以後才會關聯過載保護的動作。具體方案見下圖:

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

8)告警管理

在運維平臺上,我們有專門的頁面用於管理告警,在手機端也做了適配,方便DBA隨時都能連接到平臺查看處理告警。從下圖中可以看到當前觸發的告警列表,無顏色標註的標識該告警已經被回覆(屬於維護性告警,回覆以後不發送),有顏色的這個代表未被回覆告警(圖中的這個屬於P2等級告警)。另外可以注意到,這裡的告警內容因為是給DBA看,所以沒有做改寫。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

PC端

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

手機端

基於告警日誌,我們結合ES和Kibana實現了告警數據分析的功能,這種交互式的數據分析展示,能夠幫助DBA輕鬆完成大規模數據庫運維下的日常巡檢,快速定位有問題的集群並及時優化。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

告警分析

3、基於Prometheus的其他實踐

基於Prometheus的方案,我們還做了其他監控告警相關功能擴展。

1)集群評分

由於我們做了告警分級,大部分的告警都是P2等級,也就是白天發送。以此來降低夜間的告警數量,但是這樣一來可能會錯過一些告警,導致問題不能及時暴露,所以就做了集群評分的功能來分析集群健康狀況。並且針對一個月的評分做了趨勢展示,方便DBA能夠快速判斷該集群是否需要優化。如下圖所示:

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

集群評分

點擊詳情,可以進入該集群的詳情頁面。可以查看CPU、內存、磁盤的使用情況(這裡磁盤空間達到了262%,意思是超過配額了)。另外還有QPS、TPS、Thread_running昨日和7日前的同比曲線,用來觀察集群請求量的變化情況。最下面的注意事項還會標出扣分項是哪幾個,分別是哪些實例。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

詳情頁

2)指標預測

針對磁盤空間做了7日內小於200G的預測,因為多實例部署,所以需要針對當前宿主機上的實例進行當前數據大小、日誌大小、日增長趨勢的計算。DBA可以快速定位需要遷移擴容的節點實例。實現方法就是用了Prometheus的predict_linear來實現的(具體用法可以參照官方文檔)。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

磁盤空間預警

4、日誌相關

1)SlowLog

SlowLog管理,我們是通過一套系統來進行收集、分析的,因為要拿到原生日誌,所以就沒有采用pt-query-digest的方式。架構如下:

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

通過agent收集,然後將原始的日誌格式化以後以LPUSH方式寫入redis(由於數據量並不大,所以就沒有用Kafka或者MQ),然後再由slow_log_reader這個程序通過BLPOP的方式讀出,並且處理以後寫入ES。這個步驟主要是實現了SQL指紋提取、分片庫庫名重寫為邏輯庫名的操作。

寫入ES以後就可以用Kibana去查詢數據。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

對接到面向開發的數據庫一站式平臺,業務開發的同學可以查詢自己有權限的數據庫,同時我們也集成了小米開源的SOAR,可以用這個工具來查看SQL的優化建議

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践
从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

通過ES進行聚合,可以給用戶訂閱慢查詢的報表,有選擇性的查看相關庫的TOP慢SQL信息信息,有針對性的鏡像優化。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

2)Processlist,InnoDBStatus數據採集

為了能夠在故障回溯或者故障時查看當時的會話快照和InnoDBStatus,我們在監控agent中內置了這個功能,也是每10秒一次,區別是會判斷當前ThreadRunning是否到達閾值,如果到達才會採集數據,否則不採集。這樣的設定既解決了無用日誌太多的問題,又解決了性能異常時能夠獲取到狀態信息。下圖是日誌採集處理的邏輯,其中日誌處理模塊是和慢查詢處理在一個程序中,會話快照的處理邏輯和慢查詢類似,這裡就不贅述了。

从Zabbix到Prometheus,同程艺龙数据库监控系统的实践

四、總結

監控系統沒有絕對的誰好誰不好,最重要的是適合自己的團隊,能夠合理利用最小的成本解決問題。我們從16年開始使用1.x版本到線下的2.x版本,目前基於Prometheus的監控系統,承載了整個平臺所有實例、宿主機、容器的監控。採集週期10S,Prometheus一分鐘內每秒平均攝取樣本數9-10W。1臺物理機(不包括高可用容災資源)就可以承載當前的流量,並且還有很大的容量空間(CPU\\Memory\\Disk)。如果未來單機無法支撐的情況下,可以擴容成聯邦集群模式。

另外本文中提到的監控系統只是我們運維平臺中的一個模塊,並不是一個獨立的系統,從我們實踐經驗來看,最好是可以集成到運維平臺中去,實現技術棧收斂和系統產品化、平臺化,降低使用的複雜的。

最後說說在監控方面我們未來想做的事情,目前我們監控數據有了,但是告警只是發送了指標的內容,具體的根因還需要DBA分析監控信息。我們計劃在第一階段實現告警指標相關性分析後,可以給出一個綜合多個監控指標得出的結論,幫助DBA快速定位問題;第二階段能夠更加分析結果給出處理建議。最終依賴整個監控體系,降低運維的複雜度,打通運維與業務開發直接的溝通壁壘,提升運維效率和服務質量。


分享到:


相關文章: