隨手記統一監控平臺Focus設計解析

應用監控是多數互聯網公司最重要的基礎設施之一,其意義不僅在於可以幫助開發人員應對分佈式環境下的 Trouble Shooting 和性能管理難題,更是系統可用性的第一步。Focus 是由隨手記研發的統一應用監控平臺,承載了隨手旗下隨手記、卡牛兩款產品數百個服務的應用監控任務。本文將對 Focus 的設計思路和關鍵實現進行剖析。(本文根據 2018 年 10 月張越在 QCon 上海站的演講整理而成,有一定的補充和刪減。)

監控的體系

“監控"是一個寬泛的概念,代表了很大的一塊領域,有很多獨立的系統在其中發揮作用。在介紹具體內容之前,我想先闡述一下通常互聯網公司的監控的體系是什麼樣的。

1

一個完整的監控體系通常至少包含以下三個層次的監控:

  1. 系統層監控:用戶爲基礎運維人員,面向機器視角,關注機器的 CPU、磁盤、IO 等。

  2. 應用層監控:用戶爲開發人員或 DevOps 人員, 面向應用視角,關注應用程序的可用性,不僅要求能夠發現故障,還要提供線上故障原因排查和性能調優。

  3. 業務層監控:用戶爲運營人員,面向業務視角,關注業務的關鍵指標如下單率,轉化率。對可視化有較高要求。

在實際運用中,運營和開發人員都會關注業務指標,如果業務指標異常,則首先 check 應用監控瞭解是否系統原因導致,如不是則可能是外部原因如營銷活動、渠道問題等。開發人員在日常 DevOps 活動中則重度依賴應用監控,任何動作都需要確保對線上的影響是可控的。若發生問題時問題根因指向系統層面,則運維 check 系統監控是否存在系統級問題,如磁盤滿,網絡抖動。

以上就是一個互聯網公司的典型監控體系,本文介紹的 Focus 系統是一個應用層監控系統,專注於爲開發人員提供線上應用的故障排查與性能管理能力。

誕生背景

開源社區在監控體系內各方向上均有成熟的產品貢獻。和大多數公司一樣,隨手記最也選擇基於開源產品來組建應用監控系統,並摸索實踐了 1 年多的時間。直到架構發展到如下階段:

2

在這個階段我們實際搭建了三個子系統作用於日誌、調用鏈和指標的處理,並且通過二次開發的方式對其進行了很多適用性和易用性改造,基本實現了開發人員的常見需求。但我們的問題還沒有解決完,當我們想要更進一步的時候我們遇到的問題是:

  1. 接入和使用橫跨多個系統,無法互聯互通,效率低;

  2. 無法形成統一連貫的排障步驟,信息無法充分利用;

  3. 無法繼續演化和擴展,一些問題和需求需要深度整合開源產品;

  4. 架構太複雜,由十幾個組件拼裝而成,系統很脆弱。團隊維護工作繁重。

因此我們在 2017 年決定使用平臺化手段解決上述問題,開始着手建設統一監控平臺。力求整合資源,統一處理,用一套系統解決應用監控問題。Focus 就是爲滿足上述目的開發的監控平臺,目前承載着“隨手記”、“卡牛”兩個產品近千個核心服務的應用監控任務。

設計理念

監控系統本質是一個採集和分析系統,設計上則要遵循分析指導採集的思路。應用監控的難點就在於不僅要回答“有沒有問題”,還要回答“是什麼原因”。我認爲要回答好這兩個問題,至少需要以下 3 個維度的信息做支持:

  • Transaction 事務 :一個應用系統必然是爲了完成某樣事務存在的,那麼它的事務完成的如何? 例如對請求的響應是否成功,每個環節性能快慢?可以說事務執行情況代表了應用的可用性。

  • Event 事件:應用內部發生了什麼事情? 例如是否有異常發生?是否發生過主從切換?事件溯源爲解決問題提供重要的細節信息。

  • Stats 狀態 :應用內部的狀態如何? 例如當前隊列的長度? 線程池空閒線程數?一共處理了多少數據? 狀態的觀測和預測在發現問題方面非常有用。

