本文根據林鋒英老師在〖deeplus直播:大規模資料庫運維的化繁為簡之術〗線上分享演講内容整理而成。(文末有回放的方式,不要錯過)
作者介紹
林鋒英,vivo網際網路進階資料庫研發工程師。
1.背景
近幾年 vivo 資料庫運維規模快速增長,從數量上看增長了幾倍,達到了萬級别的規模,與此同時 DBA 每日需要處理200多條告警。
随着運維規模越大,線上故障也就越多,DBA 對于每個故障的處理時效将會下降,如果沒有強有力的工具能提高故障的排查和修複效率,那麼線上的穩定性就得不到保障。是以我們的想法是,我們固然要不斷提供更加豐富的工具,但無論工具再豐富,都需要人去主動使用,是以更重要的是改變以人為主、工具為輔的運維模式,引入自動化分析和自愈的手段來提升運維效率。
2.實作思路
2.1 短期和長期目标
目标确定後,接下來需要确定目标的實作思路。我們調研了業界的一些解決方案後,發現能力的發展可以總結為以下三個階段:
- 平台化:能夠提供一些資料和統計資訊,運維人員再基于這些資訊來進行運維;
- 智能化:已經能夠提供分析和建議,但是否采納需要運維人員自行判斷;
- 自動化:已經有部分場景可以實作自動恢複,無需人工參與了。
通常平台的發展過程如上所述,但是也需要結合我們自身的情況來決定,因為我們投入的人力較少,不是成團隊地投入這個工作,是以不太可能遵循這麼一個發展政策。是以基于人力投入的情況,我們定下的目标是,短期内我們要做投入産出比最高的工作,以求達到立竿見影的效果,但長期來看,圖中成體系的基礎能力還是需要建設起來。
2.2 尋找切入點
為了短期達到立竿見影的效果,就需要尋找一個切入點。如果我們觀察一個故障的生命周期的話,可以看到故障的生命周期分為故障前、故障中和故障後:
- “故障前”包括故障預防 ;
- “故障中”包括故障發現、故障定位和故障恢複;
- “故障後”包括故障複盤。
那麼從整個故障的生命周期來看的話,按照我們的經驗,DBA 大部分時間都是消耗在故障定位和故障恢複上的,而因為每類故障具有相似的定位路徑,是以比較容易去定義定位規則、沉澱專家經驗。是以我們的想法是将重點放在故障定位和故障恢複這兩個階段上,去提高 DBA 的運維效率,優先找一些投入産出比高的場景去實作故障自愈。
2.3 結合實際情況後的發展思路
結合前面提到的短期目标和長期目标,我們确定下來這麼一個發展思路。
首先我們會重點去實作各類故障場景的自動分析和自愈,這些自動分析和自愈行為是由故障消息驅動的,這也是一個比較直覺的方式,因為 DBA 通常也是收到故障消息後,才去進行故障定位等操作。然後當過程中需要某類基礎能力時,就去重點發展該能力。
這樣我們的短期目标和長期目标就都能兼顧到。
2.4 如何在實作過程中保證資料庫可用性
在實作方案前,需要先思考一個問題,即我們如何在實作過程中保證資料庫的可用性?
之是以把資料庫可用性單獨提出來,是因為故障自愈是自動觸發、自動執行的,而且過程中通常需要去觸達資料庫,比如查詢資料庫的狀态或執行操作,那麼這種自動的操作本身會帶來比較大風險,是以更加需要考慮實作過程中,如何避免對資料庫造成的可用性影響。那麼如何避免可用性影響呢?我們的答案是将每個故障自愈方案上線的流程标準化。
3.具體實作
3.1 故障自愈方案上線流程
下圖是我們以可用性為第一考量的前提下,确定下來的故障自愈方案上線流程。
- ①确定方案:當有一個新的故障自愈場景需要實作時,首先需要把自愈方案确定下來,即确定在這個故障場景中,需要“做什麼、怎麼去做”。這裡有兩種确定方案的方式,可以和 DBA 進行咨詢交流确定方案,也可以通過分析線上案例來确定方案
- ②開發測試:方案确定後進行程式的開發測試,此處不必贅述
- ③線上灰階:開發測試完成後,需進行線上灰階,這裡我們支援針對具體對象進行灰階,比如某個叢集經常發生該類故障,那麼可以指定灰階該集 群。如果沒有具體對象,也可以設定百分比随機灰階。當然如果某些故障場景發生的頻率很低,我們一開始也會進行線上演練,通過線上上模拟故障的方式來進行驗證
- ④全網生效:灰階完成後,開放全網生效
- ⑤演進方案:每個故障自愈方案不是上線後就是最終形态,還需要我們結合使用者回報以及後續案例來不斷進行疊代優化
上述流程的五個步驟中,“确定方案”和“演進方案”是重點,是以下文展開介紹。
3.1.1 确定方案
在實踐中,我們通過和 DBA 咨詢交流以及分析線上案例的方式來确定故障自愈的方案。
- 咨詢交流
這裡介紹下發生磁盤告警時自動清理 MySQL Binlog 的方案,通過和 DBA 咨詢交流的方式,我們确定了該方案。具體方案流程如下圖所示,其實整個方案就重點關注了兩個問題:
第一個問題,如何确定哪些 Binlog 是不可以清理的?答案是未備份的 Binlog 不能清理,因為會影響增量備份;備庫未同步的 Binlog 也不能清理,因為會影響複制同步。
第二個問題,如何保證删除過程中的系統可用性?這裡我們采用分批删除、每次删除睡眠一秒的方式來平滑删除帶來的 IO 壓力。
- 案例分析
有時不是所有方案都能夠通過咨詢交流的方式确定下來,對于根因分析的場景,因為每個運維人員的運維經曆有所差别,如果要把所有可能的情況枚舉出 來,那麼會導緻方案十分冗長,是以一種更好的方法是通過分析線上真實案例來确定方案,這樣産出的方案是最貼合線上情況的,後續也可以不斷結合案例做疊代優化。
這裡介紹下我們如何确定 SQL 類告警根因 SQL 分析方案。為了确定這個方案,我們分析了50個線上案例:首先找出哪些案例是能明顯看出有根因 SQL 的, 再對有根因 SQL 的類别進行細化,最後得到根因 SQL 的判斷步驟。
3.1.2 演進方案
針對某個故障場景的方案通常不是一步到位、直接擁有自動恢複故障的能力的,而是在實踐中不斷演進。我們把方案演進的過程分為下圖三個階段:
那麼為什麼要分階段去演進方案呢?
- 從效率的角度看,能夠先快速上線比較簡單的方案,可以快速地提高運維效率;
- 從可用性的角度看,前一階段是後一階段的基礎,隻有前一階段驗證成熟了,再去不斷演進是比較安全的做法。
以 SQL 故障場景為例來示範方案的演進過程。我們的 SQL 故障場景方案一開始隻是提供資料和統計,然後進一步地通過案例分析的方式,使其可以根據規則嘗試找出導緻告警的根因 SQL,目前正在實作對根因 SQL 的自動優化建議,最終目标是可以具備對問題 SQL 自動優化、自動限流的能力。
3.2 故障自愈流程
基于上述的思路,我們實作了一個故障消息驅動、基于規則的故障自愈流程。
首先我們監聽了故障消息,當自愈系統接收到故障消息時,會根據這個消息類型去規則庫中查找對應的自愈流程,再通過流程編排引擎運作起來。流程中會去調用相關基礎能力,最後生成一個處理結果通知,發送到我們的工作溝通軟體。同時也會将這次流程的運作資訊儲存到分析中心,使用者後續可以在分析中心看到詳細的現場快照、分析結果,還能對這次分析進行評價标注。
下面對流程中的重點元件進行介紹。
3.2.1 故障消息
首先是故障消息,在一開始設計時,我們期望是可以支援接入各種故障消息,比如告警事件、巡檢事件等,但是在實踐中,我們還是優先針對 TOP 告警場景進行開發,因為故障消息中,絕大部分都是告警。而且據我們統計,TOP 5 的告警差不多占了所有告警的一半,優先針對 TOP 告警短期内能取得不錯的效果。
3.2.2 規則庫
規則庫儲存了故障消息類型和自愈流程的綁定關系,自愈系統收到故障消息後,會根據這個消息類型去規則庫中查找對應的自愈流程。這裡我們實作了一個簡單的流程編排功能,我們的想法是,先實作一些原子操作,再去将這些操作組合成一個流程,這樣可以讓操作具有的複用性,也更容易實作新的流程。
比如針對 CPU 告警,我們将 TOP 分析和 SQL 根因分析獨立成兩個原子操作,這樣這兩個操作也能複用在其他流程中。
3.2.3 分析中心
在分析中心,使用者可以看到監控告警詳情、現場快照、分析的結果,還可以通過這裡向我們回報這個告警的原因、如何排查等資訊,幫忙我們去進行疊代優化。這樣自愈流程就不是一個黑盒了,也友善運維人員之間進行協作。
3.3 資料采集和計算
3.3.1 資料采集
故障自愈需要大量的資料支援,我們将資料分為三種類型。
- 監控資料:我們這邊的資料庫種類比較多,每種資料庫都有自己監控采集方式;
- 日志資料:采集流程中 Agent 先會向 Manager 查詢自己需要采集哪些日志,然後以類似 tail 的方式一行一行地采集,再上報給 Manager,最後由 Manager 根據配置的正規表達式解析成結構化資料,寫入 Kafka。這些日志包括慢日志、運作日志、全量日志等;
- 事件資料:我們開發了一個事件系統的 SDK,由各個服務使用這個 SDK,将自己服務的事件上報到事件系統。
3.3.2 資料計算
資料采集後,一些資料需要做計算處理。我們現在對資料做實時計算的場景比較少,下圖是近期的全量 SQL 需求。
首先由 Agent 采集 SQL LOG 檔案,進行批量上報,為了降低 Kafka 的帶寬壓力,上報的時候需要進行壓縮。上報時指定執行個體位址作為 Kafka 分區 Key, 以保證同一個執行個體的資料能寫到同一個 Kafka 分區,是以也就能保證在實時計算端,同一個執行個體的資料會落在同一個處理線程上,這樣就能在接收到資料後,做一個預聚合,降低發往下遊的網絡流量。然後通過逐層聚合的方式,先聚合出每分鐘每個 SQL_ID 的平均執行次數、平均響應時間等名額,再根據SQL_ID 的聚合資料,聚合出每分鐘每個 Table 的平均通路次數名額。最後這份資料将用以支撐 SQL 趨勢、表流量統計、SQL 過載保護等功能。
4.成果和案例
4.1 成果
10+種故障場景分析和自愈能力:
使用6人月覆寫線上70%以上告警:
4.2 案例
這裡介紹一個案例:長時間執行的 SQL 數量達到門檻值後,産生了告警,根據 SQL 根因分析得出,這是因為有一條長時間運作的 SQL 阻塞了其他 SQL,并把分析結果推送到故障處理群。從分析詳情可以看出,這是一個 MDL 鎖等待的經典場景,因為某條 SQL 長時間運作,備份程序執行 FLUSH 時請求 MDL 被阻塞,繼而引發後續 SQL 請求 MDL 阻塞。
5.未來展望
展望未來,仍有許多事項需要逐漸建設完善:
- 建立可觀測、可跟蹤的效果度量機制。目前可觀測的名額隻有告警覆寫率,而對于每次分析的有效性和正确率,現在還無法度量,是以需要建立一套效果度量機制;
- 仍有許多基礎能力需要逐漸建設完善,比如 SQL 優化建議、SQL 限流等功能;
- 基于規則的故障自愈方案容易碰到投入産出比降低、系統能力瓶頸等問題,是以需要借鑒業界方案,逐漸使用 AI 技術,在各個功能場景進行嘗試。