本文根據老師在〖deeplus直播:去哪兒網可觀測性實踐〗線上分享演講内容整理而成。(文末有回放的方式,不要錯過)
肖雙
去哪兒網 基礎架構部技術TL
- 2018年加入去哪兒網,目前負責去哪兒網 CI/CD、監控平台和雲原生相關平台建設。
- 期間負責落地了去哪兒網容器化平台建設,協助業務線大規模應用遷移至容器平台,完成監控系統 Watcher 2.0 的改造更新和根因分析系統落地。對監控告警、CI/CD、DevOps 有深入的了解和實踐經驗。
分享概要
一、以始為終,用故障名額來衡量監控系統的完善度
二、訂單類故障秒級發現
三、複雜故障,如何分鐘級定位原因
四、總結
一、以始為終,用故障名額來衡量監控系統的完善度
早期介紹内部監控系統時,我們會分享存儲量、報警量等一些核心監控名額量。随着監控疊代,我們逐漸産生疑問:這些監控系統名額究竟對業務有多大幫助?
1.故障資料分析
去年,我們對公司的故障資料進行分析,發現:
- 故障平均發現時間在4分鐘左右
- 訂單類故障1分鐘的發現率20%
- 處理時長超過30分鐘的故障比例48%
這些名額仍有很大提升空間,基于以上資料,我們參考MTTR對名額進行優化。
MTTR将故障劃分為發現階段、診斷階段和修複階段三個階段,是以我們可以針對每個階段制定對應工具,來縮短整體的MTTR。
二、訂單類故障秒級發現
我們在去年明确了目标——訂單類故障一定要做到秒級發現。
1.現狀
實作秒級故障發現之前,根據現有監控系統,梳理了秒級監控系統的建設要點:
- 采集使用Graphite協定:名額的采集和格式都是遵循Graphite協定,而建設秒級名額時必須考慮其相容性。
- 存儲IO高,占空間大:之前TSDB采用的Graphite的Carbon+ Whisper,Whipser因為空間預配置設定政策和寫放大問題,會導緻磁盤IO高以及磁盤空間占用過多。
- 分鐘級設計:資料采集、上報、報警等子產品都是分鐘級設計,采集使用Pull模式,定時每分鐘拉取。
2.存儲方案選型
當時對比了兩個TSDB,也就是M3DB和VM(VictoriaMetrics)。
1)M3DB
優點:
- 高壓縮比,高性能
- 可伸縮
- 支援Graphite協定以及部分聚合函數:業務場景中,聚合函數使用頻繁、使用場景複雜
缺點:
- 部署維護複雜
- 社群活躍度低
- 更新疊代慢
2)VictoriaMetrics
優點:
- 高性能,單機讀寫可達千萬級名額
- 每個元件都可以任意伸縮
- 原生支援Graphite協定
- 部署簡單
- 社群活躍度高,更新疊代快
缺點:
- 針對Graphite聚合讀場景下,性能下降嚴重
3.壓測資料
針對VM進行壓測:
壓測後發現,磁盤的使用量較低(40G),整體的性能消耗較低。但使用大量聚合名額或大量聚合函數查詢時,性能下降非常嚴重,甚至逾時。
4.存算分離
基于以上特點,我們對VM做了存算分離。
因為VM的優勢是單名額查詢場景性能非常好,是以我們利用VM做單名額查詢,使用上面的聚合層(CarbonAPI)計算所有的聚合函數。
聚合層(CarbonAPI)的優勢在于,它是無狀态的,可以任意擴充,在此基礎上可添加任何政策、資料監測功能、聚合邏輯、限流和壟斷等能力。
在這套架構下,需要多引入一個中繼資料DB,用以存儲所有名額資訊(哪些名額在VM叢集中的位置)。
使用者查詢時,先查詢CarbonAPI,CarbonAPI從中繼資料DB拿到名額存儲的資訊,再去VM裡拿出對應的資料,在聚合層做聚合計算,最後将資料傳回去。
在聚合層(CarbonAPI),我們還制作了一些定制化的功能。
5.名額采集
存算分離解決了VM的短闆問題,第二個任務是實作名額采集、報警的秒級處理。
1)Client端現狀
原先使用的是自研用戶端,下圖右方是用戶端架構。
在早期實作時,使用Counter.Incr()計算名額自增,它會将資料放到到本地的名額倉庫裡,這個名額倉庫實際在應用程式的用戶端也就是記憶體中。
同時,異步排程器每隔一段時間(可能是分鐘級)生成資料快照,因而Server端拉取快照時,每分鐘拉取的快照是固定的。如果一分鐘内多次拉取,也是固定快照。
這樣處理的好處是Server端異常時,補償拉取的資料也不會變更,資料準确度較高。缺點是排程器固定地每分鐘排程生成資料快照,名額倉庫隻支援分鐘級資料的存儲。
2)Client端改造
名額倉庫方案1:參考Prometheus的模式Client不做快照隻做資料累加或記錄,由Server端在拉取時做預設的增量計算
- 優點:用戶端節省記憶體,無需存儲多份資料
- 缺點:Server端做增量計算,壓力較大;采集架構改動過大,且可能存在資料精度問題
名額倉庫方案2:用戶端多份資料計算和存儲,生成多快照
- 優點:采集架構改動小,沒有資料精度問題, server 壓力小
- 缺點:會多占用一部分記憶體
- 優化:使用Tdigest做資料采樣,記憶體占用量可接受
3)Server端現狀
早期Server端進行名額采集時,使用Python+多程序的模型開發,master節點每分鐘發全量任務給work節點,這是典型的producer worker架構,其優點是worker節點可以随意擴充。
問題:
任務量大時通過MQ派發耗時長:比如每隔十秒派發十幾萬的采集任務,采集任務通過MQ派發到worker再進行消費時,過程時間可能已經超過十秒,這種場景下無法做到高頻采集。。Python做大量聚合計算時,CPU消耗高
4)Server端改造
其實還是master和worker的架構,但拆去了MQ。現在worker變成有狀态的節點,一旦worker啟動,任務被master排程給worker,master通過ETCD檢測到worker挂掉後,就會啟用rebalance,節省了任務配發的過程。
6.最終架構
秒級監控的最終架構核心分為三個部分:資料采集、資料查詢以及報警。
實踐效果層面,幫助業務線将訂單故障發現實踐由三分鐘提升到一分鐘。
三、複雜故障,如何分鐘級定位原因
微服務化後定位難的問題聚焦在:
- 鍊路複雜:相較于單體等架構更複雜
- 依賴複雜:應用依賴的資源多種多樣,依賴的外部資源也越來越多
1.鍊路與名額關聯-精準定位
鍊路部分在内部稱為Qtracer,監控系統叫Qmonitor。
為什麼要關聯這兩部分呢?
我們發現,報警(一般是名額報警)之後,如果應用的QPS很高,會查找到很多trace。由于不确定哪條鍊路與名額有關系,是以反而幹擾快速定位。
比如有三個入口,進來的流量形成了三條trace,它們的代碼路徑可能都不經過這個名額,是以不會報警。或者是隻有一條trace經過這一報警名額,用剩下兩條trace做故障定位就沒有意義。
是以我們将名額放到了Qtracer裡,Qmointor在調用名額計數時,會檢查目前是否有trace環境。如果有trace或者span,就将目前這個名額放進span。
如果名額發生告警,就能直接根據這個名額關聯到真正經過這個名額的流量,再用這些trace定位,效率顯著提高。
告警面闆
右側搜尋出trace後,我們會初步對這個trace上的應用進行異常檢測,比如哪些應用有異常日志、異常告警,應用依賴的資源是否都正常,容器運作環境是否正常等狀況,并将這些 異常展示在面闆,輔助開發定位問題。
2.自身依賴快速排查-應用概覽
将每個應用最核心的名額、狀态以及關注的内容聚合,形成應用概覽。如果應用出現問題,可以在應用概覽中快速浏覽,快速感覺應用是否健康。
應用概覽提供兩點資訊:入口的請求清單和出口的請求清單。
入口請求清單指提供了哪些服務,即别人請求的服務。請求哪些接口、接口平均QPS、異常率、平均響應時長等相關資訊,以及趨勢圖都可以在面闆中檢視。
出口請求清單指你的請用請求了别人接口或下遊服務,你可以在應用概覽中了解目标應用、其平均QPS、請求外部的異常率、響應時長等資訊。
實際應用中,開發看到以上資訊就能夠判斷應用狀态是否正常。
3.自身依賴快速排查-依賴詳情
4.自動分析平台
自動分析平台的運作邏輯是先采集Qtrace,根據trace檢視鍊路異常,然後自動分析平台推薦權重比較高的異常。
以上是自動分析平台簡單的模型圖。
最底層是知識圖譜的挖掘,知識圖譜對自動分析非常重要,應用依賴、運作容器、機房資訊等内容都需要知識圖譜記錄,形成行為的分析基礎。
行為分析出異常資訊,再經過權重體系的評估打分與排序,最終将可能的異常推薦出去。
1)知識圖譜
- 基礎資料:統一的事件中心、日志、trace、監控告警、應用畫像(應用基礎的元配置)等。
- 應用關聯關系建立:服務調用鍊、強弱依賴關系
- 資源關聯關系建立:應用依賴的各個資源關系、實體拓撲感覺 - 感覺運作在容器擴kvm的應用的主控端以及網絡環境
- 異常之間關聯關系建立:通過異常名額能精确快速的找到對應的trace、log等,異常的告警之間的關聯關系挖掘
2)應用分析
3)鍊路分析
QPS高時,即使已經精确關聯,但一分鐘内找到的trace依然很多,是以需要篩選或收斂至
較小範圍。
篩選分類:
- 異常trace篩選:重點關注,首先分類
- T值分類篩選:基于業務入口垂直分類
- 拓撲相似度篩選:比較A入口與B入口trace相似度并篩選
如何定位可能是根因的APPCode?
以報警APPCode為頂點找到聯通子圖。
周遊子圖:
- 在Trace鍊路上标記為異常的AppCode
- 計算報警濃度,報警濃度高于一定門檻值的AppCode
- 目前有L1/L2級别告警的AppCode
- 分析trace鍊路鍊路中各應用調用的接口關系,并檢視接口監控的錯誤率和延時是否正常,不正常的标記為異常AppCode
針對AppCode,進行更細次元的異常探測。
4)剪枝排序-權重體系
權重分為四種:
- 靜态權重:經驗權重,每年或每段時間會根據故障原因進行調整。
- 動态權重:root case權重,根據各個根因的嚴重級别對自己進行更新,避免真正的根因被淹沒。
- 應用權重:代表目前故障中此應用異常所占的權重比,表示此應用影響故障應用的機率大小。
- 強化依賴權重:強弱依賴可以明确表明,A應用的 m1接口依賴B應用的 m2接口是強依賴還是弱依賴,根據此資訊可以确認影響機率。
應用權重計算方式:
收斂Trace,在Trace收斂過程中,計算異常AppCode,對異常AppCode的權重進行累加應用距離,距離告警AppCode越近的App權重越高
如上圖所示,三個trace都是A入口,第一次發現C異常,C的權重會加一;第二次發現C異常,權重繼續累加,由此計算出應用權重。
除此之外,應用權重還受到應用距離的影響。在酒店的業務場景下,我們認為A和B的距離越近,A導緻B異常的可能性就越高,A的權重位越高。
強弱依賴剪枝:
當A 出現告警,B 和C都有 root case異常且B是弱依賴C是強依賴,則傾向認為A的告警由C的異常造成。
5.結果輸出
結果會提示有什麼釋出,root case占比,哪些異常需要重點關注。
6.實踐效果
上圖是我們實際的線上故障場景,比如出現MYSQL線程異常、負載特别高的情況,就會在結果輸出的界面提示出來。
經過以上改動,現在定位慢的故障比例降低20%,根因定位的準确率在70%-80%。
四、總結
- 用故障的MTTR名額來營運、優化、建設我們的監控體系
- 秒級監控主要解決進階别故障發現時長的問題
- 協助故障定位,要在鍊路複雜和依賴複雜的情況下确認應用的依賴元件以及依賴應用的健康狀況,并計算相關異常與此次故障的權重
Q&A
Q1:放在span裡的名額具體是指什麼?資料模型是怎樣的?
A:舉個例子,比如有個接口叫false,需要做QPS的監控,名額就命名為false-QPS。一般請求進入的時候,該名額就會被計數。同時,我們會檢視是否有trace、span,如果有,就将名額名放入span,進一步關聯trace id。通過後期洗數,我們能在ES裡做索引,就能夠通過名額搜尋到trace了。
這個數學模型比較簡單,trace id裡可能有很多span,span可以了解為一個大JSON,将metric放入span,就能實作關聯。
Q2:智能分析使用了哪些技術棧或工具棧?
A:語言層用的是Go,算法包括排程算法、離群檢測、權重等方面。
Q3:怎麼把控名額倉庫中的資料精度?有什麼樣的評判标準?
A:資料精度由用戶端或者SDK控制。比如0秒開始生成快照,生成了0-59秒的快照資料。無論Server端怎麼拉取,新的資料存放在新的倉庫裡,是以資料互不幹擾。
資料精度在不同的業務場景下有不同要求。大部分業務場景下,監控資料丢一兩個,問題不會太大。如果是訂單類場景,丢資料的問題就比較大。
Q4:權重體系中不同權重占比大概是多少?
A:目前沒有使用權重占比,整體類似于評分系統,不同的權重累加評分,最終篩選出評分高的名額。我們可以把權重的區間設定好,它基于自身區間或情況可以自行更新。
Q5:服務的強弱依賴怎麼确定,是事前通過靜态配置嗎?還是在動态運作時根據某個規則判斷?
A:強弱依賴由另外系統提供資料。去哪兒網實行混沌工程,其中一項内容就是強弱依賴治理。我們在業務線進行常态化的強弱依賴治理,并留存這些資料。
Q6:目前告警治理和運維團隊使用哪些線上化工具系統?如何考核應用業務團隊,量化SLA名額績效考核,還是事故統計?
A:量化SLA名額,業界有個最常用的辦法就是使用燃盡圖統計故障。比如團隊定的SRO是四個九,意味着一年隻有50多分鐘的故障時長。
↓連結回看本期直播
https://weixin.qq.com/sph/A4plNbhzq