Focus 不僅要滿足對這三種監控信息進行的採集和分析,還要利用它們之間的配合來組成一個完善的故障排查邏輯。通過數據來支撐工程師做出判斷,逐步收斂和排除噪聲最終過濾出根因,這是 Focus 系統能夠高效排障的思路。

3

實現方面,平臺化的核心優勢是可以進行多種數據的聯合分析與展現。在出報表上做到原先單一系統做不出的報表,提供更有力的決策數據;在報表的規劃上則可以做完整排查邏輯並銜接成清晰的排查步驟,提升故障排查能力。

4

舉例來說,當用戶接到一個告警,在系統中的操作路徑是:

  1. 檢查依賴拓撲報表,確定依賴和被依賴的服務正常,問題是自身問題;

  2. 跳轉到狀態報表,發現應用平均響應時間異常,劃選異常時間段;

  3. 跳轉到事務分析報表,通過響應排行發現該時間內 A 接口響應時間嚴重變慢;

  4. 在 A 接口慢事務 Top 排行中選中一條具體事務,觀察該事務的瀑布圖,發現是數據庫查詢方法慢;

  5. 跳轉到該處日誌,發現是意料外參數導致的全表查詢。

整個排查過程思路清晰且每個跳轉均提供有力的數據支撐,沒有多餘噪音。該操作邏輯的背後則是多維數據的相互協作。

數據結構和處理設計

Focus 使用以下三種數據結構來承載對事務、事件和狀態的落地:

  • 事務觀測:基於 Google Dapper 理念的 Span 數據結構。 包含耗時和失敗等事務狀態信息,通過 Tracing ID 支持分佈式事務。

  • 事件觀測 :事件日誌,KV 數據結構,可以附加任意多的額外信息。如果是事務內發生的事件則可以通過 Tracing ID 追溯到。

  • 狀態觀測:支持多維度和多值的時間序列數據結構。

在數據處理流程方面,Focus 設計爲一個全量採集系統,但不支持全量數據檢索。我認爲全量數據檢索是導致監控系統臃腫複雜的重要原因。在監控場景中,用戶需要有代表性的數據以支持決策,而不是海量原始數據的直接檢索。因此 Focus 從一開始就放棄了做全量數據存儲的念頭,只保留典型樣本數據即可。這樣的設計還降低了流量敏感性,在 11.11、除夕紅包等大型活動下,業務流量突然增大不會導致系統存儲壓力有明顯的變化。不過 Focus 保留了原數據實時供數能力 (Kafka)。在隨手記內部,額外的分析需求是由單獨的大數據系統負責的。

最終 Focus 的內部數據處理流程設計如下:

5

對目標的把握和清晰的設計思路讓 Focus 面對海量數據流量時可以保持簡單,高效,低成本。

架構設計

6

