大規(guī)模分布式鏈路分析計(jì)算在字節(jié)跳動(dòng)的實(shí)踐
一. 綜述
微服務(wù)架構(gòu)的快速發(fā)展使得分布式鏈路追蹤系統(tǒng)成為觀測(cè)體系中越來(lái)越重要的組件。字節(jié)跳動(dòng)的分布式鏈路追蹤系統(tǒng)經(jīng)歷了數(shù)年的發(fā)展后,已覆蓋了字節(jié)的絕大部分在線業(yè)務(wù),完成了對(duì)數(shù)萬(wàn)微服務(wù)和數(shù)百萬(wàn)微服務(wù)實(shí)例的在線鏈路追蹤。在經(jīng)典的指標(biāo)觀測(cè)分析和單請(qǐng)求鏈路追蹤的基礎(chǔ)上,如何從浩瀚如海的分布式鏈路數(shù)據(jù)中進(jìn)一步挖掘出更高層次的信息,為業(yè)務(wù)的架構(gòu)優(yōu)化、服務(wù)治理、成本優(yōu)化等場(chǎng)景提供更高效的數(shù)據(jù)支持,成為了下一步亟待回答的問題。
本次分享主要介紹我們構(gòu)建海量鏈路數(shù)據(jù)分析計(jì)算系統(tǒng)的實(shí)踐經(jīng)驗(yàn),以及一些具體的落地場(chǎng)景。
二. 可觀測(cè)性與鏈路追蹤
2.1 基本概念
為了方便讀者更好的理解“鏈路分析”,首先淺聊一下什么是“可觀測(cè)性”和“鏈路追蹤”。對(duì)“可觀測(cè)性”和“鏈路追蹤”的概念已經(jīng)熟悉的讀者可以跳過(guò)本章節(jié)。
隨著微服務(wù)架構(gòu)的快速發(fā)展,軟件系統(tǒng)正在從單體應(yīng)用發(fā)展為由大量微服務(wù)節(jié)點(diǎn)構(gòu)成的復(fù)雜應(yīng)用。為了更好的管控復(fù)雜的軟件系統(tǒng),“可觀測(cè)性”工具正在變得越來(lái)越重要。“可觀測(cè)性”工具構(gòu)建的基礎(chǔ)是可觀測(cè)性數(shù)據(jù),可觀測(cè)性數(shù)據(jù)一般包括如下部分:鏈路追蹤 Trace、日志 Logging、時(shí)序 Metrics、代碼級(jí) Profiling、事件 Event 和 元數(shù)據(jù)相關(guān)的 CMDB 等。
為了幫助大家對(duì)可觀測(cè)性工具有一個(gè)更直觀的感受,這里用一個(gè)例子來(lái)闡述如何基于可觀測(cè)性工具來(lái)解決工作中的實(shí)際問題:某值班人員收到告警通知服務(wù)的失敗率正在上升,點(diǎn)擊關(guān)聯(lián)到錯(cuò)誤指標(biāo)對(duì)應(yīng)的 Trace,在 Trace 中定位到錯(cuò)誤的源頭,在源頭查看到關(guān)鍵的異常日志和代碼棧,并發(fā)現(xiàn)源頭報(bào)錯(cuò)服務(wù)正在執(zhí)行一個(gè)變更操作,于是基本定位到此變更很可能就是導(dǎo)致此故障的原因。有了高質(zhì)量的可觀測(cè)性數(shù)據(jù)和工具,一個(gè)對(duì)此系統(tǒng)并不是非常熟悉的值班人員,就可能快速地完成此次故障的排查與止損。
分布式鏈路追蹤(Trace) 是可觀測(cè)性系統(tǒng)的其中一個(gè)組件。狹義上講 Trace 是對(duì)單次請(qǐng)求的明細(xì)追蹤,記錄請(qǐng)求在各環(huán)節(jié)上的調(diào)用關(guān)系,耗時(shí),以及各類明細(xì)標(biāo)簽與事件。同時(shí) Trace 還有一個(gè)角色是各類可觀測(cè)性數(shù)據(jù)的鏈接紐帶,即同一個(gè) Request Context 的數(shù)據(jù)載體,分布式請(qǐng)求上的各類信息(Metrics/Logs..)通過(guò) Trace 實(shí)現(xiàn)了可靠關(guān)聯(lián),進(jìn)而可以構(gòu)建各類可觀測(cè)性數(shù)據(jù)的上卷下鉆的跳轉(zhuǎn)功能。
2.2 字節(jié)鏈路追蹤系統(tǒng)
字節(jié)鏈路追蹤系統(tǒng)經(jīng)歷了數(shù)年的發(fā)展,現(xiàn)已覆蓋公司絕大部分在線業(yè)務(wù)。整體發(fā)展歷程如下:
2019: Trace 1.0 完成了 Trace 組件能力的構(gòu)建。
2020: Trace 2.0 實(shí)現(xiàn)了 Metrics/Trace/Log 的埋點(diǎn)一體化,對(duì)數(shù)據(jù)協(xié)議與技術(shù)架構(gòu)進(jìn)行了升級(jí),并開始構(gòu)建一站式觀測(cè)平臺(tái) Argos。
2021: 與字節(jié)絕大部分主流框架組件實(shí)現(xiàn)了默認(rèn)集成,全司各業(yè)務(wù)線微服務(wù)覆蓋度 > 80%。
2022: 構(gòu)建與探索場(chǎng)景化、智能化的場(chǎng)景,例如本分享聊的“鏈路分析”。
字節(jié)鏈路追蹤系統(tǒng)當(dāng)前的現(xiàn)狀數(shù)據(jù)(2022 年 10 月):
覆蓋面: 5 萬(wàn)+ 微服務(wù) /FAAS 數(shù),300 萬(wàn)+ 容器實(shí)例數(shù)。
使用量: 日 UV 6 千+ ,日 PV 4 萬(wàn)+。
吞吐量: Span 數(shù) 2 千萬(wàn)+/s (默認(rèn) 0.1% 采樣)。
資源配比: 100+ CPU cores 支撐 100 萬(wàn) Span/s。
SDK 性能: 單線程 40w Span/s。
查詢性能: TraceID 點(diǎn)查 P50 < 100 ms, P99 < 500 ms。
數(shù)據(jù)產(chǎn)生到可檢索時(shí)延: AVG < 1 分鐘,P99 < 2 分鐘。
存儲(chǔ)資源: 10 PB (3 副本 TTL 15 天)。
字節(jié)鏈路追蹤系統(tǒng)從數(shù)據(jù)接入側(cè)、消費(fèi)存儲(chǔ)側(cè)、到查詢平臺(tái)側(cè)的整體架構(gòu)如下圖所示,更多細(xì)節(jié)可閱讀之前的??分享??,上一次分享較為詳細(xì)的介紹了如何從零到一構(gòu)建一個(gè)分布式鏈路追蹤系統(tǒng)。本文主要聊鏈路追蹤系統(tǒng)中的鏈路聚合計(jì)算分析部分。
三. 鏈路分析技術(shù)實(shí)踐
3.1 需求場(chǎng)景
經(jīng)常使用 Trace 的同學(xué)對(duì) Trace 的印象可能是通過(guò) TraceID 或者某些 Tag 檢索出一條或者一些 Trace,然后從 Trace 數(shù)據(jù)中仔細(xì)查看明細(xì)的調(diào)用軌跡和各種 Tag 來(lái)分析一些具體問題,比如一個(gè)請(qǐng)求為什么慢,或者一個(gè)請(qǐng)求為什么出錯(cuò)了。
但是我們還面臨著一些更高層級(jí)的問題,例如,面對(duì)一個(gè)不斷變化的復(fù)雜微服務(wù)系統(tǒng):
- 穩(wěn)定性:緊急狀況時(shí),哪些服務(wù)可以被降級(jí),哪些服務(wù)必須被保障?高風(fēng)險(xiǎn)的易故障點(diǎn)在哪里??
- 流量/容量:如果某頁(yè)面的 PV 要增加10倍,哪些服務(wù)需要擴(kuò)容?需要擴(kuò)容多少??
- 成本性能:哪里存在明顯的性能反模式?哪里存在架構(gòu)不合理帶來(lái)的性能浪費(fèi)??
這些問題的答案靠人工去一條一條看 Trace 難以得到可靠結(jié)果。但是卻可以從大量的 Trace 數(shù)據(jù)中自動(dòng)化地計(jì)算出來(lái),為最終決策提供可靠的數(shù)據(jù)支持。我們把這種對(duì)大量 Trace 的聚合計(jì)算叫做 鏈路分析。
3.2 基本原理
鏈路分析的基本原理就是對(duì)大量的 Trace 進(jìn)行聚合計(jì)算,一般遵循 MapReduce 計(jì)算模型,過(guò)程中可能會(huì)結(jié)合一些訂閱規(guī)則和其他數(shù)據(jù),得到計(jì)算結(jié)果,然后應(yīng)用到具體的場(chǎng)景化應(yīng)用中去。
3.3 技術(shù)架構(gòu)
適合對(duì)大量鏈路數(shù)據(jù)進(jìn)行聚合計(jì)算的可選模式主要有三種,分別是從基于在線數(shù)據(jù)流的流式計(jì)算、從在線存儲(chǔ)中查詢有限條 Trace 然后進(jìn)行的即興(抽樣)計(jì)算,以及基于離線數(shù)倉(cāng)的離線計(jì)算。這三種計(jì)算模式的特性分析如下表所示。
計(jì)算方案 | 優(yōu)點(diǎn) | 缺點(diǎn) |
流式計(jì)算 | - 近實(shí)時(shí)的分析結(jié)果 | - 無(wú)法對(duì)任意時(shí)段任意條件的數(shù)據(jù)進(jìn)行計(jì)算 |
即興(抽樣)計(jì)算 | - 可對(duì)任意時(shí)段任意條件的數(shù)據(jù)發(fā)起分析并快速獲取結(jié)果 | 只能對(duì)抽樣的有限條 Trace 進(jìn)行計(jì)算,數(shù)據(jù)完整性較低 |
離線計(jì)算 | - 數(shù)據(jù)完整性和準(zhǔn)確度高 | - 小時(shí)級(jí)或天級(jí)的延遲的分析結(jié)果 |
分析完了三種聚合計(jì)算模式的特性后,再分析下鏈路分析場(chǎng)景所面臨的技術(shù)需求。
需求類型 | 描述 | 此類需求高的場(chǎng)景舉例 | 合適的計(jì)算方案 |
實(shí)時(shí)性需求 | 需要分析最新的數(shù)據(jù)嗎還是可以接受一定的延遲? | 故障歸因 | 即興計(jì)算/流式計(jì)算 |
數(shù)據(jù)完整性需求 | 抽樣一部分?jǐn)?shù)據(jù)計(jì)算能否滿足需求?還是必須對(duì)所有 Trace 計(jì)算才能得到結(jié)果? | 流量估算 | 離線計(jì)算/流式計(jì)算 |
需求即興程度 | 任務(wù)是即興發(fā)起且必須快速拿到結(jié)果的嗎? | 故障歸因 | 即興計(jì)算 |
基于上述分析,我們認(rèn)為并不存在一種計(jì)算模式就能解決所有問題,因此最終選擇的技術(shù)方案是流式,即興,離線一體化的技術(shù)方案:基于統(tǒng)一的基礎(chǔ)數(shù)據(jù)模型和邏輯算子,支持三種不同的計(jì)算引擎,以實(shí)現(xiàn)不同的場(chǎng)景化需求。
在落地此方案的過(guò)程中,我們總結(jié)了一些有益的實(shí)踐經(jīng)驗(yàn):
- 邏輯算子與計(jì)算引擎分離
Trace 本身數(shù)據(jù)結(jié)構(gòu)就較為復(fù)雜,其分析計(jì)算邏輯也往往有一定的復(fù)雜度,算子與引擎分離便于相同邏輯算子應(yīng)用于不同計(jì)算引擎,可以較好地提升研發(fā)效率和代碼可維護(hù)性。例如性能瓶頸分析相關(guān)算法,既可以用于即興計(jì)算,也可以用于離線計(jì)算。
- 自動(dòng)化異常數(shù)據(jù)檢測(cè)與封禁
Trace 數(shù)據(jù)常常會(huì)存在一些數(shù)據(jù)不規(guī)范現(xiàn)象,例如超高維度的接口名,導(dǎo)致聚合后的數(shù)據(jù)維度遠(yuǎn)超預(yù)期,影響計(jì)算任務(wù)的穩(wěn)定性。自動(dòng)化的異常數(shù)據(jù)發(fā)現(xiàn)與封禁或降級(jí)機(jī)制能起到較好的保護(hù)作用。
- 保留原始樣本提高可解釋性
盡量保留聚合分析結(jié)果對(duì)應(yīng)的代表原始(極值)Trace 樣本,可以提升分析結(jié)果的可解釋性和用戶信任度。
- 配備訂閱和降級(jí)機(jī)制
大數(shù)據(jù)量的計(jì)算成本較高,非基礎(chǔ)功能可采用按需訂閱模式以提升 ROI;建設(shè)對(duì)任務(wù)進(jìn)行靈活降級(jí)的能力,資源緊張的情況下優(yōu)先保障高頻基礎(chǔ)功能的高可用。
四. 鏈路分析落地場(chǎng)景
介紹完鏈路分析的底層技術(shù)架構(gòu)后,我們來(lái)介紹一些具體的落地場(chǎng)景。
4.1 精準(zhǔn)鏈路拓?fù)溆?jì)算
鏈路分析使用最高頻最廣泛的場(chǎng)景當(dāng)屬鏈路拓?fù)涞挠?jì)算。這里說(shuō)的“鏈路拓?fù)洹笔侵篙斎肴我庖粋€(gè)服務(wù)節(jié)點(diǎn)即可獲取流經(jīng)此節(jié)點(diǎn)的所有 Trace 的聚合路徑,從而清晰的得知此服務(wù)節(jié)點(diǎn)的上下游依賴拓?fù)潢P(guān)系。
由于字節(jié)的微服務(wù)數(shù)目極多且有各類中臺(tái)和基礎(chǔ)服務(wù),調(diào)用關(guān)系較為復(fù)雜,因此我們做拓?fù)溆?jì)算的目標(biāo)是:
- 精準(zhǔn):只會(huì)檢索到與被檢索節(jié)點(diǎn)有直接流量的拓?fù)涔?jié)點(diǎn)
- 靈活:可以按照任意節(jié)點(diǎn)(非僅入口),不同深度,不同粒度(服務(wù)/接口/集群/機(jī)房)進(jìn)行拓?fù)錂z索
- 實(shí)時(shí):nice to have
舉例說(shuō)明什么是精準(zhǔn)性需求:如下圖所示,“抖音.X” 和 “火山.Y” 都調(diào)用了 “中臺(tái).Z”,但是對(duì)于 “抖音.X” 的流量 “中臺(tái).Z” 會(huì)使用 “Redis.抖音”,而對(duì)于 “火山.Y” 的流量 “中臺(tái).Z” 會(huì)使用 “Redis.火山”,因此實(shí)際上 “抖音.X” 和 “Redis.火山” 是沒有直接依賴關(guān)系的。那么當(dāng)我們檢索 “抖音.X” 時(shí)希望得到的拓?fù)涫?[“抖音.X”, “中臺(tái).Z”,“Redis.抖音”],而不要包含 “Redis.火山”。
舉例說(shuō)明什么是靈活性需求:如下圖所示,不僅可以按照入口來(lái)檢索拓?fù)?,也可以按照中間節(jié)點(diǎn) “中臺(tái).Z" 或者是存儲(chǔ)組件節(jié)點(diǎn) "Redis.抖音" 來(lái)檢索拓?fù)?;不僅可以按照服務(wù)+接口粒度來(lái)檢索拓?fù)?,也可以按照服?wù)粒度、服務(wù)+集群粒度、服務(wù)+機(jī)房粒度等其他粒度來(lái)檢索拓?fù)洹?/p>
面對(duì)這樣的技術(shù)需求,我們研究了業(yè)界現(xiàn)有的一些拓?fù)溆?jì)算方案:
- 方案一:也是開源主流方案,聚合單跳調(diào)用關(guān)系,檢索拓?fù)鋾r(shí)將單跳的調(diào)用關(guān)系進(jìn)行組裝。此方案簡(jiǎn)單,低成本,但是精度較低,對(duì)于中小型的微服務(wù)系統(tǒng)是可以的,但是對(duì)于字節(jié)場(chǎng)景,例如上述例子中希望用 “抖音.X” 檢索拓?fù)鋾r(shí)希望不要看到 “Redis.火山” 的需求則無(wú)法滿足。
- 方案二:由復(fù)旦 & Ebay 分享,將 Trace 按照 Path 進(jìn)行分組聚合,每個(gè)服務(wù)節(jié)點(diǎn)對(duì)應(yīng)一組 Path。檢索時(shí)首先檢索到服務(wù)對(duì)應(yīng)的 PathID 列表,然后再根據(jù) PathID 檢索出 Path 路徑聚合成拓?fù)洹4朔桨妇茸罡?,可以清晰的梳理出每個(gè)服務(wù)節(jié)點(diǎn)對(duì)應(yīng)的所有調(diào)用路徑,但是在字節(jié)的實(shí)際場(chǎng)景中,我們發(fā)現(xiàn) Path 膨脹非常嚴(yán)重,一個(gè)服務(wù)節(jié)點(diǎn)動(dòng)輒成千上萬(wàn)的 Path,成本高檢索慢,難以滿足字節(jié)場(chǎng)景的實(shí)際需求。
結(jié)合字節(jié)場(chǎng)景的實(shí)際需求,平衡精度、成本和檢索速度,最終我們?cè)O(shè)計(jì)了一種新的方案。
- 方案三:為每個(gè)節(jié)點(diǎn)計(jì)算出一張拓?fù)鋱D,存儲(chǔ)載體選擇圖數(shù)據(jù)庫(kù)。圖數(shù)據(jù)庫(kù)的一個(gè)點(diǎn)對(duì)應(yīng)一個(gè)服務(wù)節(jié)點(diǎn),圖數(shù)據(jù)庫(kù)的一條邊對(duì)應(yīng)一個(gè)["所屬拓?fù)?,“源節(jié)點(diǎn)”,“目標(biāo)節(jié)點(diǎn)”]三元組。在上述例子中,有這樣一些邊:
所屬拓?fù)?br> | 源節(jié)點(diǎn) | 目標(biāo)節(jié)點(diǎn) | 上圖中對(duì)應(yīng)標(biāo)注顏色 |
抖音.X | 抖音.X | 中臺(tái).Z | 藍(lán)色 |
抖音.X | 中臺(tái).Z | Redis.抖音 | 藍(lán)色 |
火山.Y | 火山.Y | 中臺(tái).Z | 黃色 |
火山.Y | 中臺(tái).Z | Redis.火山 | 黃色 |
中臺(tái).Z | 抖音.X | 中臺(tái).Z | 綠色 |
中臺(tái).Z | 火山.Y | 中臺(tái).Z | 綠色 |
中臺(tái).Z | 中臺(tái).Z | Redis.抖音 | 綠色 |
中臺(tái).Z | 中臺(tái).Z | Redis.火山 | 綠色 |
- 當(dāng)需要檢索“抖音.X”對(duì)應(yīng)拓?fù)鋾r(shí),首先定位到圖數(shù)據(jù)庫(kù)中“抖音.X”對(duì)應(yīng)的點(diǎn),然后以此為起點(diǎn)發(fā)起圖的遍歷搜索,找到所有滿足“所屬拓?fù)?抖音.X”的邊(即圖中所有藍(lán)色的邊),得到了“抖音.X”所對(duì)應(yīng)的拓?fù)錇閇"抖音.X", "中臺(tái).Z", "Redis.抖音"]。
- 這個(gè)方案精度能夠滿足需求,成本相對(duì)折中,同時(shí)很好的利用了圖數(shù)據(jù)庫(kù)的特性,可以實(shí)現(xiàn)非常高效的拓?fù)洳樵?。同時(shí),由于鏈路拓?fù)涞臄?shù)據(jù)完整性需求較高,對(duì)實(shí)時(shí)性有一定的需求,因此我們使用了流式計(jì)算引擎來(lái)支持鏈路拓?fù)涞挠?jì)算,大致流程如下圖所示。
精準(zhǔn)鏈路拓?fù)涞膽?yīng)用場(chǎng)景比較廣,這里舉一些具體的例子:
- 全鏈路實(shí)時(shí)觀測(cè):實(shí)時(shí)觀測(cè)拓?fù)涓鞴?jié)點(diǎn)的流量/延遲/錯(cuò)誤率/資源使用率/告警/變更等,快速?gòu)娜溌芬暯谦@取整體狀態(tài)信息。
?
- 混沌演練:為故障演練提供鏈路依賴底圖,生成演練計(jì)劃,對(duì)全鏈路各個(gè)環(huán)節(jié)進(jìn)行故障注入,收集與驗(yàn)證系統(tǒng)的反應(yīng)得到演練報(bào)告。
- 壓測(cè)準(zhǔn)備: 提前梳理壓測(cè)流量將會(huì)流經(jīng)的節(jié)點(diǎn),讓相關(guān)節(jié)點(diǎn)做好壓測(cè)準(zhǔn)備。
- 服務(wù)架構(gòu)治理: 為服務(wù)架構(gòu)治理場(chǎng)景提供上下游依賴梳理依據(jù)。
- 故障歸因: 為故障歸因提供上下游依賴遍歷的底圖數(shù)據(jù)。
4.2 全鏈路流量估算
全鏈路流量估算主要回答的問題是:
- 流量流向哪些下游?如果當(dāng)前節(jié)點(diǎn)的流量增加了 N,那么這些下游節(jié)點(diǎn)的流量會(huì)增加多少?
- 流量來(lái)自哪些上游?如果當(dāng)前節(jié)點(diǎn)的流量增加了 N,那么這些流量是由誰(shuí)帶來(lái)的?占比如何?
全鏈路流量估算是在精準(zhǔn)拓?fù)溆?jì)算的基礎(chǔ)之上實(shí)現(xiàn)的,因此也采用了流式計(jì)算的方式,基于各路徑的 Trace 數(shù)目以及 Trace 所對(duì)應(yīng)的采樣率數(shù)據(jù)進(jìn)行估算。其計(jì)算結(jié)果格式如下圖所示,每張拓?fù)渲械拿織l邊對(duì)應(yīng)一個(gè)估算流量和流量比例。基于這樣的數(shù)據(jù),對(duì)于任意一個(gè)微服務(wù)接口,我們都可以給出上面兩個(gè)問題的答案。
全鏈路流量估算的主要應(yīng)用場(chǎng)景如下:
- 業(yè)務(wù)活動(dòng)擴(kuò)容估算: 業(yè)務(wù)在進(jìn)行大促活動(dòng)前,往往先由產(chǎn)品估算出 DAU 的增量,然后將 DAU 增量轉(zhuǎn)換為一組入口服務(wù)接口的 QPS 增量,進(jìn)而再根據(jù)全鏈路流量比例估算出全鏈路各環(huán)節(jié)的 QPS 增量和擴(kuò)容需求??煽康娜溌妨髁勘壤龜?shù)據(jù)可以為此場(chǎng)景提供很好的輔助支持。
- 成本容量治理: 準(zhǔn)確的全鏈路流量估算數(shù)據(jù),有助于業(yè)務(wù)構(gòu)建更加精細(xì)的成本容量規(guī)劃,促進(jìn)降本增效。
- 流量變化根因分析: 當(dāng)流量發(fā)生預(yù)期外的波動(dòng)變化時(shí),全鏈路流量估算數(shù)據(jù)可以幫助快速分析出波動(dòng)的根因與來(lái)源。
4.3 強(qiáng)弱依賴分析
強(qiáng)弱依賴信息是服務(wù)穩(wěn)定性治理場(chǎng)景的重要數(shù)據(jù)支撐,它也是可以通過(guò)線上的 Trace 數(shù)據(jù)自動(dòng)化地計(jì)算出來(lái)的。
強(qiáng)依賴:異常發(fā)生時(shí),影響核心業(yè)務(wù)流程,影響系統(tǒng)可用性的依賴稱作強(qiáng)依賴。
弱依賴:異常發(fā)生時(shí),不影響核心業(yè)務(wù)流程,不影響系統(tǒng)可用性的依賴稱作弱依賴。
如下圖所示,當(dāng) A 調(diào)用 B 失敗時(shí),如果 A 仍然能成功響應(yīng)其 Client,則 B 是 A 的弱依賴;當(dāng) A 調(diào)用 B 失敗時(shí),如果 A 無(wú)法成功響應(yīng)其 Client,則 B 是 A 的強(qiáng)依賴。
強(qiáng)弱依賴計(jì)算的技術(shù)目標(biāo)包括:
- 準(zhǔn)確性: 盡可能高,尤其是減少“強(qiáng)誤判弱”,提供判定依據(jù)樣本
- 覆蓋度: 盡可能高,盡可能多的為線上存在的調(diào)用關(guān)系給出強(qiáng)弱依賴數(shù)據(jù)
- 粒度: <調(diào)用方服務(wù)接口,被調(diào)方服務(wù)接口>、<場(chǎng)景,調(diào)用方服務(wù)接口,被調(diào)方服務(wù)接口>
- 實(shí)時(shí)性: nice to have
為了盡可能滿足數(shù)據(jù)的完整性和及時(shí)性需求,我們選擇了流式計(jì)算模式,從數(shù)據(jù)流中選擇帶 Error 的 Trace 進(jìn)行強(qiáng)弱依賴關(guān)系計(jì)算。需要注意短期的實(shí)時(shí)數(shù)據(jù)樣本往往不夠,需要結(jié)合歷史累積數(shù)據(jù)共同判定再下結(jié)論。
強(qiáng)弱依賴分析的主要挑戰(zhàn):
- 準(zhǔn)確率: 不同業(yè)務(wù)線判定業(yè)務(wù)穩(wěn)態(tài)的規(guī)則較難統(tǒng)一,需要推動(dòng)業(yè)務(wù)完善數(shù)據(jù)標(biāo)記或規(guī)則錄入。
- 覆蓋率: 部分路徑線上常態(tài)化錯(cuò)誤率極低,較難收集到足夠的錯(cuò)誤樣本,需要配合混沌演練進(jìn)行補(bǔ)充。
強(qiáng)弱依賴分析的主要應(yīng)用場(chǎng)景包括:
- 限流降級(jí)預(yù)案配置指導(dǎo): 強(qiáng)弱依賴數(shù)據(jù)可以回答緊急狀況時(shí)哪些服務(wù)可以被降級(jí),哪些服務(wù)必須被保障的問題。弱依賴可以進(jìn)行限流降級(jí),而強(qiáng)依賴則應(yīng)當(dāng)盡可能的保障高可用。
- 超時(shí)漏斗配置指導(dǎo): 強(qiáng)弱依賴數(shù)據(jù)可以指導(dǎo)業(yè)務(wù)更合理的配置超時(shí)漏斗。如下圖所示,弱依賴配置超時(shí)時(shí)間過(guò)長(zhǎng)是不合理的,可能會(huì)導(dǎo)致不必要的慢請(qǐng)求;如果強(qiáng)依賴配置的超時(shí)時(shí)間過(guò)短也是不合理的,可能會(huì)導(dǎo)致不必要的失敗請(qǐng)求影響用戶體驗(yàn)。
- 輔助自動(dòng)化故障歸因: 準(zhǔn)確的強(qiáng)弱依賴信息,對(duì)自動(dòng)化故障歸因可以起到較好的輔助作用。
- 服務(wù)架構(gòu)治理: 準(zhǔn)確的強(qiáng)弱依賴信息,可以協(xié)助業(yè)務(wù)優(yōu)化架構(gòu),治理不符合預(yù)期的強(qiáng)依賴,提前準(zhǔn)備災(zāi)備方案,提升整體的穩(wěn)定性和高可用。
4.4 全鏈路性能反模式分析
在實(shí)踐的過(guò)程中,我們觀察到有一些非常典型的性能反模式問題是可以從 Trace 數(shù)據(jù)中自動(dòng)化的計(jì)算發(fā)掘,常見的性能反模式包括:
- 調(diào)用放大: 單請(qǐng)求中,大量調(diào)用同一服務(wù)接口。如果在線鏈路中出現(xiàn)了調(diào)用放大比例極高的 case,往往不僅暴露出性能問題,還很可能會(huì)造成穩(wěn)定性風(fēng)險(xiǎn),需要及早治理掉。
- 重復(fù)調(diào)用: 單請(qǐng)求中,多處使用相同 Request 調(diào)用同一個(gè)服務(wù)接口。這種情況常見于基礎(chǔ)信息的重復(fù)獲取,例如多處重復(fù)去請(qǐng)求 user info 或者 device info,是可以進(jìn)行優(yōu)化的。
- 讀寫放大: 單請(qǐng)求中,從底層服務(wù)獲取的數(shù)據(jù)量遠(yuǎn)大于最終返回給client的數(shù)據(jù)量。這種情況常見于濫用重接口獲取輕信息,例如調(diào)用重接口請(qǐng)求了 user 的所有信息,卻只取了 user name 一個(gè)字段。
- 串行循環(huán): 串行循環(huán)特征較為明顯,其形態(tài)一般如下圖所示,一般可優(yōu)化為并行或批量調(diào)用。
性能反模式問題的發(fā)掘還有如下兩個(gè)需求:
- 優(yōu)先發(fā)現(xiàn)極值問題并提供 worst case 樣本
- 優(yōu)先發(fā)現(xiàn)高流量+核心鏈路上的反模式問題
因此性能反模式的分析任務(wù)需要自動(dòng)化發(fā)現(xiàn)最嚴(yán)重的那些反模式問題,給出極值樣本,并且關(guān)聯(lián)出這些問題所在路徑的流量和入口優(yōu)先級(jí),從而幫助業(yè)務(wù)對(duì)服務(wù)進(jìn)行延遲優(yōu)化和成本優(yōu)化,及早解決掉相關(guān)的潛在穩(wěn)定性風(fēng)險(xiǎn)。
4.5 全鏈路性能瓶頸分析
單請(qǐng)求的分布式 Trace 視圖清晰直接,但是局限性在于觀察者無(wú)法確定單請(qǐng)求所呈現(xiàn)出的 Trace Pattern 是普遍現(xiàn)象還是特殊現(xiàn)象。因此從大量的 Trace 數(shù)據(jù)中分析鏈路性能瓶頸,從而識(shí)別出整體性能 Pattern 和 worst case 樣本也是鏈路分析的一個(gè)需求場(chǎng)景。
從批量 Trace 中聚合計(jì)算出鏈路性能 Pattern,既有即興模式的需求,也有離線模式的需求。即興模式下可以滿足對(duì)任意時(shí)段、靈活條件(各類tag,耗時(shí)區(qū)間)篩選批量 Trace 并快速獲取分析結(jié)果的需求。離線訂閱模式下可以滿足更完整的對(duì)全量 Trace 數(shù)據(jù)的整體性能模式分析需求,并觀察長(zhǎng)期變化趨勢(shì)。因此我們會(huì)將鏈路性能分析聚合算子復(fù)用在即興和離線兩種計(jì)算模式下。
分析結(jié)果示例:
4.6 錯(cuò)誤傳播鏈分析
單條 Error Trace 可以觀察出一條錯(cuò)誤傳播路徑,但是觀察者無(wú)法確認(rèn)一條錯(cuò)誤傳播路徑是否一定代表了普遍問題,也無(wú)法回答錯(cuò)誤傳播的影響面如何。因此聚合大量的 Error Trace 去分析整體的錯(cuò)誤來(lái)源、傳播路徑和影響面也是鏈路分析的一個(gè)需求場(chǎng)景。
和鏈路性能分析類似,從批量 Trace 中聚合計(jì)算出錯(cuò)誤傳播路徑,既有即興模式的需求,也有離線模式的需求。我們也會(huì)將錯(cuò)誤傳播鏈分析算子應(yīng)用在即興和離線兩種計(jì)算模式下。即興模式可以滿足對(duì)任意時(shí)段、靈活條件(各類tag)篩選批量 Error Trace 并快速獲取聚合分析結(jié)果的需求。離線訂閱模式則可以滿足更完整的對(duì)全量 Error Trace 數(shù)據(jù)的聚合分析需求,并觀察長(zhǎng)期變化趨勢(shì),輔助業(yè)務(wù)進(jìn)行長(zhǎng)期的穩(wěn)定性優(yōu)化工作。
分析結(jié)果示例:
五. 小結(jié)與展望
本文主要介紹了在完成了從零到一的鏈路追蹤基礎(chǔ)能力的構(gòu)建之后,如何對(duì)海量的鏈路數(shù)據(jù)進(jìn)行聚合分析來(lái)回答更高層面的場(chǎng)景化問題。分享了我們的具體技術(shù)選型過(guò)程和落地的技術(shù)架構(gòu),以及一些較為成功的落地案例。
最后分享后續(xù)的一些展望:
- 數(shù)據(jù)質(zhì)量持續(xù)建設(shè): 數(shù)據(jù)質(zhì)量對(duì)于鏈路數(shù)據(jù)分析的結(jié)果優(yōu)劣起到極其重要的作用。不斷完善業(yè)務(wù)語(yǔ)義規(guī)范,推進(jìn)各層面接入覆蓋會(huì)是我們后續(xù)持續(xù)投入的工作。
- 場(chǎng)景化: 開放能力持續(xù)建設(shè),沉淀業(yè)務(wù)知識(shí)和專家經(jīng)驗(yàn),打磨業(yè)務(wù)最佳實(shí)踐。
- 智能化: 基于數(shù)據(jù)+知識(shí)+算法,持續(xù)提升應(yīng)對(duì)故障歸因、穩(wěn)定性優(yōu)化、性能成本優(yōu)化等場(chǎng)景的能效。
- 擁抱云原生 : 完善 OpenTelemetry 接入,打磨基礎(chǔ)組件,更好的適應(yīng)各類云上場(chǎng)景。
六. 加入我們
我們是字節(jié)跳動(dòng)-基礎(chǔ)架構(gòu)-應(yīng)用觀測(cè)(服務(wù)端)團(tuán)隊(duì),專注于 PB 級(jí)別海量數(shù)據(jù)的可觀測(cè)性基礎(chǔ)設(shè)施(Metrics、Tracing、Logging、Event、Profiling)和上層可觀測(cè)性應(yīng)用(E.g. 報(bào)警生命周期管理、異常檢測(cè)、根因分析)的建設(shè),為字節(jié)跳動(dòng)整體業(yè)務(wù)的穩(wěn)定性、性能優(yōu)化、服務(wù)治理等方向保駕護(hù)航。