海量監控數據處理妙招|時序數據庫 CTSDB 與 TARS 的結合

9月4日,閱文集團技術專家俞慧濤在 TARS 基金會召開的線上研討會(中國站)上進行了題爲「CTSDB 與 TARS 結合,解決海量監控數據的難題」的分享,對如何通過時序數據庫 CTSDB 與 TARS 的結合解決海量監控數據難題的應用實踐進行了深度詮釋。本文將詳細介紹該分享內容。

TARS 是騰訊於2017年開源的一套微服務框架,涉及包括開發、運維、以及測試在內的一整套微服務架構系統開發和運維的解決方案。隨着目前很多企業在業務體量數量以及微服務應用個數的規模化增長,監控數據也在呈現指數級增長態勢。TARS 中包含的發佈監控、日誌統計等服務和工具,能幫助用戶很好地解決服務健康程度監控、上報等問題。

但在實踐過程中,我們也發現,TARS 的源生存儲 MySQL 在查詢大數據量時會有無法及時輸出、多緯度聚合查詢無法展示等問題。基於這一痛點,我們通過將騰訊時序數據庫 CTSDB 與 TARS 結合的方式,解決了海量服務、海量監控以及監控輸出相對較慢等問題。

在講解我們的具體實踐前,先和大家簡單介紹下TARS 這套框架

圖1:TARS 項目的微服務開源生態系統


TARS 提供的生態支持了多種編程語言,包括 C++、Golang、Java、Node.js、PHP 和 Python 等。在上層提供了深度學習和 API 網關等一些功能,下層服務包含了服務發現、服務負載、Set/IDC 、Traffic 和日誌等功能。開發框架上有同步、異步、 TARS 協議、TUP 協議、SSL 協議、HTTP 協議和 Protocal buffers 協議,同時也支持 Cache 、DB、File System 等多種存儲的功能。


TARS 框架中監控系統現在是怎麼樣的?

TARS 平臺提供了多維度、多樣化的服務監控及特性監控。從下方的服務監控頁面可以看出,TARS 平臺的服務監控選項包含了流量、平均耗時、異常率、超時率等,可以自由選擇時間範圍、主調方業務名、主調方 IP、被調方 IP、接口名,從而縮小監控範圍,方便定位問題。


圖2:TARS 平臺的服務監控頁面


目前各個語言都提供了 Docker 部署(除此之外也支持物理機部署、Docker部署、物理機和Docker混合部署),只需把代碼倉庫地址配置到 TARS 平臺,就可以選擇分支、選擇編譯器、編譯、打包、分批發布部署到 TARS 平臺上。

當 TARS 客戶端收集完成所有數據後,會聚合寫入本地內存中,最終上報到服務器,然後聚集寫入到MySQL 。所以在簡潔清晰的流程和操作下,開發人員可以快速上手並維護這部分數據。


TARS 監控隨規模增長,數據量成指數級增加

如果把微服務比喻成中國的大小河流,那麼監控就是給各個河流的進出口,按每5分鐘記錄一次速度與水質數據 ,這數據隨着河流的交錯以相乘的方式幾何級增長。傳統的 MySQL 架構就像是所有的河流流向了一個小河一樣,無法承載這樣大的數據流量,最終會溢出 。

普通拆庫拆表流程下還面臨巨大的分析數據所產生的代碼和運維維護成本高的問題,因爲數據庫擴容需要對錶做拆解或者拆分到不同的服務上,難度較大、抗風險能力也比較低,處理起來十分複雜,所以目前暫時只支持一個數據庫的寫入。

圖3:TARS 平臺的監控數據流轉


傳統 MySQL 第二個問題是在大數據量下爲了更快的多緯度查詢更高效,會構建更多的索引來“ 加速”。主調被調與接口數量成乘積關係,數據量成倍數據增加且帶上了主調被調的基礎係數。