整體架構設計上,Focus 主要滿足幾個特點:

  1. 簡單。Simple is powerful ,簡潔架構讓問題變的易於處理。系統一共只有 3 個組件,運行時額外依賴 Kafka 和 ElasticSearch 集羣分別作爲數據的 Hub 和 Store。原始數據由採集組件蒐集併發送給 Hub,由 Hub 聚集後按照分區邏輯分發到對應的計算組件做實時處理或異常檢測,處理結果再統一存儲到存儲組件中,最後由控制組件查詢使用。

  2. 高吞吐。監控平臺目前每天處理數百億消息,整個處理過程不能存在瓶頸。數據處理主流程增量運算,能異步的地方都採用異步設計。另外整個架構是可擴展的,服務端以無狀態集羣的方式工作,可以通過投入機器的方式應對更大的流量。

  3. 實時性。監控數據時效性明顯,越實時的消息越富有價值,因此係統應該儘量快的出結果。 Focus 是一個準實時處理系統,數據處理過程可完全不落盤,設計上儘量考慮時間因素,目前大部分告警可在 1 分鐘左右發出。

  4. 高可用和自愈。監控平臺是用來排查故障的,所以自身必須是高可用的且不易受到故障影響的系統。Focus 架構中沒有單點問題,且服務故障時可自動剔除出故障的服務。

  5. 故障容忍。當監控系統出現問題,不能影響業務應用。Focus 存儲被設計爲次要組件,存儲掛掉不影響實時增量統計和告警,服務端全掛掉不影響目標應用。

  6. 部署簡單。Focus 設計爲可以開箱即用,只需要一個簡單的命令就可以啓動並在集羣中發揮作用,不需要複雜的配置和學習。這樣面對多個環境部署時就不那麼痛苦。另外開發時也很容易在本機啓動起來。

  7. 最後整個架構是演化而來的。2015 年的時候我們只做到了 Version 1.0 當中的組件 (編碼爲 1 的組件)。 在後續幾年的演化中逐步形成了現在的架構,系統也由一個 ELK 型的日誌系統演化爲了一個完善的 APM 系統。

服務端設計

7

Focus 服務端本質上是一個流計算系統。而如何化解流計算系統固有的挑戰是主要設計問題。我主要講以下幾個關鍵問題的決策:

  1. 數據狀態問題。分佈式服務的狀態處理是設計中的重點,我們通過簡單的數據分區處理方式,讓同一個維度的數據進入同一個 Partition。這樣計算服務就可以無狀態,無狀態的好處是可以任意擴展,且避免了服務間的通信等一系列困難。但是分區模式會帶來熱點問題,這一塊我們目前通過更細粒度的分區來緩解。

  2. 異構數據處理。Focus 的數據處理要支持 3 種不同的數據結構,即需要 3 套 Pipeline 來處理。 而 Focus 的服務端是同構設計的,這樣的設計更利於運維的簡化,因爲同構服務的集羣可以被抽象爲一個服務去管理。爲了做到這一點,每個實例都會同時運行截然不同的計算任務,會導致算力不均。爲此我們設計了一個算力調度模塊,可以動態或手動調整算力分配。

  3. 故障自愈。流計算也就是實時增量計算,它不像離線計算,Job 出錯了大不了再跑一次。增量運算對可靠性提出了更高的要求。在故障處理設計中,Focus 依賴 Kafka Rebalance 機制來實現故障轉移。當某個實例出現故障,Kafka 會將原本由其負責運算的數據 Rebalance 到另一個正常的實例從而保證消費不會中斷。

  4. 流計算框架選型。在上述約束下,最終我們發現 Kafka Streams 非常適合我們的場景,尤其是 Kafka Streams 作爲一個 Library 而不是 Platform 和我們的設計非常匹配。此外它還幫我們做到了 Exactly-Once 語義,以及提供了基本的如 Window 和回填機制等工具,使得開發 Pipeline 的過程非常愉快,代碼變的非常簡單。

  5. 齊全度。最後關於齊全度的問題,我們的流計算基本機制還是靠 Window。 那麼就存在有的數據早到有的數據晚到的情況,如果數據還沒到齊全,這個 Window 就關閉了推去計算了,就可能漏算從而造成誤告警。 這部分我們目前使用的還是簡單粗暴的等待方案,Window 會等待 3-5 個週期,如果超過這個等待週期還不來,則等同於發生了問題。

存儲設計

由於 Focus 同時處理 3 種異構數據,並且每一種數據結構的吞吐量都非常大。在早期設計中爲了接納這些數據存儲需求,使用了不同的針對性數據庫產品。最多的時候平臺需要依賴 4 種不同的數據庫產品纔可以跑起來。這帶來了很大的存儲方面的複雜性,於是我們開始想辦法着手簡化。

