作者介紹
宋倩倩, 2019年加入去哪兒旅行,目前在國內酒店主站與交易QA團隊,主要承擔的是國內酒店主系統業務的品質保障和效率提升。
梁成琰, 去哪兒旅行資深 devops 開發工程師,目前在基礎架構-基礎平台團隊從事 CICD、可觀測性等相關工作,雲原生 SIG 成員,專註於研發效能提升。
分享概要
背景
整體架構介紹
與分鐘級監控的區別
秒級使用場景
秒級使用
營運推廣成果
後續規劃
一、背景
伴隨著大眾井噴的出遊住宿需求,去哪兒旅行酒店訂單激增。watcher作為公司級的監控系統,承載著越來越重要的故障預警能力。但watcher當前給業務流量提供的數據精度都是分鐘級的,以分鐘級為精度的數據雖然也可以反映業務流量的情況,但對訂單報警來說,其精度是有限的,因為分鐘級的指標數據精度,帶來的必然是分鐘級的故障預警。因此每當故障發生時,故障的發現時間都要比故障開始時間晚幾分鐘。尤其是隨著業務的增長,訂單交易相關的故障還伴隨著使用者的訂單賠付行為。
按照故障"1分鐘發現-5分鐘定位-10分鐘恢復"宗旨,借助自身強大的研發能力和產品化能力,我們實作了訂單監控精度提升到秒級。借助秒級監控預警,我們可以即時掌控瞬息萬變的業務流量波動情況,及時發現業務中存在的問題,及時發現,及時解決,盡可能的減少訂單損失,提升公司品牌信任度。
二、整體架構介紹
1、監控現狀
上圖為watcher業務監控的整體架構圖,從圖中可以看出,整體架構包括四個部份,分別為數據采集、數據查詢、dashboard檢視和報警。
數據采集: 主要負責業務指標數據的收集和儲存,在儲存方面,watcher使用的是時序資料庫Graphite;數據采集使用的是自研的采集器qmonitor,包括server、client、manager三個部份,其中manager為采集配置中心,client負責收集業務側指標數據並上報server,server負責聚合數據並將數據存入時序資料庫。
數據查詢: API層,主要負責查詢指標數據,包括簡單指標查詢和復雜聚合指標查詢。查詢api是在Graphite api的基礎上進行了二次開發,並新增了指標源資訊資料庫,以滿足分集群查詢以及多種復雜條件查詢。
dashboard: 視覺化層,使用者可以透過dashboard進行指標數據檢視、面板配置、報警編輯等操作,基於grafana深度開發。
報警: 報警服務,報警狀態檢測負責對使用者所配報警進行規則判定,若滿足報警條件,則將此報警置為critical或warning狀態;報警通知服務則使用了icinga服務,支持電話、qtalk通知(qtalk為去哪兒旅行自研辦公軟體)、簡訊通知,支持開關報警、downtime等。
以上四個部份,無論是qmonitor、數據儲存、查詢以及報警,數據點都是分鐘維度的,若想支持秒級監控,便涉及到了全鏈路的修改和變更。而在秒級監控計畫啟動之前,基於以上架構,我們對watcher監控平台進行了摸排梳理,在此過程中,我們發現要想支持秒級監控,需要解決以下三方面挑戰:
挑戰一:儲存IO過高和占用空間過大的問題
當前分鐘級監控的時間序列資料庫(TSDB)使用的是Graphite的Carbon和Whisper。由於Whisper的空間預分配策略和寫放大問題,導致了磁盤IO壓力過大,同時也占用了過多的儲存空間。秒級監控帶來的是精度的提升,但也同時會導致儲存和寫入的激增,因此解決監控數據儲存的問題成為了首要任務。
挑戰二:對Graphite協定的相容性問題
目前分鐘級監控的儲存使用的是Graphite,監控數據的采集和查詢協定都是基於Graphite的。為了盡可能在使用秒級監控時讓使用者無感,在構建秒級監控系統時,必須要考慮到對Graphite協定的相容性問題。
挑戰三:需要對整個監控鏈路進行修改以適應秒級監控的挑戰
watcher現有的數據采集、數據儲存和告警系統都是基於分鐘級別設計的。如果要實作秒級監控,就需要對從數據采集到儲存,再到告警的整個鏈路進行大規模的修改。
接下來,我們將會從儲存改造、qmonitor客戶端、伺服端指標采集最佳化等幾個部份進行重點闡述。
2、儲存改造
1) 儲存方案選型
由於當前儲存Graphite不能支持秒級監控更大的並行,因此我們探索了新的儲存方案。在綜合了所有限制條件後,我們在選取儲存方案時重點對M3DB和VictoriaMetrics(以下簡稱「VM」)兩種解決方案進行了評估。選擇它們是因為它們都支持Graphite協定。
方案 | M3DB | VictoriaMetrics |
---|---|---|
優勢 | 1.高壓縮比,高效能 2.可伸縮 3.支持Graphite協定以及部份聚合函式 | 1.高效能,單機讀寫可達千萬級指標 2.每個元件都可以任意伸縮 3.原生支持Graphite協定 4.部署簡單 5.社群活躍度高,更新叠代快 |
劣勢 | 部署維護相對復雜 | 針對Graphite聚合讀場景下,效能會嚴重下降 |
在經過詳細的比較後,我們發現無論是M3DB還是VM,都具有較高的壓縮率和出色的儲存和查詢效能,都能夠滿足我們的需求。而考慮到M3DB的部署和維護相對復雜,而VM的每個元件都可以任意伸縮,部署較為簡單,且社群活躍度也比較高。另一方面,VM在壓力測試後展現出了較高的讀寫效能:單機讀寫可以支持高達1000萬級的指標。因此最終我們選擇了VM作為我們的時序資料庫。
2)VM存在的問題:聚合讀場景下效能下降嚴重
我們在對VM進行壓力測試的過程中,發現其在進行單一指標查詢時,效能表現出色,完全滿足我們的查詢需求。
壓測表現:
伺服器配置: 32核CPU,64GB記憶體,以及3.2TB的SSD儲存。
服務部署: vmstorage、vminsert、vmselec。
設定每分鐘寫入的指標數量1000萬,查詢QPS 2000。
壓測發現,平均響應時間為100ms,寫入一天的數據後,磁盤使用量約為40GB,而主機Load保持在5到6之間。
但是在進行復雜指標查詢時,比如涉及到函式查詢和聚合指標查詢,效能會顯著下降,甚至有時會超時。
3)改造方案:存算分離改造
為了解決這個效能問題,我們進行了一些改造探索。依據上文中的壓測結果,VM在單一指標的查詢上表現優秀,因此我們決定讓VM專註於單一指標的查詢,而 復雜指標的查詢和聚合由CarbonAPI來承擔。 選擇VM並進行儲存和計算分離改造後,成功解決了秒級監控的儲存、查詢和寫入問題。
為什麽是CarbonAPI
CarbonAPI是一套開源工具,不僅支持Graphite協定,還支持Graphite中大部份的聚合計算和聚合指標解析查詢,但它對聚合指標解析查詢的實作並不完整。
由於CarbonAPI是無狀態的,可以任意擴充套件,研發團隊就可以客製化一些功能,如監控處理、數據剪裁等。經過改造後,實作了儲存和計算的分離,以支持非常高的查詢QPS。
做了哪些改造
添加一個指標名後設資料DB,每當一個指標寫入VM時,會將指標名稱和查詢URL等資訊存入後設資料DB。然後,CarbonAPI在解析時,會將帶有多個標簽或函式的指標解析為單一指標,再放入VM進行查詢。這樣做有效地提升了VM的查詢效能。
3、客戶端指標采集最佳化
1)當前架構
上圖所示為watcher當前數據采集架構,若想支持秒級監控,其存在的問題是:指標倉庫和排程器不滿足需求。watcher現有的分鐘級監控主要依賴公司自主研發的SDK來進行數據采集,並未采用諸如開源的Prometheus SDK之類的工具。若想支持秒級監控,我們發現客戶端存在一些問題:
問題一:排程器問題
Counter在完成一個指標計數後,會將指標及其相關數據儲存在原生的Metric倉庫中。排程器會在每分鐘的固定時間從指標倉庫中提取數據,生成一個快照並將其儲存起來。當伺服端需要采集客戶端的數據時,它將提取這個快照,而不是直接從倉庫中獲取即時數據。這種做法與開源社群的實踐有所不同。我們 選擇使用快照而非即時數據, 主要是為了按分鐘級別對齊數據,以便於伺服端的處理。無論何時,無論伺服端進行幾次數據拉取,獲取的都是同樣的前一分鐘的數據,且這些數據是固定的,不會再發生改變。
問題二:指標倉庫問題
指標倉庫只支持分鐘級的數據儲存,這是因為我們之前的設計都是基於分鐘級別的。
2)解決方案:客戶端進行多份數據計算和儲存,生成多個快照
①方案選型
在對客戶端進行改造的過程中,我們設計了兩種方案。
方案一: 參考了Prometheus的模式,即不生成快照,而是直接獲取倉庫的即時數據,僅進行數據累加或記錄。當客戶端拉取數據時,可以選擇將原始數據存入TSDB,或自行進行增量計算。
優點: 客戶端節省記憶體。
缺點:
如果客戶端自行進行增量計算,它需要獲取前一分鐘或者前一段拉取間隔的數據,然後才能進行增量計算。如果直接將原始數據存入TSDB,每次使用者檢視數據時,需要自行進行增量計算,這將影響使用者體驗。
盡管這種模式可以節省客戶端記憶體,但它將引發我們的采集架構發生巨大變化,並可能存在數據精度問題。
方案二: 仍然依賴客戶端生成快照,但是會進行多份數據計算和儲存,並生成多個快照。
優點: 采集架構改動小,沒有數據精度問題,server壓力小。
缺點: 儲存秒級的數據會占用更多的記憶體。
由上面對比可以看出,方案二相比方案一來說現有采集架構改動小,不會存在數據精度問題,數據聚合計算分布在client端,server壓力小。雖然會占用更多的記憶體,但我們也對這一問題進行了最佳化,對於Counter類的數據,由於它本身就是一個Int或者Float64的數據,其本身占的記憶體就不多。而Timer型別的數據我們采用了Tdigest數據采樣演算法進行資料壓縮,將原本可能有1000個數據點的數據,縮減到100個數據點。透過這樣的最佳化,我們發現對記憶體的占用是可以接受的。
因此,綜合以上考慮,我們最終選擇了方案二。
②改造後的架構
選定方案二後,我們對客戶端進行了改造:
改造一: 引入一個新的計算層,這個計算層實作了兩個功能
功能一: 數據采樣。
功能二: 判斷指標是否需要進行秒級采集。
目前我們只對核心的訂單類和系統的P1級指標進行秒級采集,因為如果對所有指標都進行采集,資源消耗將非常大。在計算時,它會同時計算秒級和分鐘級的數據。
改造二: 排程器的改造,增加了一個快照管理器,用於管理多個快照。
伺服端在拉取數據時,會根據參數選擇拉取不同的快照。配置管理服務則作為伺服端和客戶端互動的介面,可以將秒級的配置即時推播給客戶端。
經過這樣的改造,我們的客戶端現在能夠滿足我們的需求,可以進行秒級的計數。
4、伺服端指標采集最佳化
1)當前架構
當前架構存在問題: 數據斷點和高資源消耗
問題一: 秒級數據采集出現斷點
在我們的原始架構中,我們采用了Master-Worker模式,這是一個相對簡單但功能強大的設計。在這個架構中,Master充當一個全域排程器,定期從資料庫拉取所有任務,並透過訊息佇列將任務分發給各個Worker。這是一個經典的生產者消費者模式,其優勢在於Worker可以輕易地進行擴充套件,因為它們是無狀態的,如果任務過多,可以簡單地增加Worker以滿足需求。
然而,當我們嘗試進行秒級采集時,我們遇到了一些問題。我們有數以十萬計的任務,透過訊息佇列發送任務時,有時需要長達12秒的時間。這與我們的秒級采集需求不符,因為如果任務的發送就需要12秒,而我們的采集間隔只有10秒,那麽 秒級數據采集就會出現斷點。
問題二:高資源消耗
系統是使用Python開發的,使用了多行程/多執行緒的模型。當需要拉取大量的節點數據並進行聚合計算時, CPU的消耗過高 。需要一個合理的解決方案,既能滿足秒級采集的需求,又能有效地管理資源消耗。
2)解決方案:將任務排程的功能轉移到Worker節點
將任務排程的功能轉移到了Worker節點上,盡管使得Worker變成了有狀態的服務,但是如果一個Worker出現故障,Master會監聽到這個變化並將該Worker的任務重新分配給其他節點。
3)改造後架構
該架構仍然可以方便地進行擴充套件,同時我們選擇了 Go + Goroutine 這樣的開發模式,因為它更適合高並行的場景。經過改造後,系統現在可以支持分鐘級和秒級的數據采集。
架構介紹:
①去掉了訊息佇列,依然保持了Master-Worker的模式。
②增加了任務分區的功能到Master節點中。
例如,我們有數以十萬計的任務,透過任務分區,可以清楚地知道有多少個Worker節點,然後將不同的任務分配給不同的Worker,這是透過Etcd進行分區設定實作的。
③Worker節點會監聽etcd的事件,一旦檢測到事件,它就會知道需要執行哪些任務,比如ID為1到1000的任務。
④Worker會獲取這些任務,並將任務緩存到記憶體中,然後開始執行。
5、最終架構
三、與分鐘級監控的區別
相同點 | 區別 |
---|---|
數據記錄方面:都使用sdk,生成快照的形式收集 數據儲存方面:都使用時序資料庫 數據使用方面:都可以透過dashboard檢視 & api拉取 數據采集方式:qmonitor server都采用 http協定,pull 的形式獲取數據 | 分鐘級和秒級監控最大的不同,便是數據點采樣頻率的不同;采樣頻率由分鐘級提升到秒級,頻率是原來的N倍,由此也帶來了效能和儲存空間的挑戰。 數據收集方面:qmonitor sdk 支持的指標聚合頻率不同,一個是分鐘級聚合計算,一個是秒級聚合計算 數據儲存方面:儲存介質不同,分鐘級監控儲存使用whisper,秒級監控使用查詢效能更好、壓縮比更強的Victoria metrics,透過我們的測試,發現查詢效能是whisper的10倍,壓縮比是whisper的8倍 數據使用方面:資料來源不同,秒級監控和分鐘級監控分屬不同資料來源,可以在dashboard面板選擇 數據拉取方式:qmonitor server 拉取頻率不同,分鐘級監控server端每分鐘拉取一次並進行聚合計算,秒級監控按秒級頻率拉取並進行聚合計算 |
四、秒級使用場景
秒級監控的核心目的,是更快的發現核心業務的問題,非核心業務引入秒級監控,一方面會形成報警風暴,造成打擾,另一方面也會造成資源的浪費。因此我們主要監測核心業務與核心指標變化。
五、秒級使用
1、編排秒級面板,明確核心業務監控以及核心套用
在已經明確了秒級監控主要監測核心業務與核心指標變化的前提下,該如何編排秒級面板?
不管是面向整個業務,還是僅面向一個計畫,不同的業務體量差異,都可以根據各自特點梳理出對應的核心監控面板。譬如只關註業務最核心的指標,又或者是業務的關鍵過程指標。單個監控面板上可以包含一個監控指標,也可以包含多個監控指標,透過不同緯度來綜合反應業務/計畫情況。
在避免報警風暴和不必要的資源浪費的同時,提前編排秒級面板,可以依據核心監控指標推匯出受影響的套用範圍,從而評估大概的sdk升級成本,人力投入成本,方便下一步工作的開展。
2、套用sdk版本升級,添加秒級指標白名單
秒級監控的實作涉及到了指標采集sdk的修改,因此若想要使用秒級能力,需要升級對應套用的sdk,而我們借助tc同學配套的元件升級機制,可以實作修改版本、beta測試、灰度驗證到線上全量上線的全流程自動化。
為了方便大家的接入和使用,我們主要做了以下兩點策略:
1)秒級指標采用白名單的方式添加
watcher指標的采集使用的是pull的方式,對於業務類指標,需要開發同學在程式碼裏呼叫打點方法,並在監控平台配置套用拉取的參數包括環境、埠號、路徑等,為了減少開發同學在使用秒級監控時額外增加程式碼修改成本和配置成本,我們使用了白名單機制。具體實作如下圖,新增一個秒級監控metadb,保存指標白名單,並推播到套用sdk,對於配置了白名單的指標,sdk在記錄分鐘級打點的同時,也會記錄秒級的打點,無需改動程式碼和拉去配置,做到了秒級指標的一鍵添加。
2)dashboard新增秒級監控資料來源,並在panel加以區分
我們在watcher新增了秒級資料來源,提供了快速切換資料來源的配套工具,以便於大家快速配置秒級監控面板和報警。並且在watcher的panel維度增加了資料來源標識以區分分鐘級和秒級監控面板。
3、配置秒級報警
1)通知模版
watcher報警通知服務使用的是icinga集群,為了實作報警通知的秒級觸達,我們新增了秒級的通知檢測模版SL1、SL2,兩類模版的檢測頻率和秒級指標數據的采樣頻率保持一致。其中SL1在報警狀態改變後會立即同時電話通知和qtalk通知(qtalk是去哪兒旅行自研辦公協作平台),SL2在報警狀態改變後會立即進行qtalk通知,3分鐘後進行電話通知。業務線同學可以根據報警級別配置不同通知模版。
2)報警規則配置策略
如下圖所示,相同指標在分鐘級和秒級的監控表現,可以直觀的看出,秒級監控指標的數據趨勢更加陡峭。
分鐘級監控指標:
秒級監控指標:
報警規則配置會直接影響秒級報警的準確和有效。在分鐘級報警規則配置方式的基礎上,秒級還要:
①精細化設定報警規則,避免報警未報問題。譬如:觀察指標趨勢,根據實際情況盡可能的細化時間間隔,在流量高峰期間,設定不同時間間隔的報警規則。
為什麽要精細化設定報警規則?
如上如所示,秒級監控指標的數據趨勢更加陡峭,如果參考分鐘級來設定報警規則,流量在高峰期間掉了一個坑,指標累計下降造成的損失,秒級並不能更快地發現並預警。
②區分工作日與周末節假日,避免因流量降低造成的誤報問題
六、營運推廣成果
1、影響力
公司內多業務線推廣落地使用。
2、優勢對比
與分鐘級監控對比,故障發現時長從4分鐘降低到了1分鐘內。
3、營運監測範圍
核心業務指標: 訂單量、交易失敗率、順暢度等;
業務全鏈路: 進訂、下單、支付、確認、取消等;
4、秒級監控經過一段時間的營運,ATP故障1min發現率和預警準確率兩個指標穩步提升
七、後續規劃
采用演算法即時監測趨勢主動發現問題,無論是顯著有別於其他點的異常,還是連續性異常,實作指標異常下降智慧分析檢測,指標跌零智慧分析預警。
作者丨宋倩倩、梁成琰
來源丨公眾號:Qunar技術沙龍(ID:QunarTL)
dbaplus社群歡迎廣大技術人員投稿,投稿信箱: [email protected]