1. 程式人生 > >透過CAT,來看分散式實時監控系統的設計與實現

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

轉載自:http://mp.weixin.qq.com/s?__biz=MzA5Nzc4OTA1Mw==&mid=410426909&idx=1&sn=851bf383a5c82f6c9eb5fa0f3b0b9399&scene=0#wechat_redirect

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在分散式實時方面,主要歸結於以下幾點因素:

  1. 去中心化,資料分割槽處理;

  2. 基於日誌只讀特性,以一個小時為時間視窗,實時報表基於記憶體建模和分析,歷史報表通過聚合完成;

  3. 基於記憶體佇列,全面非同步化,單執行緒化,無鎖設計;

  4. 全域性訊息ID,資料本地化生產,集中式儲存;

  5. 元件化、服務化理念,致力於工具間互通互聯。

嘉賓介紹

吳其敏,網際網路老兵,軟體工匠,開源愛好者,一直深入程式碼一線,接觸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聊架構系列文章的第十篇,聊聊架構社群將會邀請國內頂級的架構師與大家探討實戰中的架構經驗,歡迎關注『聊聊架構』公眾號並回復『乾貨』獲取入群方式。