毫秒間查詢千億級Trace數(shù)據(jù),SkyWalking上鏈路追蹤這么強?
一、開篇
自從SkyWalking開始在公司推廣,時不時會在排查問題的人群中聽到這樣的話:“你咋還沒接SkyWalking?接入后,一眼就看出是哪兒的問題了…",正如同事所說的,在許多情況下,SkyWalking就是這么秀。作為實踐者,我非常感謝SkyWalking,因為這款國產全鏈路監(jiān)控產品給公司的伙伴們帶來了實實在在的幫助;也特別感謝公司的領導和同事們,正因為他們的支持和幫助,才讓這套SkyWalking(V8.5.0)系統(tǒng)從起初的有用進化到現(xiàn)在的好用;從幾十億的Segment儲能上限、幾十秒的查詢耗時,優(yōu)化到千億級的Segment儲能、毫秒級的查詢耗時。
小提示:
- SkyWalking迭代速度很快,公司使用的是8.5.0版本,其新版本的性能肯定有改善。
- Segment是SkyWalking中提出的概念,表示一次請求在某個服務內的執(zhí)行鏈路片段的合集,一個請求在多個服務中先后產生的Segment串起來構成一個完整的Trace,如下圖所示:
SkyWalking的這次實踐,截止到現(xiàn)在有一年多的時間,回顧總結一下這段歷程中的些許積累和收獲,愿能反哺社區(qū),給有需求的道友提供個案例借鑒;也希望能收獲到專家們的指導建議,把項目做得更好。因為安全約束,要把有些內容和諧掉,但也努力把這段歷程中那些靚麗的風景,盡可能完整地呈現(xiàn)給大家。
二、為什么需要全鏈路監(jiān)控
隨著微服務架構的演進,單體應用按照服務維度進行拆分,組織架構也隨之演進以橫向、縱向維度拆分;一個業(yè)務請求的執(zhí)行軌跡,也從單體應用時期一個應用實例內一個接口,變成多個服務實例的多個接口;對應到組織架構,可能跨越多個BU、多個Owner。雖然微服務架構高內聚低耦合的優(yōu)勢是不言而喻的,但是低耦合也有明顯的副作用,它在現(xiàn)實中給跨部門溝通、協(xié)作帶來額外的不可控的開銷;因此開發(fā)者尤其是終端業(yè)務側的架構師、管理者,特別需要一些可以幫助理解系統(tǒng)拓撲和用于分析性能問題的工具,便于在架構調整、性能檢測和發(fā)生故障時,縮減溝通協(xié)作方面的精力和時間耗費,快速定位并解決問題。
我所在的平安健康互聯(lián)網股份有限公司(文中簡稱公司),是微服務架構的深度實踐者。公司用互聯(lián)網技術搭建醫(yī)療服務平臺,致力于構筑專業(yè)的醫(yī)患橋梁,提供專業(yè)、全面、高品質、一站式企業(yè)健康管理服務。為了進一步提高系統(tǒng)服務質量、提升問題響應效率,部門在21年結合自身的一些情況,決定對現(xiàn)行的全鏈路監(jiān)控系統(tǒng)進行升級,目的與以下網絡中常見的描述基本一致:
- 快速發(fā)現(xiàn)問題
- 判斷故障影響范圍
- 梳理服務依賴并判斷依賴的合理性
- 分析鏈路性能并實施容量規(guī)劃
三、為什么選擇SkyWalking
在做技術選型時,網絡中搜集的資料顯示,谷歌的Dapper系統(tǒng),算是鏈路追蹤領域的始祖。受其公開論文中提出的概念和理念的影響,一些優(yōu)秀的企業(yè)、個人先后做出不少非常nice的產品,有些還在社區(qū)開源共建,如:韓國的Pinpoint,Twitter的Zipkin,Uber的Jaeger及中國的SkyWalking等,我司選型立項的過程中綜合考慮的因素較多,這里只歸納一下SkyWalking吸引我們的2個優(yōu)勢:
1)產品的完善度高:
- java生態(tài),功能豐富
- 社區(qū)活躍,迭代迅速
2)鏈路追蹤、拓撲分析的能力強:
- 插件豐富,探針無侵入
- 采用先進的流式拓撲分析設計
“好東西不需要多說,實際行動告訴你“,這句話我個人非常喜歡,關于SkyWalking的眾多的優(yōu)點,網絡上可以找到很多,此處先不逐一比較、贅述了。
四、預研階段
當時最新版本8.5.0,梳理分析8.x的發(fā)布記錄后,評估此版本的核心功能是蠻穩(wěn)定的,于是基于此版本開始了SkyWalking的探索之旅。當時的認知是有限的,串行思維模型驅使我將關注的問題聚焦在架構原理是怎樣、有什么副作用這2個方面:
1)架構和原理:
- agent端 主要關注 Java Agent的機制、SkyWalking Agent端的配置、插件的工作機制、數(shù)據(jù)采集及上報的機制。
- 服務端 主要關注 角色和職責、模塊和配置、數(shù)據(jù)接收的機制、指標構建的機制、指標聚合的機制及指標存儲的機制。
- 存儲端 主要關注 數(shù)據(jù)量,存儲架構要求以及資源評估。
2)副作用:
- 功能干擾
- 性能損耗
1、架構和原理
SkyWalking社區(qū)很棒,官網文檔和官方出版的書籍有較系統(tǒng)化的講解,因為自己在APM系統(tǒng)以及Java Agent方面有一些相關的經驗沉淀,通過在這兩個渠道的學習,對Agent端和OAP(服務端)很快便有了較系統(tǒng)化的認知。在做系統(tǒng)架構選型時,評估數(shù)據(jù)量會比較大(成千上萬的JVM實例數(shù),每天采集的Segment數(shù)量可能是50-100億的級別),所以傳輸通道選擇Kafka、存儲選擇Elasticsearch,如此簡易版的架構以及數(shù)據(jù)流轉如下圖所示:
這里有幾處要解釋一下:
- Agent上報數(shù)據(jù)給OAP端,有grpc通道和kafka通道,當時就盲猜grpc通道可能撐不住,所以選擇kafka通道來削峰;kafka通道是在8.x里加入的。
- 千億級的數(shù)據(jù)用ES來做存儲肯定是可以的。
- 圖中L1聚合的意思是:SkyWalking OAP服務端 接收數(shù)據(jù)后,構建metric并完成metric 的Level-1聚合,這里簡稱L1聚合。
- 圖中L2聚合的意思是:服務端 基于metric的Level-1聚合結果,再做一次聚合,即Level-2聚合,這里簡稱L2聚合。后續(xù)把純Mixed角色的集群拆成了兩個集群。
2、副作用
對于質量團隊和接入方來說,他們最關注的問題是,接入SkyWalking后:
- 是否對應用有功能性干擾
- 在運行期能帶來哪些性能損耗
這兩個問題從3個維度來得到答案:
1)網絡資料顯示:
- Agent帶來的性能損耗在5%以內
- 未搜到功能性干擾相關的資料(盲猜沒有這方面問題)
2)實現(xiàn)機制評估:
- 字節(jié)碼增強機制是JVM提供的機制,SkyWalking使用的字節(jié)碼操控框架ByteBuddy也是成熟穩(wěn)定的;通過自定義ClassLoader來加載管理插件類,不會產生沖突和污染。
- Agent內插件開發(fā)所使用的AOP機制是基于模板方法模式實現(xiàn)的,風控很到位,即使插件的實現(xiàn)邏輯有異常也不影響用戶邏輯的執(zhí)行。
- 插件采集數(shù)據(jù)跟上報邏輯之間用了一個輕量級的無鎖環(huán)形隊列進行解耦,算是一種保護機制;這個隊列在MPSC場景下性能還不錯;隊列采用滿時丟棄的策略,不會有積壓阻塞和OOM。
3)性能測試驗證:
測試的老師針對dubbo、http這兩種常規(guī)RPC通信場景,進行壓力測試和穩(wěn)定性測試,結果與網絡資料描述一致,符合預期。
五、POC階段
在POC階段,接入幾十個種子應用,在非生產環(huán)境試點觀察,同時完善插件補全鏈路,對接公司的配置中心,對接發(fā)布系統(tǒng),完善自監(jiān)控,全面準備達到推廣就緒狀態(tài)。
1、對接發(fā)布系統(tǒng)
為了對接公司的發(fā)布系統(tǒng),方便系統(tǒng)的發(fā)布,將SkyWalking應用拆分為4個子應用:
這里有個考慮,暫定先使用純Mixed角色的單集群,有性能問題時就試試 Receiver+Aggregator雙角色集群模式,最終選哪種視效果而定。
SkyWalking Agent端是基于Java Agent機制實現(xiàn)的,采用的是啟動掛載模式;啟動掛載需在啟動腳本里加入掛載Java Agent的邏輯,發(fā)布系統(tǒng)實現(xiàn)這個功能需要注意2點:
- 啟動腳本掛載SkyWalking Agent的環(huán)節(jié),盡量讓用戶無感知。
- 發(fā)布系統(tǒng)在掛載Agent的時候,給Agent指定應用名稱和所屬分組信息。
SkyWalking Agent的發(fā)布和升級也由發(fā)布系統(tǒng)來負責;Agent的升級采用了灰度管控的方案,控制的粒度是應用級和實例級兩種:
- 按照應用灰度,可給應用指定使用什么版本的Agent
- 按照應用的實例灰度,可給應用指定其若干實例使用什么版本的Agent
2、完善插件補全鏈路
針對公司OLTP技術棧,量身定制了插件套,其中大部分在開源社區(qū)的插件庫中有,缺失的部分通過自研快速補齊。
這些插件給各組件的核心環(huán)節(jié)埋點,采集數(shù)據(jù)上報給SkyWalking后,Web端的【追蹤】頁面就能勾勒出豐滿完美的請求執(zhí)行鏈路;這對架構師理解真實架構,測試同學驗證邏輯變更和分析性能損耗,開發(fā)同學精準定位問題都非常的有幫助。這里借官方在線Demo的截圖一用(抱歉后端程序員,五毛特效都沒做出來,豐滿畫面還請自行腦補)
友情小提示:移除不用的插件對程序編譯打包和減少應用啟動耗時很有幫助。
3、壓測穩(wěn)測
測試的老師,針對SkyWalking Agent端的插件套,設計了豐富的用例,壓力測試和穩(wěn)定性測試的結果都符合預期;每家公司的標準不盡一致,此處不再贅述。
4、對接自研的配置中心
把應用中繁雜的配置交給配置中心來管理是非常必要的,配置中心既能提供啟動時的靜態(tài)配置,又能管理運行期的動態(tài)配置,而且外部化配置的機制特別容易滿足容器場景下應用的無狀態(tài)化要求。啰嗦一下,舉2個例子:
- 調優(yōu)時,修改參數(shù)的值不用來一遍開發(fā)到測試再到生產的發(fā)布。
- 觀測系統(tǒng)狀態(tài),修改日志配置后不需要來一遍開發(fā)到測試再到生產的發(fā)布。
Skywaling在外接配置中心這塊兒,適配了市面中主流的配置中心產品。而公司的配置中心是自研的,需要對接一下,得益于SkyWalking提供的模塊化管理機制,只用擴展一個模塊即可。
在POC階段,梳理服務端各模塊的功能,能感受到其配置化做的不錯,配置項很豐富,管控的粒度也很細;在POC階段幾乎沒有變動,除了對Webapp模塊的外部化配置稍作改造,與配置中心打通以便在配置中心管理Webapp模塊中Ribbon和Hystrix的相關配置。
5、完善自監(jiān)控
自監(jiān)控是說監(jiān)控SkyWalking系統(tǒng)內各模塊的運轉情況:
完善自監(jiān)控后的架構如下圖所示:
6、自研Native端SDK
公司移動端的應用很核心,也要使用鏈路追蹤的功能,社區(qū)缺了這塊,于是基于SkyWalking的協(xié)議,移動端的伙伴們自研了一套SDK,彌補了Native端鏈路數(shù)據(jù)的缺失,也在后來的秒開頁面指標統(tǒng)計中發(fā)揮了作用。隨著口口相傳,不斷有團隊提出需求、加入建設,所以也在持續(xù)迭代中;內容很多,這里先不展開。
7、小結
POC階段數(shù)據(jù)量不大,主要是發(fā)現(xiàn)系統(tǒng)的各種功能性問題,查缺補漏。
六、優(yōu)化階段
SkyWalking的正式推廣采用的是城市包圍農村的策略;公司的核心應用作為第一批次接入,這個策略有幾個好處:
- 核心應用的監(jiān)管是重中之重,優(yōu)先級默認最高。
- 核心應用的上下游應用,會隨著大家對SkyWalking依賴的加深,而逐步自主接入。
當然安全是第一位的,無論新系統(tǒng)多好、多厲害,其引入都需遵守安全穩(wěn)定的前提要求。既要安全又要快速還要方便,于是基于之前Agent灰度接入的能力,在發(fā)布系統(tǒng)中增加應用Owner自助式灰度接入和快速卸載SkyWalking Agent的能力,即應用負責人可自主選擇哪個應用接入,接入幾個實例,倘若遇到問題僅通過重啟即可完成快速卸載;這個能力在推廣的前期發(fā)揮了巨大的作用;畢竟安全第一,信任也需逐步建立。
隨著應用的接入、使用,我們也逐漸遇到了一些問題,這里按照時間遞增的順序將問題和優(yōu)化效果快速的介紹給大家,更多技術原理的內容計劃在公眾號『架構染色』專輯【SkyWalking調優(yōu)系列】補充。開始之前有幾個事項要說明:
- 下文中提到的數(shù)字僅代表我司的情況,標注的Segment數(shù)量是處理這個問題的那段時間的情況,并不是說達到這個數(shù)量才開始出現(xiàn)這個現(xiàn)象。
- 這些數(shù)值以及當時的現(xiàn)象,受到宿主機配置、Segment數(shù)據(jù)的大小、存儲處理能力等多種因素的影響;請關注調整的過程和效果,不必把數(shù)字和現(xiàn)象對號入座哈。
1、啟動耗時
1)問題
有同事反饋應用啟動變慢,排查發(fā)現(xiàn)容器中多數(shù)應用啟動的總耗時,在接入SkyWalking前是2秒,接入后變成了16秒以上,公司很多核心應用的實例數(shù)很多,這樣的啟動損耗對它們的發(fā)布影響太大。
2)優(yōu)化
- 記錄啟動耗時并隨著其他啟動數(shù)據(jù)上報到服務端,方便查看對比。
- 優(yōu)化Kafka Reporter的啟動過程,將啟動耗時減少了3-4秒。
- 優(yōu)化類匹配和增強環(huán)節(jié)(重點)后,容器中的應用啟動總耗時從之前16秒以上降低到了3秒內。
- 梳理Kafka 啟動和上報的過程中,順帶調整了Agent端的數(shù)據(jù)上報到kafka的分區(qū)選擇策略,將一個JVM實例中的數(shù)據(jù)全部發(fā)送到同一個的分區(qū)中,如此在L1層的聚合就完成了JVM實例級的Metric聚合,需注意調整Kafka分片數(shù)來保證負載均衡。
2、kafka積壓-6億segment/天
1)問題
SkyWalking OAP端消費慢,導致Kafka中Segment積壓。未能達到能用的目標。
2)優(yōu)化
從SkyWalking OAP端的監(jiān)控指標中沒有定位出哪個環(huán)節(jié)的問題,把服務端單集群拆為雙集群,即把 Mixed角色的集群 ,修改為 Receiver 角色(接收和L1聚合)的集群 ,并加入 Aggregation角色(L2聚合)的集群,調整成了雙集群模式,數(shù)據(jù)流傳如下圖所示:
3、kafka積壓-8億segment/天
1)問題
SkyWalking OAP端消費慢,導致Kafka中Segment積壓,監(jiān)控指標能看出是在ES存儲環(huán)節(jié)慢,未能達到能用的目標。
2)優(yōu)化
- 優(yōu)化segment保存到ES的批處理過程,調整BulkProcessor的線程數(shù)和批處理大小。
- 優(yōu)化metrics保存到ES的批處理過程,調整批處理的時間間隔、線程數(shù)、批處理大小以及刷盤時間。
4、kafka積壓-20億segment/天
1)問題
Aggregation集群的實例持續(xù)Full GC,Receiver集群通過grpc給Aggregation集群發(fā)送metric失敗。未能達到能用的目標。
2)優(yōu)化
- 增加ES節(jié)點、分片,效果不明顯。
- ES集群有壓力,但無法精準定位出是什么數(shù)據(jù)的什么操作引發(fā)的。采用分治策略,嘗試將數(shù)據(jù)拆分,從OAP服務端讀寫邏輯調整,將ES單集群拆分為 trace集群 和 metric集群;之后對比ES的監(jiān)控指標明確看出是metric集群讀寫壓力太大。
- 優(yōu)化Receiver集群metric的L1聚合,完成1分鐘的數(shù)據(jù)聚合后,再提交給Aggregation集群做L2聚合。
- Aggregation集群metric的L2 聚合是基于db實現(xiàn)的,會有 空讀-寫-再讀-累加-更新寫 這樣的邏輯,每次寫都會有讀,調整邏輯是:提升讀的性能,優(yōu)化緩存機制減少讀的觸發(fā);調整間隔,避免觸發(fā)累加和更新。
- 將metric批量寫ES操作調整成BulkProcessor。
- ES的metric集群使用SSD存儲,增加節(jié)點數(shù)和分片數(shù)。
這一次的持續(xù)優(yōu)化具有里程碑式的意義,Kafka消費很快,OAP各機器的Full GC沒了,ES的各方面指標也很穩(wěn)定;接下來開始優(yōu)化查詢,提升易用性。
5、trace查詢慢-25億segment/天
1)問題
Web端【追蹤】頁中的查詢都很慢,僅保存了15天的數(shù)據(jù),按照traceId查詢耗時要20多秒,按照條件查詢trace列表的耗時更糟糕;這給人的感受就是“一肚子墨水倒不出來”,未能達到好用的目標。
2)優(yōu)化
ES查詢優(yōu)化方面的信息挺多,但通過百度篩選出解決此問題的有效方案,就要看咱家愛犬的品類了;當時搜集整理了并嘗試了N多優(yōu)化條款,可惜沒有跟好運偶遇,結論是顏值不可靠。言歸正傳,影響讀寫性能的基本要素有3個:讀寫頻率,數(shù)據(jù)規(guī)模,硬件性能;trace的情況從這三個維度來套一套模板:
這個分析沒有得出具有指導意義的結論,讀寫頻率這里粒度太粗,用戶的使用情況跟時間也有緊密的關系,情況大概是:
- 當天的數(shù)據(jù)是讀多寫多(當天不斷有新數(shù)據(jù)寫入,基于緊急響應的需求,問題出現(xiàn)時可能是近實時的排查處理)。
- 前一天的數(shù)據(jù)是讀多寫少(一般也會有問題隔天密集上報的情況,0點后會有前一天數(shù)據(jù)延遲到達的情況)。
- 再早的話無新數(shù)據(jù)寫入,數(shù)據(jù)越早被讀的概率也越小。
基于以上分析,增加時間維度并細化更多的參考因素后,分析模型變成了這樣:
從上表可以看出,整體呈現(xiàn)出hot-warm數(shù)據(jù)架構的需求之勢,近1-2天為hot數(shù)據(jù),之前的為warm數(shù)據(jù);恰好ES7提供了hot-warm架構支持,按照hot-warm改造后架構如下圖所示:
- 恰逢公司ES中臺調優(yōu)版的ES發(fā)布,其內置的ZSTD壓縮算法空間壓縮效果非常顯著。
- 對 trace集群進行hot-warm架構調整,查詢耗時從20多秒變成了2-3秒,效果是非常明顯的。
- 從查詢邏輯進一步調整,充分利用ES的數(shù)據(jù)分片、路由機制,把全量檢索調整為精準檢索,即降低檢索時需要掃描的數(shù)據(jù)量,把2-3秒優(yōu)化到毫秒。
這里要炫一個5毛特效,這套機制下,Segment數(shù)據(jù)即使是保留半年的,按照TraceId查詢的耗時也是毫秒。
至此完成了查詢千億級Trace數(shù)據(jù)只要毫秒級耗時的階段性優(yōu)化。
6、儀表盤和拓撲查詢慢
1)問題
Web端的【拓撲】頁,在開始只有幾十個應用的時候,雖然很慢,但還是能看到數(shù)據(jù),隨著應用增多后,【拓撲】頁面數(shù)據(jù)請求一直是超時(配置的60s超時)的,精力有限,先通過功能降級把這個頁面隱藏了;【儀表盤】的指標查詢也非常的慢,未能達到好用的目標。
2)優(yōu)化
Web端的【儀表盤】頁和【拓撲】頁是對SkyWalking里metric數(shù)據(jù)的展現(xiàn),metric數(shù)據(jù)同trace數(shù)據(jù)一樣滿足hot-warm的特征。
①metric集群采用hot-warm架構調整,之后儀表盤中的查詢耗時也都減小為毫秒級。
②【拓撲】頁接口依然是超時(60s),對拓撲這里做了幾個針對性的調整:
- 把內部的循環(huán)調用合并,壓縮調用次數(shù)。
- 去除非必要的查詢。
- 拆分隔離通用索引中的數(shù)據(jù),避免互相干擾。
- 全量檢索調整為精準檢索,即降低檢索時需要掃描的數(shù)據(jù)量。
至此完成了拓撲頁數(shù)據(jù)查詢毫秒級耗時的階段性優(yōu)化。
7、小結
SkyWalking調優(yōu)這個階段,恰逢上海疫情封城,既要為生存搶菜,又要翻閱學習著各種ES原理、調優(yōu)的文檔資料,一行一行反復的品味思考SkyWalking相關的源碼,嘗試各種方案去優(yōu)化它,夢中都在努力提升它的性能。疫情讓很多人變得焦慮煩躁,但以我的感受來看在系統(tǒng)的性能壓力下疫情不值一提。凡事貴在堅持,時間搞定了諸多困難,調優(yōu)的效果是很顯著的。
可能在業(yè)務價值驅動的價值觀中這些技術優(yōu)化不產生直接業(yè)務價值,頂多是五毛特效,但從其他維度來看它價值顯著:
- 對個人來說,技術有提升。
- 對團隊來說,實戰(zhàn)練兵提升戰(zhàn)力,團隊協(xié)作加深友情;特別感謝ES中臺這段時間的鼎力支持!
- 對公司來說,易用性的提升將充分發(fā)揮SkyWalking的價值,在問題發(fā)生時,給到同事們切實、高效的幫助,使得問題可以被快速響應;須知戰(zhàn)爭拼的是保障。
這期間其實也是有考慮過其他的2個方案的:
- 使用降低采樣率的兜底方案;但為了得到更準確的指標數(shù)據(jù),以及后續(xù)其他的規(guī)劃而堅持了全采樣。
- 采用ClickHouse優(yōu)化存儲;因為公司有定制優(yōu)化的ES版本,所以就繼續(xù)在ES上做存儲優(yōu)化,剛好借此機會驗證一下。后續(xù)【全鏈路結構化日志】的存儲會使用ClickHouse。
這個章節(jié)將內容聚焦在落地推廣時期技術層面的準備和調優(yōu),未描述團隊協(xié)調、推廣等方面的情況;因每個公司情況不同,所以并未提及;但其實對多數(shù)公司來說,有些項目的推廣比技術本身可能難度更大,這個項目也遇到過一些困難,PM去推廣是既靠能力又靠顏值, 以后有機會再與大家探討。
七、未來規(guī)劃
H5、Native以及后端應用都在持續(xù)接入中,相應的SDK也在不斷地迭代;目前正在基于已建立的鏈路通道,完善【全鏈路業(yè)務狀態(tài)追蹤】和【全鏈路結構化日志追蹤】,旨在給運營、客服、運維、開發(fā)等服務在一線的同事們提供多視角一站式的觀測平臺,全方位提升系統(tǒng)服務質量、提高問題響應速度。