透過CAT,來看分布式實時監控系統的設計與實現

轉載:透過CAT,開看分布式實時監控系統的設計與實現

2011年底,我加入大眾點評網,出于很偶然的機會,決定開發CAT,為各個業務線打造分布式實時監控系統,CAT的核心概念源自eBay閉源系統CAL----eBay的幾大法寶之一。

在當今互聯網時代,業務需求旺盛,開發團隊往往采用scrum等敏捷開發流程,加班加點快速迭代以滿足業務需求,是常態。采用分布式系統設計和服務化,由多臺機器協作來共同完成用戶請求,是典型的解決方案。網站故障頻發,內部關系錯綜復雜,故障定位緩慢,甚至找不到問題根源,也是常有的事。雖然已經有很多日志監控工具,或許單個工具功能還不錯,但整體服務化水平參差不齊,工具間不能互通互聯;另一方面,由于日志數據量大,且分散,使得查找問題根源基本靠人品。

這些也是我們要開發CAT的初衷。

CAT簡介

CAT(Central Application Tracking),是基于純Java開發的分布式實時監控系統。開源代碼托管在GitHub(搜索CAT即可),作者是吳其敏(qmwu2000)和尤勇(youyong205)。

產品相關分享在網上可以找到:

看大眾點評如何通過實時監控系統CAT打造7*24服務-尤勇@QCon高可用架構群 2015

分布式監控系統的設計與實現-尤勇@QCon上海2015

大眾點評網監控系統架構剖析-尤勇@2013第二屆華東架構師大會

大眾點評網監控平臺剖析-吳其敏@QCon杭州2012

CAT現狀

CAT采用非常開放的Apache License開源,在國內已經有100多家互聯網公司在使用和評估,包括大眾點評網、攜程網、獵聘網、陸金所和找鋼網等。截至2016年3月,CAT已經獲得了1000多個stars。

設計目標

可擴展:支持分布式、跨IDC部署,橫向擴展。

高可用:所有應用都可以倒下了,需要監控還站著,告訴它們發生了什么。

實時處理:信息的價值會隨時間銳減,尤其是事故處理過程中。

全量數據:小概率事件是常態,百萬分之一的概率,碰到了就是100%。

高吞吐:要想還原真相,需要全方位的監控和度量,必須要有超強的處理吞吐能力。

故障容忍:CAT本身故障不應該影響業務正常運轉,CAT掛了,應用不該受影響,只是監控能力暫時減弱。

不保證可靠:允許消息丟失,這是一個很重要的trade-off,雖然目前CAT可以做到4個9的可靠性。

CAT架構

架構追求簡單去中心化分工協作,兩層結構,除了依賴外部存儲如HDFS和MySQL外,不依賴其他系統,CAT內部全面采用組件化設計和實現。CAT每天消息量巨大,一臺機器是不能處理全部流量,必須分片處理,均衡負載。

業務應用目前使用CAT API進行埋點,后臺異步線程采用TCP長連接方式,將消息源源不斷地傳輸到后臺服務器;CAT具有fail-over機制,在后臺服務器不可用時會自動切換到另一臺可用服務器。CAT目前使用native協議做序列化和反序列化,將來會考慮支持更多協議,比如thrift。

消息被送到后臺,經反序列化后會被放入隊列,實時消費調度器會將消息分發到所有消費者內部隊列,每個消費者只需處理自己的消費隊列,各消費者之間彼此相對獨立,如果消費速度太慢,導致消費隊列滿,則新來的消息會被丟棄。典型消費者都采用實時增量計算的方式,流式處理消息,產生的報表會在當前小時結束后保存到中央數據庫中。

日報表采用后臺作業的形式,由24個小時報表合并得到。周報表則由7個日報表合并得到,以此類推。

CAT控制臺,即UI層,負責接收用戶請求,從后臺存儲中將報表信息取出顯示。對于實時報表,直接通過HTTP請求分發到相應消費機,待結果返回后聚合展示;歷史報表則直接取數據庫并展示。

所有原始消息會先存儲在本地文件系統,然后上傳到HDFS中保存;而對于報表,因其遠比原始日志小,則以K/V的方式保存在MySQL中。

消息處理

消息處理分五個階段:收集、傳輸、分析、存儲和展示

收集階段:負責業務應用日志的埋點和采集。CAT目前提供多種語言的客戶端供業務應用程序調用,埋點結果以消息樹的形式存入傳輸隊列。如果隊列滿,則會自動丟棄當前消息。

傳輸階段:CAT客戶端負責將客戶端消息傳輸到后端,CAT消費機負責接收消息。傳輸前CAT客戶端會與CAT消費機建立TCP長連接,不斷地從客戶端隊列中取出消息樹,序列化后寫入網絡;CAT消費機則不斷地從網絡中取出數據,反序列化后放入消費隊列。

