作者介紹
劉鵬飛,2021年4月加入去哪兒網(wǎng)DBA團隊,負責公司的MySQL的管理和運維,以及數(shù)據(jù)庫的自動化平臺開發(fā)。具有多年的數(shù)據(jù)庫管理和優(yōu)化經(jīng)驗。
一、背景
去哪兒網(wǎng)數(shù)據(jù)庫監(jiān)控告警系統(tǒng)前期主要通過 Nagios+NRPE 插件來實現(xiàn)的。NRPE 是 Nagios 的一個功能插件,可以實現(xiàn)監(jiān)控主機的 CPU 負載情況、磁盤使用情況等,通過不同的檢測命令實現(xiàn)獲取不同的監(jiān)控指標數(shù)據(jù)。使用 NRPE,需要被監(jiān)控主機上部署 NRPE 程序,Nagios 上安裝 check_nrpe 插件。具體架構(gòu)如下圖所示。
流程說明:
Nagios 運行 check_nrpe 插件,定時通知 check_nrpe 檢測哪些服務(wù);
check_nrpe 通過 SSL 通道調(diào)用遠端主機上的 NRPE 程序;
NRPE 接收到調(diào)用命令運行相應(yīng)的監(jiān)控腳本,獲取相應(yīng)的監(jiān)控指標數(shù)據(jù);
NRPE 將監(jiān)控指標數(shù)據(jù)返回給 check_nrpe ;
check_nrpe 再將獲取的數(shù)據(jù)返回給 Nagios ;
Nagios根據(jù)獲取的監(jiān)控數(shù)據(jù),將告警信息通過 notification 插件發(fā)送到郵箱,電話等。
這里需要說明一下,熟悉 Nagios 的同學應(yīng)該都清楚, Nagios 其實只是起到調(diào)度的作用。監(jiān)控指標的獲取,監(jiān)控告警級別的判斷,告警通知功能的實現(xiàn)都是通過相應(yīng)的插件來完成的。那么這就帶來了以下問題:
告警閾值不能靈活調(diào)整;
告警級別不能靈活調(diào)整;
告警屏蔽不支持多樣化;
告警屏蔽延遲時間比較長;
告警的差異化支持不友好;
告警信息都從同一個通道中發(fā)送出來,不支持分組發(fā)送,導(dǎo)致無法區(qū)分哪些是重要緊急的告警信息。
DBA若要調(diào)整告警配置都涉及繁瑣和批量的更改監(jiān)控腳本,還有可能涉及重啟 NRPE 。我相信每個人對于這樣的操作都會厭惡至極,甚至會導(dǎo)致很多失誤。
二、改進之路
既然現(xiàn)在的監(jiān)控系統(tǒng)對于 DBA 來說不是很友好,那要如何解決呢?把現(xiàn)在的架構(gòu)整個否定,選擇其他監(jiān)控系統(tǒng),如 zabbix ,OpenFalcon 等?倘若整個架構(gòu)替換就會完美嗎?另外,整個架構(gòu)替換的話,從被監(jiān)控的成千上萬的實例的監(jiān)控獲取到告警發(fā)送整個流程里的所有程序和腳本都要替換,無論從時間成本和人力成本考慮都太高了。那對于上面的問題,到底該怎么解決呢?
并且,通過上面的描述發(fā)現(xiàn),我們遇到的問題,其實是報警效率低的問題,包括配置更改,更快速地發(fā)現(xiàn)需要解決的報警等等,而不是報警不準確,報不出來等問題,所以我們不需要去替換當前的監(jiān)控報警系統(tǒng),或者我們自己再去做一個報警系統(tǒng),并且我們始終認為,我們應(yīng)該做自己擅長的事情,報警系統(tǒng)并不是我們擅長的。
所以我們所考慮的是如果在當前系統(tǒng)基礎(chǔ)之上,解決這些問題。并且盡可能地將我們 DBA 所擅長的融入到這個系統(tǒng)中去。
上面已經(jīng)提及了,Nagios 其實就是起到調(diào)度作用,獲取監(jiān)控數(shù)據(jù)和發(fā)送告警都是通過插件來實現(xiàn)的,那是不是還可以通過插件來解決上面遇見的問題呢?若是給 notification 插件增加一個功能,使之能將監(jiān)控信息寫入到 Kafka 中,然后再增加一個程序?qū)崿F(xiàn)從 Kafka 讀取監(jiān)控信息并進行告警判斷和發(fā)送告警信息的功能,好像就能解決上面的問題了。這里所能體現(xiàn)出來的,就是 DBA 擅長的工作了,比如判斷哪一個報警應(yīng)該是要被快速解決掉的。改進后整個監(jiān)控告警系統(tǒng)如下圖所示:
架構(gòu)改進說明:
整個架構(gòu)從 notification 插件之前均無變化;
notification 插件其實可以不用實現(xiàn)告警發(fā)送的功能了,只需要實現(xiàn)將監(jiān)控信息寫入到對應(yīng)的 Kafka 中;
增加 alarm 程序,alarm 程序?qū)崿F(xiàn)告警閾值的靈活調(diào)整,告警級別的判斷等,以及發(fā)送告警信息;
將告警配置統(tǒng)一標準化并存儲到 MySQL 數(shù)據(jù)庫中,修改配置只需修改對應(yīng)表記錄即可,另外 alarm 程序在處理監(jiān)控信息過程中也會去查詢 MySQL 數(shù)據(jù)庫,找出對應(yīng)的告警模板信息,告警屏蔽時間等;
為了防止 Kafka 消息堆積,以及 alarm 單點故障, alarm 程序可以部署在多臺機器上,實現(xiàn)高可用,如圖二中的示例是將 alarm 程序部署在兩臺主機上,分別為alarm1,alarm2;
所有的 NRPE 配置文件里的告警分級和閾值,可以保持目前不變,或者干脆都改為統(tǒng)一標準,亦或者降低標準,需要報的都報出來。需要修改相應(yīng)配置時,只需要修改下游 MySQL 中的對應(yīng)配置參數(shù)即可;
不緊急的報警,可以不報,只是將他們做個統(tǒng)計分析,然后以報表的方式發(fā)出來,然后自上而下地去解決問題。
alarm 的主要流程包含從 Kafka 獲取監(jiān)控數(shù)據(jù),根據(jù)告警配置判斷告警級別,將告警信息分組發(fā)送。alarm 的具體流程如下圖所示。
1)獲取監(jiān)控信息
alarm 從 Kafka 獲取監(jiān)控信息,監(jiān)控信息主要包含監(jiān)控指標數(shù)據(jù),監(jiān)控獲取時間,主機名,對應(yīng)的模板名稱等信息。
2)告警模板配置
告警模板分為全局配置和自定義配置,其中自定義配置可以實現(xiàn)主機層面的自定義配置和實例層面的自定義配置。這些模板配置信息均保存在數(shù)據(jù)庫中,這樣若要更改某個告警模板的閾值,或者某個主機/實例的告警配置都只需要更改對應(yīng)的表記錄即可。對告警模板的調(diào)整已經(jīng)界面化,操作起來既方便又靈活,不用再批量繁瑣地更改監(jiān)控腳本。
告警模板信息主要包括以下信息:
模板名稱,不同的告警模板對應(yīng)不同的監(jiān)控指標;
是否啟動,可以靈活啟停告警模板,不啟用的情況下,獲取到對應(yīng)的監(jiān)控信息不會在發(fā)送告警;
標識字段、比較方法和正則表達式,這為了識別監(jiān)控數(shù)值,并進行告警級別判斷;
告警值、嚴重值、電話值和夜間電話值是為不同的告警級別設(shè)置的不同閾值,通過和閾值的比較進行不同的告警分級,從而可以差異化選取告警媒介(郵件、QTalk 或者電話),發(fā)送到不同的組別,這樣就便于 DBA 篩選重要緊急的告警;
電話閾值(秒),判定完告警級別,會再次判斷該告警持續(xù)時長,若達不到模板里配置的時長,也不會發(fā)送告警,這樣做是為了防止某些指標瞬時的變化然后又及時恢復(fù)導(dǎo)致的告警。
告警模板,如下圖所示:
3)告警屏蔽和發(fā)送
告警屏蔽十分靈活,可以對某個主機或者某個實例屏蔽,也可以針對某一個監(jiān)控項屏蔽,屏蔽時間范圍也可自行靈活設(shè)置。這樣告警屏蔽就具備了多樣化,DBA 可以根據(jù)實際情況在需要時選擇合適的屏蔽粒度或屏蔽時間進行設(shè)置。由于是直接修改的配置模板,所以前面提到的屏蔽延遲問題也就不存在了。
告警發(fā)送,在判定出告警級別后,會根據(jù)告警級別判斷告警發(fā)送途徑。目前使用的告警媒介有兩種,QTalk(去哪兒網(wǎng)內(nèi)部工具)和電話。其中發(fā)送到 QTalk 里的信息會根據(jù)告警級別(warning,critical,call)發(fā)送到不同群組,實現(xiàn)告警信息分級,便于區(qū)分重要緊急告警信息。
這里要特別說一下 call 級別的告警,call 級別的告警除了會發(fā)送 QTalk 信息外,還會進行語音告警。對于語音功能的實現(xiàn),我們處理的方式是會先將 call 級別的告警再放入 Kafka 對應(yīng)的另一個 topic 里,然后由語音告警系統(tǒng)統(tǒng)一調(diào)度。這樣做是因為整個公司目前使用的是同一套語音系統(tǒng),若是各自直接調(diào)用語音系統(tǒng),容易導(dǎo)致語音系統(tǒng)堵塞。
三、智能化探索
去哪兒網(wǎng)數(shù)據(jù)庫監(jiān)控的智能化目前還處于初級的階段,主要實現(xiàn)了告警管理、慢查詢管理、磁盤空間管理。在告警信息發(fā)送前會加上一個鏈接,通過這個鏈接可以在手機端或者PC端調(diào)用智能化處理程序。
告警管理做到了告警屏蔽/開啟功能,還能根據(jù)實際情況設(shè)置屏蔽時長。也可以選擇屏蔽的粒度,是主機層面還是實例層面,亦或是單一的告警項,十分靈活。對于 DBA 要處理告警或進行實例維護時可以很便捷的管理告警,不用再繁瑣的查找、操作。
需要注意,告警屏蔽的環(huán)節(jié)很關(guān)鍵。我們現(xiàn)在的告警屏蔽僅僅在 alarm 發(fā)送告警這一環(huán)節(jié)將告警過濾掉,而不影響 Nagios 對 check_nrpe 的調(diào)度,也就是不影響監(jiān)控數(shù)據(jù)的獲取,也不會影響告警級別判斷等其他環(huán)節(jié)。這樣就不會造成監(jiān)控數(shù)據(jù)的丟失,帶來的好處就是在以后做告警信息統(tǒng)計分析和多指標聯(lián)合分析時,不會發(fā)生因為數(shù)據(jù)丟失而導(dǎo)致分析失效或者分析結(jié)果誤差較大的情況。
在檢測到監(jiān)控信息里有慢查詢時,會根據(jù)告警信息里包含的實例信息連接到對應(yīng)的實例,查詢出當前實例里執(zhí)行時間最長且未結(jié)束的慢查詢,然后將慢查詢的相關(guān)信息,如連接用戶、執(zhí)行的具體 SQL 等,返回給管理界面,同時生成 kill 操作,這樣 DBA 看到這些信息就能判斷如何處理,是否可以 kill 。避免了 DBA 還要登陸到實例,然后執(zhí)行查詢語句的過程。同時也降低了發(fā)生誤操作的概率。
或許有人會有疑問,不能直接在程序里自動kill嗎?當然可以。但是執(zhí)行多久的慢 SQL 自動 kill ,這個時長標準取多少呢?10s?100s?定義成多少總有不合適的地方。因為有的業(yè)務(wù)線執(zhí)行的 SQL 耗時可能大部分都比較長,如 BI ,數(shù)據(jù)分析;有的業(yè)務(wù)線只有個別 SQL 耗時比較長。反過來想一下,若是能一殺了之,那是不是就能把對應(yīng)的業(yè)務(wù)功能下線呢。
所以這里只是給出了一個處理方式,真正要解決慢 SQL 還要去判斷某一慢 SQL 造成的影響,并將其優(yōu)化掉。目前去哪兒網(wǎng)已經(jīng)制定了一套慢查詢風險指數(shù)模型,可以很好地去界定一個慢查詢是不是真的有風險,或者風險有多大,這樣就可以以上帝視角的方式,來管理所有的慢查詢, 這樣自上而下地去根本性地解決問題,效率和成效會非常高。
當我們發(fā)現(xiàn)磁盤空間剩余率不足時,通常會臨時刪除或者清空一些文件,以便能快速釋放一部分空間。其實在我們做清理文件時基本可以分為兩種情況,一種是能進行批量操作刪除的,如清理數(shù)據(jù)庫 binlog ;另一種就是只能單獨處理,或刪除或置空文件,如 MySQL 的錯誤日志等。所以我們在監(jiān)控到數(shù)據(jù)庫主機磁盤空間告警時,就可以分為兩種情況進行統(tǒng)計和清理操作:
對目錄級別的空間統(tǒng)計,這種目錄里存放的都是同一類的文件,按照一定規(guī)律生成,清理時可以進行批量清理,最明顯的就是存放 MySQL 的 binlog 的目錄;
對文件級別的空間統(tǒng)計,這種文件所在的目錄里面存放的文件沒有規(guī)律性,清理時只能單獨操作刪除,有的只能置空不能刪除,如 MySQL 的慢日志,錯誤日志等。
另外,數(shù)據(jù)庫主機的目錄結(jié)構(gòu)已經(jīng)進行了標準化規(guī)范。所以,我們就能抽象出一個配置模板,將那些可能會出現(xiàn)大文件的目錄配置到模板中,并配置是進行目錄級統(tǒng)計還是進行逐個的文件掃描統(tǒng)計。這樣的直接好處就是能直接掃描確定的目錄,不用再層層遞歸掃描,更不用全盤掃描,代價相對很低,并且更高效。
如圖七展示的樣例 ,收到磁盤告警后,自動化程序根據(jù)配置模板自動收集并上報的磁盤空間使用信息,DBA 在看到報警后就能很快的進行清理磁盤的操作,并判斷出釋放空間的大小,是否需要緊急地進行進一步的操作來解除風險。
四、寫在最后
目前數(shù)據(jù)庫的告警已經(jīng)具備了基本的功能,以及初步的智能化。但是要想盡善盡美,還有很長很長的路需要我們?nèi)ヌ剿鳌?/p>
未來會在下面幾個方面進行深耕:
告警信息的統(tǒng)計分析。通過分析歷史的告警信息,獲取各個告警類型告警頻率和占比;分析出各個實例的告警分布情況,根據(jù)告警情況和監(jiān)控指標對實例做進一步的健康診斷。這樣可以從整體上了解集群實例的狀態(tài),更容易發(fā)現(xiàn)潛在問題。
多指標聯(lián)合分析告警。目前的告警只是根據(jù)某一個指標進行判斷,可能會有誤報或者不準的情況。若將相關(guān)的指標的聯(lián)合分析,更能體現(xiàn)實例的狀況。如現(xiàn)在檢測到 threads_running 達到閾值就會告警,但是實例負載并不高,一切正常,這就是一個無效的告警。有時候 threads_running 比平常高,但沒有達到閾值,結(jié)果實例負載已經(jīng)有較大的波動,有了變慢的現(xiàn)象,這時候又應(yīng)該及時發(fā)出告警。所以有時對于單指標的告警并不能很好的反應(yīng)實例狀況,這時若將 threads_running 和磁盤 IO、cpu、鎖等指標聯(lián)合分析,能更好的發(fā)現(xiàn)問題,反應(yīng)實例狀況。
指標突變檢測。有些時候數(shù)據(jù)庫異常,從簡單的指標數(shù)據(jù)值是無法判斷出問題的,這時就需要檢測一些指標的突變情況,如 QPS/TPS 突變、連接數(shù)突變等。相信很多 DBA 都遇見過,由于應(yīng)用變更,突然發(fā)現(xiàn)數(shù)據(jù)庫連接被打滿了。查看監(jiān)控連接數(shù)并不是瞬時被打滿,也經(jīng)歷了一定時間,這時如果有這種突變檢測能更早的發(fā)現(xiàn)問題。
聯(lián)系客服