我們從下方的監控表 SQL 中就能發現這個問題:當索引使用15~16個維度的時候,插入速度會非常慢,索引佔用磁盤空間也非常大。例如在現在的生產過程中,如果有超過了1G 的監控數據,索引就需要佔用將近2~3個 G 的內存,消耗了大量的內存,而且在數據和索引量都非常多的情況下,它的寫入也會變得非常慢,這個時候在當前的服務特別多的情況下,我們從監控服務上就可以很清楚的看得到相關的信息。

圖4:TARS 監控 MySQL 數據庫中監控表的索引定義


那有沒有更好的辦法可以去解決這些問題?

我們考慮過使用一些相對比較成熟的方案來解決現在我們的問題,其中就包括了Elasticsearch 和 PostgreSQL 集羣版本,但是很快就發現它們都存在一些問題而不能完全滿足我們的需求:

  • Elasticsearch :不支持平臺監控服務希望具備的冷熱的概念,例如我們的大多數的需求都是希望請求當前 7天的數據而很少有人會超過7天。

  • PostgreSQL:同樣不支持冷熱的概念,且當分析量較大時也會存在索引量特別大的問題。

所以在層層篩選和對比下,我們最終還是選擇了騰訊雲提供的具有時序功能的 CTSDB。

CTSDB 是基於  Elasticsearch 改造的版本,擁有多維度的數據分析和時序的功能,不僅能幫助我們自動淘汰相對時間比較久的一些數據,還能查詢到最近7天到10天的熱的數據庫,也能順利支持多個維度的分析。


CTSDB 的特點及優勢

  • 高併發寫入:數據先寫入內存,對於線上的批量寫入比較友好。

  • 低成本存儲:通過數據上卷(Rollup),相比 MySQL 而言,能夠更好的對歷史數據做聚合,節省存儲空間。不僅能支持 avg、min、max 等常用聚合方式,還支持 Group  By、區間、Geo、嵌套等複雜聚合分析。

  • 運維成本趨向於 0 :不需人工消耗大量時間處理數據。


CTSDB 的架構存儲的亮點

  • 用:專有主節點負責維護保障整個集羣的健康狀態,最大程度的保證了數據不會丟失。

圖5:騰訊雲 CTSDB 的架構圖


  • 高擴展性:隨着業務發展和數據增長,節點的數量在30個節點保持最高狀態。


在確認使用 CTSDB 後,我們如何去進行操作和替換呢?

我們選擇了TarsJava重構了Tars-QueryStat(查詢) 與Tars-querystat(寫入)服務。目標是非常快速地替換這個服務並降低後續的查詢維護的成本。目前 TarsStat 服務和 Tars-QueryStat 服務都是使用的 C++ 使用的 TARS 流做的數據的接入。新增加功能維護成本相對較高。

第二個非常重要的的原因是Java 和Elasticsearch的協作非常的友好 。Java語言ElasticSearch客戶端可以直接連接到 CTSDB, 此客戶端在商業應用上和開源的歷史上擁有大量的成功的使用案例 。所以以選擇TarsJava 重構TarsStat 對我們而言就是一個非常好的選擇。


何實現一個連接到 CTSDB 的 TarsJava 服務

我們使用原 TarsStat 服務的 TARS IDL 文件生成 querystat與tarsstat兩個服務Java 版本的接口與項目文件, 增加 tars.tarsstat.consumer 把原本請示的節點做 Hash 劃分上報。這樣做的好處是可以實現多點部署,避免單節點宕機而影響服務正常運營。同時,運算服務多節點部署可以幫助我們在數據量大且運算特別消耗 CPU 的情況下,實現快速擴容並不丟失監控數據。

當多個服務進行數據運算時可分擔一部分數據寫入和 CPU 的壓力,而且能更快進行功能迭代(在之前部署時,使用原架構可能會存在一部分丟失,而目前最差情況也只是丟失其中的一部分)。

當然,我們目標也並不是爲了替換掉原本 C++ 的服務,而是我們希望在查詢和處理以及需求的產出能夠得到相對比較好的平衡。

圖6:從原 TarsCpp 語言服務改造成 TarsJava 服務的流程

