攜程監控系統 Hickwall 演進之路

大偉,攜程軟件技術專家,關注企業級監控,日誌,可觀測性領域。

一、背景

監控領域有三大塊,分別是 Metrics,Tracing,Logging。這三者作爲 IT 可觀測性數據的三劍客,基本可以滿足各類監控、告警、分析、問題排查等需求。

Logs:我們對於 Logs 是更加寬泛的定義,即記錄事物變化的載體,包括常見的訪問日誌、交易日誌、內核日誌等文本型以及 GPS、音視頻等泛型數據。日誌在調用鏈場景結構化後其實可以轉變爲 Trace,在進行聚合、降採樣操作後會變成 Metrics。

Metrics:是聚合後的數值,相對比較離散,一般有 name、labels、time、values 組成,Metrics 數據量一般很小,相對成本更低,查詢的速度比較快。

Traces:是最標準的調用日誌,除了定義調用的父子關係外(一般通過 TraceID、SpanID、ParentSpanID),一般還會定義操作的服務、方法、屬性、狀態、耗時等詳細信息,通過 Trace 能夠代替一部分 Logs 的功能,通過 Trace 的聚合也能得到每個服務、方法的 Metrics 指標。

近年來,可觀測性這個概念如火如荼,可以看作是對監控的一次大升級。CNCF 也發佈了 OpenTelemetry 標準,旨在提供可觀測性領域的標準化方案。那麼相比傳統的監控告警,監控和可觀測性有啥區別和聯繫呢?個人理解,可觀測性能夠以更加白盒的方式看透整個複雜的系統,幫助我們更好的觀察系統的運行狀況,快速定位和解決問題。

簡單理解,監控和可觀測性的關係。監控告訴我們系統的哪些部分是正常工作的,可觀測性告訴我們那裏爲什麼不工作了。監控側重宏觀,可觀測性包括微觀能力。監控是可觀測性的子集。

圖 1

近些年,隨着攜程集團對線上故障 1-5-10 目標的提出(即第 1 分鐘發現故障,第 5 分鐘定位故障,第 10 分鐘解決故障),對監控系統提出了更高的要求。監控系統最重要的三個特點可以定義爲,系統穩定性,數據及時性,數據精準性,三者缺一不可。

攜程監控系統 Hickwall 是一個企業級的指標監控告警系統,兼容了業界的 Prometheus 監控標準,覆蓋攜程所有的指標監控數據,包括系統層和應用層。主要目標是實現指標數據的採集、接入、存儲、展現,並在此基礎上配置告警和通知,告警治理等,同時爲第三方平臺提供第一手的監控數據和告警事件。

二、遇到的問題

隨着業務不斷膨脹,系統規模的持續擴大,Hickwall 遇到了一些問題:

三、主要的演進

針對上述問題和痛點,Hickwall 過去兩年進行了一些針對性的優化和演進。

3.1 雲原生監控

1)TSDB 升級,經過三次演進,現在是基於 VictoriaMetrics 實現的第四代的 TSDB 解決方案。完全兼容 Prometheus 查詢語法。

2)提供了自研 Beacon 容器監控組件,和 k8s 體系高度集成,不僅支持容器系統指標,JVM 指標,也支持自定義的 PrometheusSDK 埋點接入。

3.2 解決高基數問題

1)產品升級,新增日誌 / 指標預聚合能力,產品開放配置能力,根據一定配置策略,通過將多維原始數據降維,收斂指標維度,聚合輸出預聚合數據,通過這種方式可以縮減指標量級,對後續鏈路的處理都有性能提升。目前系統配置了 166 條聚合規則,生成了 209 個指標。

2)指標治理:監控統計指標維度,應用維度的高基數檢測,對非法寫入進行封禁。非法寫入包括了 tag 的 value 使用了隨機數,字符內容超過 256 個字符,指標名稱使用了中文命名等。