分析階段:負責報表生成。實時消費調度器會將消費隊列消息取出,分發給每個消費者內部隊列;報表分析器只會從自己的報表隊列中取出消息樹,逐個消費,更新報表模型。CAT以小時為單位形成報表,原始日志轉儲(raw log dump)是一個特殊的分析器,它不生產報表,而是將消息存入本地文件系統。

存儲階段:負責報表和原始日志的存儲,目前報表會存在MySQL中,原始日志壓縮后存在HDFS中長久保存。保留時長取決于存儲容量的大小,一般報表會保存3個月以上,原始日志保存一個月。

展示階段:負責數據的可視化。作為用戶服務入口,負責報表和原始日志的輸出顯示。對于實時報表請求,會向各個消費機分發請求,并將結果聚合后輸出HTML,在瀏覽器展示;歷史報表會直接取自數據庫。XML數據輸出是另一種內置的數據展示方式,方便基于CAT開放外圍工具。

日志埋點

日志埋點是監控活動的最重要環節之一,日志質量決定著監控質量和效率。當前CAT的埋點目標是以問題為中心,像程序拋出exception就是典型問題。我個人對問題的定義是:不符合預期的就可以算問題。比如請求未完成,響應時間快了慢了,請求TPS多了少了,時間分布不均勻等等。

在互聯網環境中,最突出的問題場景,我的理解是,跨越邊界的行為。包括但不限于,HTTP/REST、RPC/SOA、MQ、Job、Cache、DAL; 搜索/查詢引擎、業務應用、外包系統、遺留系統; 母/子公司, 第三方網關/銀行, 合作伙伴/供應商之間;還有各類業務指標,如PV、用戶登錄、訂單數、支付狀態、銷售額。

CAT提供API支持的語言有:Java,.NET,將來打算支持C/C++、NodeJS、Go、PHP、Python等。

領域建模

此模型可以覆蓋大部分業務應用的日常埋點需求。各種類型都有個性化分析和展示。

消息樹

CAT消息樹如實記錄真實用戶請求的處理時序,這些請求可能被分布在多臺機器上。消息樹可以豐富地表達嵌套關系、先后次序和并行處理,這將有助于開發者清楚的了解用戶請求到底是怎么被一步步執行的,尤其在追蹤一些疑難雜癥時,這會特別有用。

只要遵循CAT埋點規范,CAT會自動地將多臺機器上的消息樹串起來,可以逐層展示。

當然也有另一種更適合于人的視圖,方便識別突出問題,畢竟人對圖形識別更加擅長。

CAT API

API力求精簡,將來還有進一步優化空間。大部分CAT埋點應該在底層基礎架構中完成,一般應用層不需要做大多埋點。有些產品使用如java-agent等方式埋點,CAT埋點也可以采用,埋點質量取決于現有應用代碼的規范程度和覆蓋范圍。

實時分析

CAT的實時性不是用戶要看什么,CAT就實時計算出結果,呈現給用戶;而是根據日志消息的特點(比如只讀特性)和問題場景,量身定做的。CAT將所有的報表按消息的創建時間,一小時為單位分片,那么每小時就產生一個報表。當前小時報表的所有計算都是基于內存的,用戶每次請求即時報表得到的都是最新結果,給人一種“實時”的感覺。對于歷史報表,因為它是不變的,所以就實時不實時也就無所謂了。

對于內存增量計算,它可以分為:計數、計時和關系處理三種。計數又可以分為兩類:算術計數和集合計數。典型的算術計數如:總個數(count),總和(sum),均值(avg),最大/最小(max/min),吞吐(tps)和標準差(std)等,其他都比較直觀,標準差稍微復雜一點,大家自己可以推演一下怎么做增量計算。那集合運算,比如95線(表示95%請求的完成時間),999線(表示99.9%請求的完成時間),DAU(日活用戶數)等,則稍微復雜一些,系統開銷也更大一點。關系處理則涉及圖的運算,這里不細述。

報表建模

了解增量計算很重要,但最終需要落實到各個不同的報表上。一個報表往往有多個維度,以transaction報表為例,它有5個維度,分別是應用、機器、大類、小類和分布情況。如果全維度建模,雖然靈活,但開銷將會非常之大。CAT選擇固定維度建模,可以理解成將這5個維度組織成深度為5的樹,訪問時總是從根開始,逐層往下進行。

CAT為每個報表單獨分配一個線程,所以不會有鎖的問題,所有報表模型都是非線程安全的,其數據是可變的。這樣帶來的好處是簡單且低開銷

