字節跳動觀測數據埋點標準化實踐
背景
隨著字節跳動業務規模不斷擴大,對存量和新增業務的服務質量承諾變得越發關鍵。穩定性治理方面:怎樣支持保障服務線上的高可用性,或者在出現故障/事故時,如何高效且迅速地止損、定位分析影響面已成為一個重要議題。
穩定性建設所涉及的話題十分廣泛,涵蓋流程梳理與標準化、數據標準化、SLO 定義、故障自愈、事故復盤和演練等方面,字節跳動基礎架構可觀測團隊提供的穩定性平臺建設思路是“事前預防、事中處理、事后復盤、事后補救/反哺事前”這四個階段。
其中, 觀測數據標準化以及一系列配套的數據鏈路,如:數據埋點、數據消費、數據存儲、數據查詢、離線數倉等,都是后續穩定性建設的重要數據基石。
并且,由此引申出排障/止損效率的問題,由于字節的服務/基礎設施是分層建設的,包括端側客戶體驗層、網絡接入層、應用服務層、基礎設施層、IDC\資源層等,不同層面的統計/描述口徑是否一致、能否對應,以達到在跨層間能上卷下鉆和平層內過濾聚合的“車同軌書同文”效果,這對于大幅提升整體排查效率, 讓 SRE/GOC 同學能夠自助完成端到端的問題排查就顯得尤為重要。
擁有統一的觀測數據標準, 能夠在很大程度上提升團隊間的排障效率,從人工分析的方式提升至更大程度的自助/自動化排障的階段。
埋點標準化的重要性
提高研發效率 & 降低研發協同成本
- 面向排障方面:跨層間的上下文過濾便捷,術語統一。
- 進行歷史數倉分析(容量優化)時,整體數據處理邏輯的適配成本會大幅降低。
- 用戶的學習曲線陡峭,理解心智負擔沉重。
為 AIOps 提供強有力的數據支撐
觀測數據屬于 AIOps 的五大基石(數據、知識、算法、代碼聯動、人機協同)之一。在清華裴丹老師的《AIOps 落地的 15 條原則》里,也都提及了數據的重要性。
擁有數據標準化和統一的訪問體驗,為后續穩定性的終極目標 MTTR 1-5-10(1 分鐘發現,5 分鐘響應以及 10 分鐘快恢復)提供了數據層面的保障。包括同層數據的聚合 / 過濾,以及跨層數據的下鉆和上卷,都會有統一的使用方式。
名詞解釋
名詞 | 解釋 |
Metrics 2.0 | 字節跳動內部使用廣泛的時序數據處理引擎,提供了時序數據收集、存儲和聚合查詢的功能。2.0 版本提供引入多值概念,打平prometheus 4類指標類型語義、支持秒級打點& 存儲周期定制化等多租戶特性、 端到端高性能優化的分布式時序集群版本。 |
BytedTrace | BytedTrace是字節跳動使用的一套集成了 Tracing/Logging/Metrics 三種能力的可觀測性解決方案,提供了從采集、傳輸、存儲、檢索到前端產品化交互的整套能力。它定義了統一的數據模型(Trace 、Span 、Event、Metrics 等),提供了各語言配套 SDK,并與公司各主流框架組件實現默認集成。 |
觀測埋點 TagKV | Metrics TagKV 是一種用于標記和管理度量數據的鍵值對(Key-Value Pair)格式。通常用于監控系統、分布式追蹤系統和日志管理系統等領域,TagKV 提供了一種靈活且高效的方法來分類和篩選數據。 |
Measurement | 可觀測對象的某個指標,如服務的上游調用延時,物理機的 CPU 使用率。Measurement 是帶有可觀測對象的 context的,是語義化的,同時能識別在不同條件下應該使用哪個版本的指標以及對應的 TagKV。而且可以根據觀測對象的元數據條件,同時關聯多個時序數據源,便于按需時序數據源切換。 |
SLO | Service Level Objectives,服務級目標是指服務提供方對所提供服務的某些性能或質量指標所設定的目標值。這些指標通常用于衡量服務的可用性、性能和其他關鍵屬性,旨在確保服務達到預期的質量水平。 |
TCE | Toutiao Cloud Engine,為字節跳動內部提供的高度可用、彈性擴展的容器服務。 |
PSM | Product Subsys Module,是字節跳動內部服務的唯一標識。 |
GOC | Global Operations Center,基于字節跳動各類研發,運維體系下的高可用產品能力,結合穩定性保障策略及運營機制,提供字節跳動全線基礎產品的可靠性服務與設施穩定性保障,達成字節跳動全線業務各類場景下的端到端高可用性。 |
字節埋點標準化挑戰與拆解思路
挑戰:歷史上可觀測性埋點質量偏低
首先,我們對埋點標準化進行定義,包括但不僅限于如下的標準定義,包括覆蓋完整、定義統一、計量準確、面向引擎友好等四大方面。
簡而言之,在 2020 年以前,從覆蓋完整、定義統一、計量準確、面向引擎友好等維度來看,字節整體的觀測數據埋點存在一定的差距。
具體如下:
負載均衡 埋點
- 計量準確:中等水平
a.存在較嚴重的打點丟失問題
- 面向引擎友好:較低水平
a.指標打點對于配置預計算不友好
b.指標名膨脹也比較嚴重
微服務 埋點
- 覆蓋完整:中等水平
a.20 年前 Tracing 方案還在 V1 版本
- 計量準確:中等水平
a.遇到高基數的指標會被封禁
- 面向引擎友好:較低水平
a.指標打點對于配置預計算不友好
b.指標名膨脹也比較嚴重
c.加權計算也不好實現
語言運行時 埋點
- 定義統一:較低水平
a.Golang & C++ 框架 不同的版本定義的指標格式都不太一樣
- 面向引擎友好:較低水平
a.指標打點對于配置預計算不友好
容器指標 埋點
- 覆蓋完整:較低水平
- 沒有日志采集覆蓋
- 計量準確:中等水平
- 遇到高基數的指標會被封禁
- 面向引擎友好:較低水平
- 指標打點對于配置預計算不友好
基礎架構存儲 & 數據庫 埋點
- 覆蓋完整:較低水平
- 存儲、數據庫、MQ 客戶端沒有黃金指標打點
- 沒有日志采集覆蓋
- 計量準確:較低水平
- 不同存儲、數據庫、MQ 產品打點格式 都不一
- 面向引擎友好:較低水平
a.指標打點對于配置預計算不友好
思路:分層&向后兼容推進埋點標準化
總結來說,之前的字節服務端觀測數據質量大致存在三類問題。
- 同層數據/跨層數據不一致。
- 觀測的多模態數據類型(指標、日志、鏈路)的數據定義不統一。
- 觀測數據格式對引擎不夠友好,例如所有數據都在 default 租戶的一個大倉里,再比如很多觀測指標的定義對于預計算不友好。
針對上述問題,我們采取了如下的多個思路逐一進行解決。
實施思路
一方面,在埋點側就盡可能統一埋點 TagKV 定義,而且平臺級 TagKV 都通過環境變量或者請求上下文自動注入對應的 Tag Value, 以防止由業務手工注入帶來的人工錯誤。
另一方面,對于指標、鏈路和日志侵入式 SDK,我們通過字節內部的遠程過程調用框架以及存儲、數據庫、消息中間件的客戶端 SDK 搭載嵌入中間件,對于業務來說,能相對透明地升級到最新特性的版本。另外, 對于遠遠低于 SDK 基線版本的服務, 我們也通過字節軟件供應鏈安全治理平臺通過編譯卡點的不同程度[warning 提示/發布卡點]推動業務升級。
在 負載均衡、應用、中間件、存儲計算組件等各個縱向方面, 我們也主動與對應的平臺對接,推動指標、日志、鏈路的埋點注入。
最后,在指標埋點上也額外關注對于多租戶的聲明,以達到一定的分庫分表功能,以及多值聲明,以最大程度減少數據消費和存儲成本。如下所示, 就是團隊在各個不同觀測對象的埋點方面所做的業務推進情況。
難點:識別和解決
類似觀測數據標準化的工作歷經多年,牽涉的團隊眾多,整個過程并非毫無波折。遇到問題時要解決問題并思考能否將其標準化或者平臺化,同時也要考慮能否盡可能地復用其他團隊的能力和工具來助力我們進一步推廣。當時如何高效地推動業務升級是我們的主要目標。
[業務推進] 高效推動業務升級觀測SDK
在 Metrics SDK 需要升級到基線版本的情況下,以前的做法是在字節軟件供應鏈安全治理平臺上配置版本攔截,提醒用戶升級,但是整體升級效率比較低,我們也無法跟蹤用戶的升級進展。因此我們聯合字節軟件供應鏈安全治理平臺團隊實現 SDK 自動升級功能。
Metrics SDK 自動升級
Metrics SDK 自動升級功能可以自動實現在當前業務代碼庫的代碼提交期間,如果檢測到對應集成的metrics SDK 低于基線版本,則會向用戶推送代碼提交失敗的通知,提醒用戶需要主動升級到metrics SDK基線版本或以上的操作。
遠程過程調用 框架 & 基礎組件客戶端 集成 BytedTrace SDK 集成
觀測團隊多年來持續推動公司的遠程過程調用 框架以及基礎組件客戶端 集成 BytedTrace SDK 。借助字節軟件供應鏈安全治理平臺進行遞進式卡點推廣,依靠代碼血緣平臺來推動框架、組件的基礎庫版本實現升級。在存有流量的微服務上,BytedTrace SDK的覆蓋比例按照 TCE pod 接入情況來計算,當前已達到 95%。
從服務的優先級角度而言,公司當前96% 的 P0 服務中已接入 Bytedtrace SDK 。
[業務推進] 提升基礎組件觀測埋點質量
TCE 調度 / 運行時 打點格式設計思路
前文提到,提升業務層、應用層、容器層等多層間指標的跨層關聯和下鉆能力是指標標準化的一個重要目標,而實現跨層關聯的關鍵動作在于保證同一含義的指標 TagKV 在各層上的定義保持統一,為實現這一點,我們對各個層次上的核心組件進行了統一的設計,具體如下:
層次 | 核心組件/著手點 | 埋點標準化設計思路 |
業務層 | Metrics 2.0 SDK | - 內置統一的平臺級TagKV,提供橫向跨語言、跨服務的TagKV統一 |
應用層 | 運行時 指標、遠程過程調用 指標 | - 橫向上,提供統一的、跨語言的指標名定義 |
- 縱向上,對齊Metrics 2.0 SDK 平臺級TagKV規范 | | 容器層 | 與調度合作,對容器指標采集agent(TCE調度)進行標準化改造 | - 對齊Metrics 2.0 SDK 平臺級TagKV規范 |
- 首先,我們在 Metrics 2.0 SDK 內置定義了一套平臺級 TagKV,這樣所有使用 Metrics 2.0 SDK 的業務打點都會攜帶標準的預定義的 TagKV。這些共同TagKV包括:_cluster、_psm、_pod_name、_ipv4 等。
- 在應用層,挑選了對業務排障、應用觀測常用且通用的兩類指標(運行時、遠程過程調用)進行標準化,目標是在橫向上,提供跨語言、統一的指標名、TagKV語義定義等;在縱向上,對齊 Metrics 2.0 SDK 平臺級 TagKV 規范,以便于跨層關聯。以 運行時 指標為例,其定義規范如下:
a.不同語言的指標采用統一命名約定:runtime. {runtime} . {metric}[ . {field}]
b.不同語言類似含義指標采用統一命名風格:如 go、java 中統計堆對象申請量的指標都命名為memory.allocated_bytes
c.必須包含 Metrics 2.0 SDK TagKV 規范的平臺級 TagKV,如 _psm、_pod_name 等
- 在容器層,與調度團隊共同推動其 TCE 容器指標采集 agent(TCE調度) 的指標標準化改造,指標 TagKV 對齊Metrics 2.0 SDK TagKV 規范。
通過將這些核心組件進行標準化改造,為跨層的指標關聯和下鉆提供了能力基礎。同時,在每個核心組件的指標定義上,我們還通過以下兩個方式進一步提升埋點的性能和成本收益,第一點是對各個組件使用獨立租戶,實現資源的隔離,保障寫入穩定性和查詢性能;
指標 | 租戶名 | 集群類型 |
運行時 | apm.runtime | 獨立集群 |
遠程過程調用 框架 | apm.rpc | 獨立集群 |
TCE 容器指標 | computation.tce | 獨立集群 |
第二點是在語義明確的前提下,盡量使用多值格式定義指標,降低存儲成本。以 TCE調度 指標為例,將原來 mem 相關的四個指標合并為一個多值指標的四個字段,存儲成本大致可以被認為降低至四分之一。
原指標 | 改造后多值指標名 | 改造后多值字段 |
tce.host.mem_total | inf.tce.host.mem | total |
tce.host.mem_free | free | |
tce.host.mem_available | available | |
tce.host.mem_used | used |
[配套工具] 幫助平滑遷移觀測數據
[工具1] 語義化指標替換
我們提供語義化指標替換,稱為Measurement,其能力就是對原始 Metrics 打點的語義化封裝;同時能識別在不同條件下應該使用哪個版本的指標以及對應的 TagKV。這兩個關鍵能力能夠促使在做數據遷移時,觀測大盤和報警基本達到比較平滑的狀態。
原始 Metrics 打點:直接寫入時序數據庫(可以是 metrics \ influxdb \ prometheus)的數據。
語義化封裝:用標準的語義化來包裝原始的 metrics 打點數據。比如 go 服務的 gc 數量的 metrics 打點是 go.{{.psm}}.numGcs,其中{{.psm}}為具體的 psm, 我們會定制一個語義化指標名叫 "runtime.go.gc_num"來表達 go 服務的 gc 數量,包括用統一的 TagKV 來封裝對應的原始 TagKV。不管是 open api 還是前端調用, 都用指標 "runtime.go.gc_num" 對measurement 服務進行調用。
不同條件下的查詢路由:需要這個能力是因為在字節內部原始 Metrics 的打點會不斷的升級, 比如 golang 運行時 歷史上會有 v1 、v2 、v3 多個版本,我們需要能夠在給定的輸入信息條件下去查詢到對應的指標版本。這個判斷條件實現的邏輯一般為可用輸入的 psm 名字構成 Metrics go v1 的指標名,再根據指標名的數據是否存在來判斷是 runtime v1、runtime v2 或者 runtime v3 的版本,指標判斷也以此類推。或者可以通過 psm 的 scm 編譯信息確定該 psm 編譯的 golang 運行時 版本是 v1、v2 或者 v3。通過對應條件的判斷來做到對應數據的查詢路由。
在有了 Measurement 能力后,我們抽象出了 Measurement 服務,該服務作為觀測大盤和報警的一個數據源。在盡量不需要用戶介入的情況下完成數據打點的遷移和替換。
當前借助 Measurement 能力,針對公司的 遠程過程調用、HTTP 等框架,容器引擎、FaaS、機器學習推理等平臺,還有負載均衡、緩存、數據庫、消息隊列等基礎組件,以及golang 運行時 等,均進行了統一的標準化語義封裝,這些語義化封裝在觀測平臺上均有所展現。
[工具2] Metrics 前綴分流
怎樣幫助業務順利地遷移到新租戶,同時確保新老指標的查詢方式均可使用,是我們在推動業務租戶遷移時所面臨的較大挑戰。
針對上述問題,觀測團隊起初推進引導用戶主動遷移至新租戶,旨在實現租戶隔離,提供更優的穩定性保障,進行精細化容量治理以降低成本。然而,后來發現主動遷移的速度太慢,趕不上打點量的自然增長。于是,推出了讓用戶無感知的被動租戶遷移方案。大致思路是依據某些特定的指標前綴,主要涵蓋一級 / 二級前綴,通過特定配置把這些指標分別路由到不同的新租戶,并且在新租戶上支持查詢翻譯,即便用戶不修改查詢租戶,繼續用 Default 租戶查詢仍能正常獲取數據。該方案具有以下優勢:
- 業務在讀寫兩側無需進行代碼變更,就能將流量遷移到新租戶集群。
- 最大程度減少不同租戶間因集群變更和讀寫流量變化對線上穩定性產生的相互影響,提供更出色的穩定性保障。
- 精準對接業務線租戶,便于后續進行打點流量治理、容量規劃以及資源充值等操作。
具體的實現由 Metrics 組件中各模塊的相互配合完成,包括寫入、控制面、查詢、數倉等方面,大致的實現流程如下:
前綴分流租戶的整個過程存在眾多細節,為減少過程中的過多人為操作,防止出現某些環節被遺忘的情況,觀測團隊設計了分流流程工單以及白屏化運維平臺,盡可能讓整個操作流程實現自動化,提高分流租戶的效率。此外,前綴分流遷移新租戶的整個過程對于業務來說成本為零,同時對于 觀測團隊而言不像依賴業務方主動遷移那樣周期漫長,其周期短、生效時間快,能夠收斂團隊人力的持續投入。
總的來說,觀測團隊提供了一種讓用戶無感知、實現無縫遷移新租戶的方案,用戶的核心觀測大盤和報警也無需修改,最大程度降低了埋點標準化對用戶的打擾。
埋點標準化字節的實踐與效果
觀測數據質量前后對比
經過 2020-2022 年推進 BytedTrace SDK 覆蓋率、2023 年推動云基礎組件和應用層指標租戶遷移之后, 從埋點標準化的 4 個維度看,都有不同程度的質量提升。
負載均衡
-計量準確:較高水平 [2020年為中等水平]
- 通過 2.0 SDK 三個特性, 基本消除丟點的問題:
a.打點本地聚合
b.面向字節流的 codec 編碼
c.Agentless 投遞
-面向引擎友好:較高水平 [2020年為較低水平]
- 實現面向預計算友好的效果
-成本收益:
- Metrics 2. 0 打點商品成本相對 1.0 下降 94%
- Metrics 2. 0 很好地解決了打點封禁問題,特別是在一些配置量巨大的核心集群,解決了其超過 90%打點無法查詢的情況
- Metrics2. 0 TLB 機器成本初步統計主容器和 adaptor 打平,同時相對 1.0 節約了 ms2 的 15000 核資源
微服務
-覆蓋完整:較高水平 [2020年為中等水平]
- 80%以上 PSM 覆蓋到 BytedTrace SDK 集成
-計量準確:中等偏上水平 [2020年為中等水平]
- 高基數的指標封禁問題 由于遷移到了新租戶 可以做封禁閾值定制化
- [計劃中] 升級 bytedTrace 內的 metrics 2.0 SDK 降低丟點的風險
-面向引擎友好:較高水平 [2020年為較低水平]
- 實現面向預計算友好的效果
-成本收益:
- 以計算關鍵組件 Consumer 為例,新租戶只需要老租戶 20%的資源,就可以完成相同數據的寫入計算;其他寫入計算類組件也類似
- 以存儲關鍵組件 tsdc 為例,新租戶只需要老租戶 55%的資源,就可以完成數據的寫入、存儲
語言 運行時
- 定義統一:較高水平 [2020年為較低水平]
- 統一了不同語言和框架的 運行時 打點格式
容器指標
-覆蓋完整:中等水平 [2020年為較低水平]
- TCE調度 接入日志租戶
-計量準確:較高水平 [2020年為中等水平]
- 引入多值 降低指標名數量
- 高基數的指標封禁問題 由于遷移到了新租戶 可以做封禁閾值定制化
- 通過 2.0 SDK 三個特性, 基本消除丟點的問題
a.打點本地聚合
b.面向字節流的 codec 編碼
c.Agentless 投遞
-面向引擎友好:較高水平 [2020年為較低水平]
- 實現面向預計算友好的效果
基礎架構 存儲 & 數據庫
-計量準確:較高水平 [2020年為中等水平]
- 引入多值 降低指標名數量
- 高基數的指標封禁問題 由于遷移到了新租戶 可以做封禁閾值定制化
- 通過 2.0 SDK 三個特性, 基本消除丟點的問題
- 打點本地聚合
- 面向字節流的 codec 編碼
-面向引擎友好:中等水平 [2020年為較低水平]
- 打點格式調整的 支持預計算配置
-成本收益:
- 以 mysql 遷移為例
a.Mysql 租戶 成本節省 45.7%
b.Mysql 租戶 帶寬節省了 80%
截止到今年年初, Metrics 在中國國內區域已經接入 60+ 租戶,占總流量的 70% 左右。
賦能效果總結
加速微服務端到端根因定位
通過指標標準化 & 多模觀測數據 [指標, 日志,鏈路]標簽術語的標準化, 我們實現面向微服務的上卷 & 下鉆關聯分析。
也使得使得跨層問題根因分析有了可能性:
目前端到端根因定位覆蓋了60%以上的報警場景,日均觸發根因定位 50余萬 次,用戶對定位結果的正反饋率超過80%。
簡化服務性能離線數倉構建
在實現了在線觀測數據的標準化,并將其導入統一的存儲介質之后,構建字節整體關于服務性能、容量、吞吐量的數倉大盤就更加便捷。比如 展現某服務的單核 QPS 分時熱力圖 如下:
目前基于微服務應用性能數倉已覆蓋公司超97%的微服務量化,有效支持字節跳動各業務線服務性能、服務應用健康度度量,由此帶動一系列精準的成本優化。
觀測底座自身收益
- 從穩定性角度看,由于引入metrics多租戶概念,所以我們能夠通過邏輯租戶映射到物理資源,從而降低故障半徑,減少不同租戶間流量的相互干擾。
- 從成本角度看,我們能夠依據每個租戶的副本數、存儲時長 TTL、打點的最小精度以及多值定義,最大程度地降低寫入流量和存儲容量的成本。metrics 多租戶遷移前后對比,成本節省幅度在 20% ~ 80% 不等。
總結
歷經上述觀測埋點套件 BytedTrace SDK推廣、Metrics 指標標準化遷移和推廣、部分業務接入日志多租戶,字節后端觀測數據的質量在覆蓋完整度、定義統一、計量準確、面向引擎友好四個方面上取得了顯著的質量提升。這也為后續的全景全棧高效排障奠定了堅實的基礎,幫助更多業務團隊在業務穩定性方向持續建設。
依托字節跳動內部可觀測團隊大規模技術實踐,通過內外合力,在火山引擎上推出了應用性能監控全鏈路版(APMPlus)、托管 Prometheus(VMP)、云監控等可觀測產品,致力于為用戶提供全面、智能、高效、易用且安全的全棧可觀測解決方案。
目前 APMPlus Server 端監控已正式 GA 并支持最新的大模型鏈路追蹤相關能力,歡迎咨詢了解。
?? 相關鏈接
APMPlus : www.volcengine.com/product/apmplus
VMP : www.volcengine.com/product/prometheus
云監控 : www.volcengine.com/product/cloudmonitor