3)容量規劃:做好集羣的自監控,進行妥善的容量規劃,主要是監控 ts 增長數量和 datapoint 數據量,以應對日益增長的指標數據。

4)忽略有問題的 tag:治理平臺能夠按需配置 ignore tag,例如針對 HPA 場景下的應用埋點,忽略 value 容易發生變化的 hostname 和 ip 這兩種 tag(一般不會關心這種維度),可以大大減少基數。

3.3 數據粒度提升

爲了響應集團 1-5-10 目標,核心指標採集上秒級,目前主要涉及的是核心的系統指標,業務訂單指標和部分應用指標,其他非關鍵可以按需自行配置。

3.4 告警中臺接入

自研新一代統一的 pull 告警系統,統一各類老的告警技術方案,目前接入告警規則 10 萬 +,同時對接了告警中心,對用戶提供一站式的告警治理能力。

3.5 解決數據延遲問題

數據延遲問題主要是數據鏈路還依賴了消費 Kafka 來寫入 TSDB。因此我們將核心鏈路改造成最短路徑,從數據網關分發數據直接寫到 TSDB,從根本上解決了延遲問題。

3.6 時序存儲的演進

Hickwall 存儲這塊主要經歷了下面四個階段。

第一階段:ES 存儲,Graphite 查詢語法

第一個版本的架構主要以數據寫 Kafka,消費 Kafka 進 ES 的套路來設計。這個方案的好處:

第一個版本已經初步實現了監控系統的功能,但是在使用過程中同樣暴露了一些問題:

1)ES 存儲導致數據容易堆積

ES 是一個非常穩定的全文索引工具,比較適合日誌,搜索的場景。但是卻不是最好的監控數據的存儲方式,主要是寫入性能不是很好,必須大批量,高等待的方式寫才能達到比較大的量,但是這個比較大的量相對監控數據的場景也略顯不夠。

而且爲了提高寫的性能,還需要犧牲數據的實時性(提高 refresh time 來減少磁盤操作,提高寫入量)。實時性又是一個高質量的監控系統所需要努力提高的。這就是一個矛盾點,雖然當時能夠做到勉強接受,但肯定不是最理想的,當時的數據 latency 需要 30s 以上。

2)數據鏈路過長

監控數據主要是從 Proxy 進來到 Trigger 告警需要依次經過 6 個組件,任何一個組件出現問題,都可能導致告警漏告或誤告。

第二階段:基於 InfluxDB 存儲,打造自研的 Incluster 集羣方案,Graphite 查詢語法

ES 用於時間序列存儲存在不少問題,例如磁盤空間使用大,磁盤 IO 使用多,索引維護複雜,寫入和查詢速度慢等。當時 InfluxDB 是排名第一的時序數據庫,到 2017 年的時候已經比較穩定,所以我們萌生了用 InfluxDB 替換 ES 作爲存儲的方案。但是 InfluxDB 並沒有開源的集羣方案,因此我們自研了 Incluster 集羣方案。

在元數據管理這塊使用了 Raft 來保證一致性和分區容錯性。集羣大致的實現思路是,客戶端通過 Incluster 節點寫入數據,Incluster 按照數據分佈策略將寫入請求轉發到相關的 InfluxDB 節點上,查詢的時候按照數據分佈策略進行數據讀取和合並。在用戶查詢方面,實現了類 Graphite 語法用於配圖,兼容上一代語法,從而可以減少用戶遷移配圖的成本。

第三階段:ClickHouse 列式存儲,SQL 查詢語法

2019 年,我們逐步開始推進應用埋點存儲的統一接入。在這個階段,InfluxDB 在高基數場景下,查詢表現並不是很好,集羣穩定性也受到了較大的挑戰。因此我們調研了當時大火的 ClickHouse,開始接入應用埋點,並且提供 SQL 語法查詢。攜程的機票部門率先接入,在自定義應用埋點場景取得了比較好的效果。