報表代碼是使用自研的maven plugin自動生成的。所有報表是可合并和裁剪的,可以輕易地將2個或多個報表合并成一個報表。在報表處理代碼中,CAT大量使用訪問者模式(visitor pattern)。

消息存儲

消息存儲是CAT最有挑戰的部分。關鍵問題是消息數量多且大,像大眾點評和攜程每天消息數在300-400億左右,大小有50TB,也就是說每秒消息數在50-60萬上下,每秒大小在1GB左右。如果分10臺機器處理,則每天每秒需要處理5-6萬消息,100MB大小。如果網站流量來點波動的話,挑戰就更大了。由于時間關系,這部分今天就不細述了(感興趣的同學,歡迎加群與吳老師一對一交流)。

總結

CAT在分布式實時方面,主要歸結于以下幾點因素:

去中心化,數據分區處理;

基于日志只讀特性,以一個小時為時間窗口,實時報表基于內存建模和分析,歷史報表通過聚合完成;

基于內存隊列,全面異步化,單線程化,無鎖設計;

全局消息ID,數據本地化生產,集中式存儲;

組件化、服務化理念,致力于工具間互通互聯。

嘉賓介紹

吳其敏,互聯網老兵,軟件工匠,開源愛好者,一直深入代碼一線,接觸java近20年。現在攜程網負責框架研發,曾任大眾點評網首席架構師、任eBay&易趣資深架構師等。關注分布式系統框架、組件化系統開發,高質量數據建模和代碼生成等。

互動問答

問題:業界類似解決方案,以及與CAT的異同?

業界有很多開源監控系統,但大多是基于日志行的(如ELK),CAT是基于日志樹的。其中最主要的差異是監控源數據的質量。

問題:請問吳老師,CAT與應用間是否做了反饋機制,監控報警后是否會有應用重啟,服務降級這種操作?點評內部的pigeon是否有這種服務健康檢查包括自動降級的功能,能否談談您的看法?

監控可以理解為監和控。現階段CAT的側重點還是在監上,將來會考慮控的一面。要做到控,光CAT是不夠的。

問題:CAT如何做到高實時性,又如何避免對應用本身性能,可用性等產生影響的?

CAT在編碼的時候非常的關系性能,每一行代碼都經過多次review。消息發送異步化也是避免對主線程造成性能和可用性干擾的重要手段。另外,CAT在設計時就要求做到:不保證可靠,如果后臺出現可用性問題和性能問題,客戶端會主動丟棄消息,確保應用可用。

問題:怎么解決埋點性能問題?特別是訪問量大的應用,千萬級的,出現問題很多?

這是個好問題。CAT不會幫你解決業務埋點的問題。監控埋點是一個領域,跟你要解決的問題非常相關,不同應用,不同場合,不同公司的歷史階段,應該采取不同的策略。對于訪問量非常大的應用,CAT埋點要做到小而精,適當的時候可以在客戶端做一下聚合。

問題:請問這里的消息樹是怎么實現的?是自己規定流程自主研發嗎?

只要使用CAT API埋點,消息樹是自然而然形成的,無需特別處理。CAT中有示例代碼,可以參考一下。

問題:請教吳老師cat server端集群部署時,且數據落本地磁盤,報表的統計基于全量數據還是只是開起任務的哪臺機器上的數據,如果是全量的,數據是怎么匯總的?

CAT是主張全量日志分析的,全量數據落到每一臺消費機上只是一個分片,CAT中所有報表都有內置將分片合并的能力,所有的報表在展示時會合并,做數據匯總。

問題:如果客戶端上報大量size很大的日志,CAT有沒有自保護?

有。CAT在客戶端有保護機制,服務器端一般處理能力很強,有一定的保存措施,如丟棄消息之類的。但如果報表過大,則可能會出現內存問題。

感謝志愿者田光、攀爬的蝸牛、Bendy PAN、qiaoliang、王旭林、cloes對本文的整理和編輯。本文是老X聊架構系列文章的第十篇,聊聊架構社群將會邀請國內頂級的架構師與大家探討實戰中的架構經驗,歡迎關注『聊聊架構』公眾號并回復『干貨』獲取入群方式。

號外號外

吳老師提到的由InfoQ組織的全球頂級的軟件開發大會QCon北京將會在4月21日舉行(倫敦站剛剛結束),在大會的第一天就設有架構相關的專題,目前確定分享的主題有58到家的實時消息平臺架構、魅族的推薦系統實踐、藝龍的電商檢索系統,還有知乎的反作弊系統。

感興趣的同學歡迎點擊閱讀原文鏈接了解會議詳情,輸入聊聊架構社群優惠碼QCON-ARCHTIME-PROMO獲取專屬優惠

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容