開源or自研?騰訊全鏈路日誌監控實踐告訴你
作者介紹
吳樹生
騰訊高階工程師,負責SNG大資料監控平臺建設。近十年監控系統開發經驗,具有構建基於大資料平臺的海量高可用分散式監控系統研發經驗。
背景
全鏈路日誌監控在現在盛行的微服務和分散式環境下,能有效地提高問題定位分析效率,成為開發和運維利器。當前已有開源解決方案和成熟的廠商提供。
比如Twitter的zipkin基於Google的Dapper論文設計開發了分散式跟蹤系統,用於採集各處理節點間的日誌和耗時資訊,幫助使用者排查請求鏈路的異常環節。
在有統一RPC中介軟體框架的業務部門容易接入zipkin。但織雲全鏈路日誌監控平臺(後成全鏈路)面對的實際業務場景更為複雜,全鏈路日誌監控實現遇到更多的挑戰,全鏈路技術選型經歷了從開源元件到自研的變化
當前織雲全鏈路日誌監控平臺已接入空間和視訊雲業務日誌資料。每日資料儲存量10TB,可做到1/10的壓縮比,峰值流量30GB/s。
我們先分享一個案例場景:
2017年8月31日 21:40~21:50 X業務模組指標異常,成功率由99.988%降為97.325%。如下圖所示:
收到成功率異常告警後,在多維監控系統上通過畫像下鑽發現是空間點播業務的iphone客戶端成功率下降,返回碼為-310110004。如下圖:
通過大盤多維資料分析發現異常原因後,因涉及APP問題,還需要進一步分析使用者出現異常的上下文。因而需要查看出現異常的使用者在異常時間點的全鏈路日誌資料。在全鏈路檢視上,可以展示查詢出來符合異常條件的使用者日誌和操作過程。
以上是從面到點的異常分析案例。
使用場景
歸納全鏈路日誌監控的使用場景主要有三大類:
- 一是個例分析,主要有處理使用者投訴和從面到點的異常分析;
- 二是開發除錯,主要用於開發過程中檢視關聯模組的日誌和作為測試提單線索;
- 三是監控告警,主要是從日誌資料中提取維度,統計為多維資料用於異常檢測和原因分析。
遇到的挑戰
在構建織雲全鏈路日誌監控平臺時,織雲監控模組經歷了從傳統監控和質量統計到大資料多維監控平臺的轉型。踩過大資料套件的坑,也遇到過業務場景的挑戰。
- 業務多樣性挑戰
QQ體系內有豐富多樣的業務,例如:手Q、空間、直播、點播、會員等。這些業務產生的不同樣式的日誌格式,並且沒有一致的RPC中介軟體框架。這個背景決定系統需要支援靈活的日誌格式和多種採集方式。
- 海量資料挑戰
同時線上超2億使用者上報的狀態資料,日儲存量超10T,頻寬超過30GB/s。需要穩定和高效的資料處理、高效能和低成本的資料儲存服務。在使用開源元件完成原型開發後,逐漸遇到效能瓶頸和穩定性挑戰,驅使我們通過自研逐漸替換開源元件。
應對挑戰
日誌多樣化
日誌的價值除提供查詢檢索外,還可做統計分析和異常檢測告警。為此我們將日誌資料規範化後分流到多維監控平臺。複用監控平臺已有的能力。
基於前面積累的監控平臺開發經驗,在織雲全鏈路日誌監控平臺設計時取長補短。通過自研日誌儲存平臺解決開源儲存元件遇到的成本、效能和穩定性瓶頸。
織雲全鏈路日誌監控平臺提供了4種資料格式支援,分別是分隔符、正則解析、json格式和api上報:
分隔符、正則解析和json格式用於非侵入式的資料採集,靈活性好。但是服務端的日誌解析效能較低,分隔符的資料解析只能做到4W/s的處理效能。而api方式則能達到10W/s處理效能。對於內部業務,我們推薦採用統一的日誌元件,並嵌入api上報資料。
系統自動容災和擴縮容
對於海量的日誌監控系統設計,為做到,第一步是將模組做無狀態化設計。比如系統的接入模組、解析模組和處理模組,這類無需狀態同步的模組,可單獨部署提供服務。
但對這類無狀態業務模組,需要增加剔除異常鏈路機制。也就是資料處理鏈路中如果中間一個節點異常,則該節點往後的其他節點提供的服務是無效的,需要中斷當前的鏈路。異常鏈路剔除機制有多種,如通過zk的心跳機制剔除。
為避免依賴過多的元件,我們做了一個帶狀態的心跳機制。上游節點A定時向下遊節點B傳送心跳探測請求,時間間隔為6s。B回覆心跳請求時帶上自身的服務可用狀態和鏈路狀態。上游節點A收到B心跳帶上的不可用狀態後,如果A下游無其他可用節點,則A的下游鏈路狀態也置為不可用狀態。心跳狀態依次傳遞,最終自動禁用整條鏈路。有狀態的服務通常是儲存類服務。這類服務通過主備機制做容災。如果同一時間只允許一個master提供服務則可採用zk的選舉機制實現主備切換。
做到系統自動容災和擴縮容的第二步是實現通過路由機制實現名字服務和負載均衡。使用開源元件zookeeper能快速實現名字服務功能。要求在服務端實現註冊邏輯,在客戶端實現路由過載邏輯。
資料通道的容災
我們採用兩種機制:雙寫方式和訊息佇列。
● 對於資料質量要求高的監控資料,採用雙寫方式實現。這種方式要求後端有足夠的資源應對峰值請求。提供的能力是低延時和高效的資料處理能力。
●對於日誌資料採用具備資料容災能力的訊息佇列實現。使用過的選型方案有kafka和rabbitmq+mongodb。
採用訊息佇列能應對高吞吐量的日誌資料,並帶有削峰作用。其副作用是在高峰期資料延時大,不能滿足實時監控告警需求。採用訊息佇列還需要注意規避訊息積壓導致佇列異常問題。
例如使用kafka叢集,如果訊息量累積量超過磁碟容量,會造成整個佇列吞吐量下降,影響資料質量。
我們後來採用rabbitmq+mongodb方案。資料在接入層按1萬條或累積30s形成一個數據塊。將資料庫隨機寫入由多個mongodb例項構成的叢集。將mongodb的ip和key寫入rabbitmq中。後端處理叢集從rabbitmq獲取待消費的資訊後,從對應的mongodb節點讀取資料並刪除。通過定時統計rabbitmq和mongodb的訊息積壓量,如何超過閾值則實施自動清理策略。
查詢
日誌的儲存方案為應對高效和低成本查詢,我們採用自研的方式實現。全鏈路上報的資料按使用者ID或請求ID作為主key進行hash分片。分片後的資料在快取模組累積1min或1M大小,然後寫入檔案伺服器叢集。檔案寫入集群后,將hash值與檔案路徑的對映關係寫入ElasticSearch。
查詢資料提供兩類能力:
第一類是按主key查詢。查詢方式是對待查詢key計算hash值,從ES中檢索出文件路徑後送入查詢模組過濾查詢;
第二類查詢能力是非主key的關鍵字查詢。根據業務場景,提供的查詢策略是查詢到含關鍵字的日誌即可。該策略的出發點是平衡查詢效能,避免檢索全量文字。也就是第一次查詢1000個檔案,如果有查詢結果則停止後續的查詢。如果無查詢結果返回,則遞增查詢2000個檔案,直到查詢10萬個檔案終止。
為滿足多樣的業務場景。我們在資料處理模組抽象了ETL能力,做到外掛化擴充套件和可配置實現。並提供統一的任務管理和叢集管理能力。
總結
全鏈路日誌監控的開發過程有以下經驗可借鑑:
- 使用成熟的開源元件構建初級業務功能;
- 在業務執行過程中,通過修改開源元件或自研提升系統處理能力和穩定性,降低運營成本和提升運維效率;
- 採用無狀態化和路由負載均衡能力實現標準化;
- 抽象提煉功能模型,建立平臺化能力,滿足多樣業務需求。