從下圖中 ,原 TarsStat 的服務的數據結構已經設計的非常完美,實現自定義監控上報非常的容易。我們可以看到 TarsStat  的核心數據庫和數據結構 StatMicMsgHead 和StatMicMsgBody,它的接口是 reportMicMsg,最核心的結構體是 StatMicMsgBody 結構 , 它表示了聚合 5 分鐘的數據統計結果 。接收上報報的數據接口僅一個。
查看 StatMicMsgHead 數據結構,數據結構中的核心字段有 MasterName(主調的服務名),SlaveName (被調的服務名)InterfaceName(被調的服務接口)等。
結構體 StatMicMsgBody 負責了數據圖表展示與收集的工作。字段 count 是所有成功的調用量,字段 timeoutCount 是超時調用量,字段 execCount 是異常調用量。在最終圖表展現時,是以這樣的模式去展現當前監控的數據的:count =成功調用量;超時量=timeoutCount/總count+ timeoutCount 數。
這些數據結構非常的簡單,StatMicMsgHead 也負責了主健 Key 的作用。由 10 個值組成的 1個key 和 7個值來組成的 1個 body 的數據統計。我們目前的所有的數據都是聚合的狀態,而不是單個上報,因爲如果監控和數據都用單點的方式上報,當它的數據有 100 個接口去請求時,對整個服務的消耗非常大,所以我們在框架設計時不會實時地上報所有的數據到監控的服務。

圖7:TarsStat服務的數據結構與IDL描述文件


我們該如何實現多點 Hash 負載?

圖8:TarsJava Stat服務Hash負載的設計


我們目前使用的框架自帶 Hash 模式來請求目標的服務,原本整個請求到當前的服務,但是它宕機了服務也會受到影響。所以目前改造的方法是:

日誌上報服務tarsstat  增加一個 Provider Servant,Provider 使用 Hash 的方式 再去請求當前的服務新增加的 Consumer,Consumer 接收到 Hash 後的上報結果後,在內存中做累加統計表,並按 5 分鐘任務週期存儲到 CTSDB 。這種情況下最大的好處就是 consumer 只會收到一個服務的數據, 並不用加鎖非常的高效,且在當前統計完結束以後就直接可以存入到 CTSDB, 不需要在 CTSDB 再做一層聚合,所以說 CTSDB 永遠都只有寫入沒有聚合查詢處理操作,另外在 consumer 裏面去做聚合以後結束,也最大程度地保證了寫入的效率和服務上報不會存在較大的延遲。

在覈心方法上報的時候,我們使用是異步,增加了一個對應的數據分組上報到當前的服務。所以在最終處理好以後就有3個服務 stat(原本的話就只有一個),可以最大程度的保證即使其中一個出現問題,也可以馬上回傳所有監控信息,因爲如果節點宕機了,它會繼續重試,所以數據會自動快速恢復。

圖9:新上線的 TarsStat 服務部署到生產環境


從下圖中可以看到之前我們所處理的其中一個 StateConsumer、StatObj。在300多個監控下,三秒不到就可以把所有的結果和排序全部都給找出來,不管你選擇哪個維度,都能夠非常快速的去展現所有的監控的一個結果。

圖10:實際部署好的 Servant 名稱


如果有對  TARS 感興趣或者希望更深的去了解和學習 TARS 的朋友,可以前往  TARS 的 B 站官方賬號搜索包含  C++、Golang、Java、PHP 的入門部署以及 Demo 項目從0~1 上手實踐到發佈等上手課程:https://space.bilibili.com/358991052 




TARS基金會是Linux基金會下的非營利性、微服務基金會,致力於建設一個強大而靈活的微服務生態系統。無論你在哪個行業,無論你使用什麼技術棧,這裏能助你快速實現你的創意。


點“在看”讓TARS小姐姐變好看

本文分享自微信公衆號 - TARS星球(TarsCloud)。
如有侵權,請聯繫 [email protected] 刪除。
本文參與“OSC源創計劃”,歡迎正在閱讀的你也加入,一起分享。

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