Facebook Canopy 初探
原創宣告 :本文系作者原創,謝絕個人、媒體、公眾號或網站 未經授 權 轉載,違者追究其法律責任。
Google Dapper
首先簡單回顧一下 Google 的 Dapper,2010 年 Google 釋出 Dapper 的論文系統闡述了在複雜的、大規模分散式叢集環境下如何進行系統的跟蹤以及問題的分析與定位。通過產生一個全域性唯一的 traceId 以及用 span、annotation 核心資料模型把相關呼叫組成一個完整的呼叫樹。關於 Dapper 如何做低消耗、應用級透明等細節,可以參考 Dapper 的論文。這裡主要是簡單回顧一下其核心思想,因為後續出現的分散式跟蹤產品包括本文要分析的 Facebook 的 Canopy 都有受其啟發。此文是基於2017年 Facebook 釋出的 Canopy 論文,分析其如何進行分散式跟蹤以及問題分析定位。
Span在 Dapper 跟蹤樹種短暫的關聯關係
圖片出自 Google Dapper[1]
背景介紹
TMM
在 Canpoy 產品前,Facebook 有一個產品叫 TMM(The Mystery Machine),在其 2014 年的論文中有具體描述,簡單看一下其架構如下:
將 trace 資料儲存到 Hive、Scribe 中,然後通過 Hadoop 去跑 job 去分析計算其 trace 模型。從 1.3M 條 trace 資料中分析計算出相關模型需要 2 個小時,分析還是依賴離線計算能力上,實時性沒有那麼強。
Canopy
在網際網路分散式環境下,每一個系統在其特定場景下都有其特殊性,各自的模型都有其不同點,無法繼承如 RPC 場景、Event Loop、瀏覽器頁面載入、Mobile App 等,如果為某些場景定製化,會面臨這些場景的迭代開發時間長。
另一方面一些效能分析工具不能跨系統進行分析,需要掌握每一種場景下應該使用什麼樣的分析工具以及相關資料之間的對映關係。每一種工具都有其開發週期,部署時間較長。基於此 Facebook 設計開發 Canopy 的出發點很明確主要是進行單個或跨系統間效能問題的定位,對一些問題分析的推測進行快速驗證。
Canopy 於 2015 年開始在生產環境投入使用,每天產生和處理 13 億資料量,整個產品是作為替換 TMM 在進行演進。
示 例
首先通過一個分析診斷問題的示例來看一下 Canopy 是如何去定位問題的。在此之前,先簡單說下 Facebook 頁面顯示的一些技術點。Facebook 顯示的一個完整的頁面是有很多由不同團隊開發的 page pieces 組成。Facebook 的核心框架會將它們進行合併在 web servers 和使用者的瀏覽器端執行。為了優化使用者體驗,會用到一種 Early Flush 技術。Early-Flush 是服務端的一種優化技術手段,實現預測客戶端需要的資源,批量傳送給客戶端。
問題描述,Facebook.com 在顯示某個頁面的初始化平均響應時間增加了300ms,如 a) 圖顯示:
圖片出自 Facebook Canopy[2]
通過頁面載入延時看到其延時增加 300ms,但沒法定位到具體的某部分導致其增加,在此基礎上進行進一步的拆解分析,如 b) 圖顯示:
圖片出自 Facebook Canopy[2]
從圖分析服務後端的 server 以及網路相關延時都沒有發生變化,但瀏覽器執行時間以及資源 (css,js 等) 的獲取時間增加了。 很自然接下來去分析資源載入這塊的問題如 c) 圖所示:
圖片出自Facebook Canopy[2]
頁面初始化顯示需要的資源發現 css 的資源下降了 5%,同時發現 Early-Flush 圖有一次 miss,導致 css 額外載入了 10KB 的資料,如 d) 圖所示:
圖片出自 Facebook Canopy[2]
通過這些 metrics 已經知道問題所在(Early-Flush 沒有命中),但還不知道具體是哪一部分導致,所以進行進一步的拆解,按 page pieces 進行分組,找到 root cause 是 UserInput 部分導致資源的載入如 e) 圖所示:
圖片出自 Facebook Canopy[2]
分析 UserInput 因增加的新的功能有變動,需要一些新的資源,但 Early-Flush 元件並不知道其發生了變更,從而沒有達到的優化的效果,通過調整 Early-Flush 相關配置,效能問題從而解決。這是一個很常見的因相關配置沒有進行修改而導致效能問題的 case,但往往這種問題很難發現定位到。
圖片出自 Facebook Canopy[2]
挑 戰
從上面的示例中可以看出,後面需要很豐富、詳細的 trace 以及 metrics 資料進行分析、拆解。挑戰主要體現在如下幾個方面:
-
Trace資料的模型
直接操作海量的基本的效能資料是非常笨重的,擴充套件上也不太可能。工程師和使用的工具都必須理解底層的事件資料與各元件高層次(High level)的資料之間的對映關係。但如果建立一個高層次的固化的模型又會帶來問題:已經存在的元件,已經未來新的元件,以及三方的元件的如何支援進來。如果用多種執行模型,效能資料粒度以及質量存在大幅度變化,效能資料多樣化,無法統一。因此 trace 模型的如何管理非常關鍵。在 Dapper 中 Span 來表示樹形層次關係,在模型方面 Dapper 用 Span 來表示樹形層次
-
資料的分析
在資料量大的情況下提供從多特徵角度進行切分、分組、過濾、組合及彙總 trace 資料
-
滿足通用以及個性化需求
對於一些常用場景的一般的用法支援的情況下,具備支援個性化需求的能力來滿足不同場景的需求。
設 計
這部分主要看 Canopy 是如何設計去滿足以及迎接這些挑戰。
Pipeline
通過管道機制,從系統生成的跟蹤資料中提取效能資料。在管道的每一個階段,給使用者的提供定製能力,並且各個元件之間的關注點是隔離的,這樣可以進行彼此的演進而不互相影響。
Canopy 的 trace 資料的收集的思路和 Dapper 類似,也是基於一些通用的元件進行 instrument,產生一個 traceId,然後在各個元件中進行傳遞,產生相關的事件,Canopy Event 會在後續介紹。
圖片出自 Facebook Canopy[2]
產生的事件會已上報進行收集處理,以下是其主要處理流程
圖片出自 Facebook Canopy[2]
④ 事件中帶有執行過程中的相關效能資料以及依賴(因果)關係資料
⑤ 收到資料在記憶體中進行聚合
⑥ 落地儲存
⑦ 如果一個請求的所有事件收齊,然後就排隊處理,在 Canopy 中所有和跟蹤相關資料都已事件方式上報,需要確保一次完整的鏈路資料已經收齊
⑧ 把 trace event 事件對映成 trace model,因為 trace 事件中包含了相關資料能以此進行模型的重構
⑨ 執行 feature 表示式,從已經模型化的 trace中抽取計算需要的特徵資料,從這塊可以支援一些定製化的需求
⑩ 表示式中通過dataset配置繫結自己感興趣的過濾掉自己不需要的 trace,以及資料的輸出配置
⑪ 自己查詢 dataset,或檢視檢視和 Dashboard
⑫ 除了可以自定義 dataset,也提供了共享的(通用)dataset,一些通用的high-level特性進行查詢檢視以及 Dashboard,以及一些工具用下鑽分析。
以上介紹了 Canopy 的主體流程,通過 Canopy 的 events 把所有 trace 資料進行上報儲存,在 Instrumentation API 層都是基於 events 攜帶需要的 trace 資訊,而沒有特定的資料模型進行封裝,而在資料收集後可以進行很靈活的模型重建以及資料的抽取。
下面來看起各個相關點的設計。
Instrumentation APIs
主要職責
-
產生 traceId,並負責傳遞
-
記錄請求相關的結構層次(e.g. 何時何地,執行緒和元件因果關係,網路通訊)
-
收集有用的效能資料
解耦設計
-
特定的 Instrumentation 任務應該訪問有限的 API,這樣降低接入門檻減少出錯,產生一些不正常的 trace 資料
-
訪問這些有限的 API (封裝好相關邏輯),產生的資料相比自己去構建資料更健壯
-
從多個角度捕獲效能相關的資料,而不會破壞已經存在的邏輯。這樣可以很好的支援自定義需求的設計以及與第三方包的整合
Trace Event
Trace Event
Canopy中的 event 結構資訊:
圖片出自 Facebook Canopy[2]
Event type 可擴充套件,會根據 type 來做不同的處理,sequenceNumber 和 timestamp 主要用於將同一個程序或執行緒中的 event 排序,EventId(RandomId) 用於關聯其他有關係的 event。會在傳送方記錄 eventid,traceId 和 eventid 都會透傳給接收方,在接收方會記錄傳送者的 eventid。
Modeled Traces
根據 event 來構建 Modeled Trace,效能資料 High-Level 表現形式,隱藏了底層日誌事件的不一致性。
型別
-
Execution units:執行執行緒
-
Blocks:execution unit中計算段(Segments of computation within an execution unit)
-
Points:一個Block中即時發生的events
-
Edge:points間的因果關係
可以表示程序間或機器間的因果關係也可用於表示同一程序中的execution units或blocks。非常適合以下模式
長時間執行的執行單元間的流,雙向通訊,應用級別block依賴
Trace Datasets
-
Trace 資料衍生出來的資料集,囊括了很多Traces資料的資訊
-
效能分析的主要入口點(面向工程師)
-
Feature(trace中一個元素的label或聚合值或一些結構關係) 通過抽取函式(抽取函式是無狀態的且一條trace記錄執行一次)產生
Trace Dataset 表現形式
基於這些豐富或自定義的 trace 資料集來支援一般以及個性化需求。
小 結
本文介紹了 Facebook Canopy 在面對海量 trace 資料以及各種環境下,如何去設計端到端的效能分析產品。縱觀下來,其設計特點是解耦的設計,trace 事件資料沒有繫結到固定的資料模型中,資料處理環節支援靈活的 feature 抽取,形成不同的 trace dataset 資料集來達到不通場景的需求。
參考
[1] Dapper, a Large-Scale Distributed Systems Tracing Infrastructure
[2] Canopy: An End-to-End Performance Tracing and Analysis System


長按二維碼關注我們 ▶▶▶

點選“閱讀原文”獲取招聘資訊