存儲的問題在於:需要用一個數據庫支持三種數據結構的高性能存儲。考察了一圈,我們決定使用 ElasticSearch 作爲低層引擎。理由是 ElasticSearch 可以很好的存儲 Span 和 Log 數據,並擁有勝任海量時間序列存儲和檢索的基礎特性:

  • 高效的倒排索引機制。

  • 列存儲能力,並且可以對列存儲進行壓縮。

  • 強大的聚合能力和非物化視圖的特性,可塑性高。

  • 擴展非常簡單,還支持並行運算。

  • 在合理的優化下,速度很快。

8

依靠 ElasticSearch 的強大可塑性,我們在其上設計了一個裝飾層。 通過裝飾層,ElasticSearch 將作爲低層存儲引擎按需提供以下幾種形態的服務:

  • 先進高效的時間序列數據庫。

  • 專爲 Trace 存儲和檢索設計的鏈路數據庫。

  • 日誌全文檢索庫和存儲庫。

9

以時間序列爲例,上圖爲列舉的一些大塊的優化點,在裝飾服務的針對優化下,最終我們做到了壓縮比 10:1 的時序存儲,單節點~1w 讀和~12w 寫的性能,90% 的聚合查詢都可以在 2 秒內返回結果, 並且支持複雜聚合查詢。 這個結果在我們的場景中相比 InfluxDB 也是毫不遜色的。

客戶端設計

Focus 客戶端會一次性把全部需要的信息採集到,包括 Span、Log、Metric 和一些 Metadata。是一個一站式採集客戶端。

在接入方面提供針對事務、事件、狀態的三套埋點 Low-Level API。開發人員可以按需埋點滿足個性化需求。在 Low-Level API 的基礎上,Focus 提供常見中間件的預埋點包,大多數應用的接入都只需要引包即可,甚至可以不需要配置文件。

在設計上我們讓客戶端儘量的簡單,只做好採集這一件事情就可以了。因此放棄了一些有誘惑力的想法,包括在客戶端進行聚合、配置下達、字節碼修改等。事實證明這樣帶來了很多好處:客戶端更不易出錯且設計穩定不易變化。出錯和易變是客戶最不願意接受的;整個客戶端的邏輯很少且容易理解,在開發跨語言客戶端和用戶自行擴展時都非常的容易;另外性能也很容易做到很高。

在實現上客戶端的整個處理步驟都是異步的,減輕對業務的影響。 優化方面手段主要是針對隊列和序列化的優化、對消費線程喚醒的控制、以及嚴格控制內存和對象的使用,防止因爲監控導致 GC。

10

總結

事實上監控系統內的設計決策遠不止這些,篇幅所限就不全部介紹了。最後我總結了一些在進行監控系統設計時的心得可以供大家參考:

  • Simple is powerful 少就是多。做設計抉擇時,只有一個核心評判標準:哪個方案更簡單。

  • 不要讓客戶端做太多事情。我們曾經維護了一個功能強大而智能化的客戶端,直到不得不下決心重做。Focus 版本越高的客戶端功能反而越少。

  • 考慮全量存儲的必要性。存儲很容易成爲系統的瓶頸,我們嘗試在全量存儲上做優化,後來發現 90% 的信息都沒人看,於是我們轉變了思路。

  • 利用開源工具來實現你不感興趣的部分,只做感興趣的那部分就行了。 Focus 把很多枯燥困難的工作都甩給 Kafka 和 ES 來解決了:) 。

  • 爲目標設計。先了解用戶想看什麼併爲此設計報表,然後爲了實現該報表而反推數據處理和採集設計。錯誤的思路:採集一堆數據再進行數據挖掘最後看看能出什麼報表。

  • 不追求完美。勇於把不完美的東西發佈給用戶用,吐槽是必然的,但有用戶纔有演化的方向。

最後我想說 Focus 仍然在不斷的迭代中,很多設計取捨也和公司規模和具體場景有很大關係,所謂拋磚引玉,歡迎大家和我們交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章