第四階段:基於開源的 VictoriaMetrics TSDB,PromQL 查詢語法

2020 年,隨着雲原生技術的發展,內部對雲監控的需求越來越強烈。因此我們在 2020 年調研並測試了業界開源的 VictoriaMetrics TSDB,這款 TSDB 作爲 Prometheus 的遠端持久存儲解決方案,提供了相較於傳統 TSDB 較好的性能和天然兼容 Prometheus 協議的查詢語法和接口。

這款 TSDB 經過測試在綜合寫入性能和查詢方面表現較好。目前我們內部主要分了三個大集羣,集羣規模已經達百餘臺物理機,成爲攜程統一的 Metrics 存儲方案。

圖 2

3.7 監控可視化的演進

由於內部使用的可視化工具是基於 Grafana 二次開發,伴隨着存儲技術的升級,2020 年我們還進行了一次 Grafana2 版本到 6 版本的全面升級,新版本增加了多種新的數據源,所見即所得的告警能力,更多的圖表類型展現,可視化方面大大提升了用戶體驗。

圖 3

四、平臺現狀

隨着多年的發展,目前平臺指標數據量寫入量峯值在千萬級 / 秒,查詢量數千 qps,接入各類告警規則 10 萬 +,查詢 P99 控制在 1s 內。數據粒度最小支持到 10s 級,時序數據默認保存一年。計算 + 存儲集羣規模達百餘臺物理機,並且主要組件都上了 k8s 平臺。數據統計如圖 4 所示。

圖 4

五、目前架構

從數據流向看,目前總體大致架構如圖 5 所示,可見數據流和告警是走的最短路徑。

1)數據:data->Proxy->TSDB

2)告警:data->Proxy->Trigger

這從根本上規避數據延遲和告警延遲問題。下面會主要介紹 Hickwall 所依賴的幾個核心組件。

圖 5

Collector 組件:

數據採集,提供多種客戶端,包括了 Hickwall SDK(應用埋點),Hickwall agent(機器數據採集),Prometheus SDK,Beacon(容器數據採集)。

Proxy 組件:

提供給 Hickwall SDK,Hickwall agent,Prometheus SDK 的統一支持多協議的數據收集服務,主要是 thrift protocol 和 line protocol。作爲數據接收的統一入口,承擔了流量接入,分發,流量保護,數據統計等功能。Proxy 默認爲每個應用 ID 提供了固定的流量配額,具備了基於指標,應用 ID 的限流能力,目前是基於固定時間窗口進行數據量流控。

告警組件:

提供了 Trigger 流式告警和基於 Bosun 的統一 pull 告警。通過推拉結合的告警引擎解決了大規模閾值告警和複雜同環比告警場景。

DownSample 組件:

數據降採樣,支持可以配置的聚合採樣粒度,節省存儲成本。同時提供數據保存更長的時間。

Piper 組件:

統一的告警通知服務,支持告警通知升級。

Transfer 組件:

負責監控數據分發給第三方系統,供數據分析,容量規則,AI 智能告警等用途。

Grafana 看板服務:

所見即所得的查詢,提供豐富的圖表展現以及監控大盤。

TSDB Cluster:

是最核心的時序存儲集羣,時序類的查詢一般 QPS 都比較高(主要有很多告警規則),通常都是 range 查詢,每次查詢某一個單一的指標 / 時間線,或者一組時間線進行聚合。所以對於這類數據都會有專門的時序引擎來支撐,目前主流的時序引擎基本上都是用類似於 LSM Tree 的思想來實現,以適應高吞吐的寫入和查詢。

ClickHouse Cluster:

ClickHouse 作爲優秀的 OLAP 列式數據庫,早期是我們採用的第三代時序存儲引擎,現在慢慢退居二線,目前現在用來導入一些時序數據和高基數指標數據,提供一些額外的數據分析能力。

Hickwall Portal:

一站式的監控日誌告警治理平臺,目前提供了指標接入,指標查詢,告警配置,通知配置,日誌接入,日誌管理,機器 agent 治理等模塊。

從存儲集羣來看,TSDB Cluster 的架構如下:

1)總體架構分爲三層結構,vminsert 寫入層,vmstorage 存儲層,vmselect 查詢層。這三個組件都可以單獨進行擴展,並運行在大多數合適軟件上。

2)寫入層無狀態,支持多協議的寫入,寫入層支持多協議,包括 InfluxDB,OpenTSDB,Prometheus,Graphite 等。接受程序寫入的數據,通過對 metric+tag 組合進行一致性 hash 寫入到對應的存儲節點,當有存儲節點失聯,會進行數據重路由分發到好的節點上面。重路由的過程中,由於數據分發策略的變化,可能會導致寫入變慢,等待存儲節點倒排索引重建完成,就會恢復寫入速度正常。

3)存儲層有狀態,採用 shared nothing 的結構,每個節點數據不共享,獨立存儲,增加了集羣的可用性,簡化集羣的運維和集羣的擴展。支持多租戶,採用了 ZSTD 壓縮,列式存儲,支持副本配置。

存儲層的基本原理可以理解爲存儲了原始的數據,並且會依據查詢層發來的 time range 和 label filter 進行數據查找並且返回。在存儲層,針對時序數據做了很多存儲優化。存儲層要求配置一個數據保存的時間,俗稱 Retention Period。Retention Period 到期後,會進行倒排索引的清理和重建,cpu 和 io 通常會大幅提升,會影響寫入效率。

從壓縮來看,壓縮能夠很好節省內存和磁盤空間,時序數據的壓縮特徵比較明顯,TSDB Cluster 採用先做時序壓縮,再做通用壓縮的方法。比如,先做 delta-of-delta 計算或者異或計算,然後根據情況做 zig-zag,最後再根據情況做一次 ZSTD 壓縮。據測試統計,在生產環境中,每個數據點(8 字節時間戳 + 8 字節 value 共計 16 字節)壓縮後小於 1 個字節,最高可達 0.4 字節,能提供比 Gorilla 算法更好的壓縮率。

4)查詢層無狀態,支持 PromQL 查詢。

基本原理可以理解爲進行查詢語法解析,從存儲層獲取時序數據並且返回標準的格式,查詢層往往會進行一些查詢 QPS,查詢耗時的限制,以保證後端服務不被拖垮。

TSDB 的部署架構圖如下:

 圖 6

六、未來規劃

隨着可觀測性技術的不斷髮展,僅僅侷限於 Metrics 監控是不行的,我們對未來的展望如下。

1)指標分級

指標管理沒有優先級,希望提供分級管理的模式。

2)雲原生可觀測性的探索

eBPF 指標採集的引入,提升主機端的可觀測性能力。

3)Logging,Metrics,Tracing 的結合。

多套方案交織:可能要使用至少 Metrics、Logging、Tracing3 種方案,維護代價巨大。在這種多套方案組合的場景下,問題排查需要和多套系統打交道,若這些系統歸屬不同的團隊,還需要和多個團隊進行交互才能解決問題,整體的維護和使用代價非常巨大。因此我們希望能夠使用一套系統去解決所有類型可觀測性數據的採集、存儲、分析的功能。

4)兼容業界主流協議,OpenTelemetry 的標準。

OpenTelemetry 旨在提供統一的可觀測性數據收集,未來服務端可以提供兼容 OpenTelemetry 協議的接入,擁抱開源社區,我們在保持關注中。

5)agent 邊緣計算,前置數據聚合。

現在是服務端基於 Flink 做預聚合,希望可以在 agent 端提供一些預聚合能力,比如採集日誌的 agent 能夠聚合 Metrics 輸出。

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/SSTHO9RhKEglpcBLRiyyqw