BPF 之巔:洞悉 Linux 系統和應用性能

以下內容節選自《BPF之巔:洞悉Linux系統和應用性能》一書!


--正文--

BPF是近年來Linux 系統技術領域一個巨大的創新。作爲 Linux 內核的一個關鍵發展節點,其重要程度不亞於虛擬化、容器、SDN 等技術。

▊ BPF 和 eBPF 是什麼

BPF 是 Berkeley Packet Filter(伯克利數據包過濾器)的縮寫,這項冷門技術誕生於 1992 年,其作用是提升網絡包過濾工具的性能。2013 年,Alexei Starovoitov 向 Linux 社區提交了重新實現 BPF 的內核補丁,經過他和 Daniel Borkmann 的共同完善, 相關工作在 2014 年正式併入 Linux 內核主線。此舉將 BPF變成了一個更通用的執行引擎,其可以完成多種任務,包括用來創建先進的性能分析工具。

精確地解釋 BPF 的作用比較困難,因爲它能做的事情實在太多了。簡單來說,BPF 提供了一種在各種內核事件和應用程序事件發生時運行一段小程序的機制。如果你熟悉 JavaScript,可能會看到一些相似之處 :JavaScript 允許網站在瀏覽器中發生某事件(比如鼠標單擊)時運行一段小程序,這樣就催生了各式各樣基於 Web 的應用程序。BPF 則允許內核在系統和應用程序事件(如磁盤 I/O 事件)發生時運行一段小程序,這樣就催生了新的系統編程技術。該技術將內核變得完全可編程,允許用戶(包括非專業內核 開發人員)定製和控制他們的系統,以解決現實問題。

BPF 是一項靈活而高效的技術,由指令集、存儲對象和輔助函數等幾部分組成。由於它採用了虛擬指令集規範,因此也可將它視作一種虛擬機實現。這些指令由 Linux 內核的 BPF 運行時模塊執行,具體來說,該運行時模塊提供兩種執行機制 :一個解釋器和一個將 BPF 指令動態轉換爲本地化指令的即時(JIT)編譯器。在實際執行之前,BPF 指令必須先通過驗證器(verifer)的安全性檢查,以確保 BPF 程序自身不會崩潰或者損壞內核(當然這不會阻止最終用戶編寫出不合邏輯的程序—那些雖可執行但沒意義的程序)。

目前 BPF 的三個主要應用領域分別是網絡、可觀測性和安全。本書主要關注可觀測性(跟蹤)。

擴展後的 BPF 通常縮寫爲 eBPF,但官方的縮寫仍然是 BPF,不帶“e”,所以在本 書中,筆者用 BPF 代表擴展後的 BPF。事實上,在內核中只有一個執行引擎,即 BPF(擴展後的 BPF),它同時支持擴展後的 BPF 和“經典”的 BPF 程序。

▊ 跟蹤、嗅探、採樣、剖析和可觀測性分別是什麼

這些全都是用來對分析技術和工具進行分類的術語。

跟蹤(tracing)是基於事件的記錄—這也是 BPF工具所使用的監測方式。你可能已經使用過一些特定用途的跟蹤工具。例如,Linux 下的 strace(1),可以記錄和打印系統調用(system call)事件的信息。有許多工具並不跟蹤事件,而是使用固定的計數器統計監測事件的頻次,然後打印出摘要信息 ;Linux top(1) 便是這樣的一個例子。跟蹤工具的一個顯著標志是,它具備記錄原始事件和事件元數據的能力。但是這類數據的數量不少,因此可能需要經過後續處理生成摘要信息。BPF 技術,催生了可編程的跟蹤工具的出現,這些工具可以在事件發生時,通過運行一段小程序來進行定製化的實時統計摘要生成或其他動作。

strace(1) 的名字中有“trace”(跟蹤)字樣,但並非所有跟蹤工具的名字中都帶 “trace”。例如,tcpdump(8) 是一個專門用於網絡數據包的跟蹤工具。(也許它應該被命 名爲 tcptrace ?)Solaris 操作系統有它自己的 tcpdump 版本,稱爲 snoop(1M)(嗅探器);之所以起這個名字,是因爲它是用來嗅探網絡數據包的。筆者先前在 Solaris 系統上開發 和發佈了許多跟蹤工具,在那裏我(有一絲後悔)普遍使用了“嗅探器”來命名那些工具。這也是爲什麼現在會有下面這些工具:execsnoop(8)、opensnoop(8)、biosnoop(8) 等。嗅探、 事件記錄和跟蹤,通常指的是一回事。這些工具將在後面的章節中加以介紹。

除了工具的名稱,“tracing”一詞也經常用於描述將 BPF 應用於可觀測性方面的用途。Linux 內核開發人員尤其喜歡這麼表達。

採樣(sampling)工具通過獲取全部觀測量的子集來描繪目標的大致圖像 ;這也被 稱作生成性能剖析樣本或 profiling。有一個 BPF 工具就叫 profile(8),它基於計時器來對運行中的代碼定時採樣。例如,它可以每 10 毫秒採樣一次,換句話說,它可以每秒採樣 100 次(在每個 CPU 上)。採樣工具的一個優點是,其性能開銷比跟蹤工具小,因爲 只對大量事件中的一部分進行測量。採樣的缺點是,它只提供了一個大致的畫像,會遺漏事件。

可觀測性(observability)是指通過全面觀測來理解一個系統,可以實現這一目標的工具就可以歸類爲可觀測性工具。這其中包括跟蹤工具、採樣工具和基於固定計數器的工具。但不包括基準測量(benchmark)工具,基準測量工具在系統上模擬業務負載,會更改系統的狀態。本書中的 BPF 工具就屬於可觀測性工具,它們使用 BPF 技術進行 可編程型跟蹤分析。

▊ 初識 BCC:快速上手

讓我們直接切入主題,快速上手來看一些工具的輸出吧。下面這個工具會跟蹤每 個新創建的進程,並且爲每次進程創建打印一行信息。這個叫 execsnoop(8) 的工具來自 BCC 項目,它通過跟蹤 execve(2) 系統調用來工作。execve(2) 是 exec(2) 系統調用的一 個變體(也因而得名)。第 4 章會介紹 BCC 工具的安裝,再往後的章節會更詳細地介紹相關工具。

上面的輸出顯示了在執行跟蹤的過程中,系統創建了哪些進程 :其中有些進程運行 時間太短,因而使用其他工具可能無法捕獲到相關信息。在輸出中都能看到大量標準的 UNIX 工具:ps(1)、grep(1)、sed(1)、cut(1) 等。但是在這裏你無法看到這個命令的打印速度。execsnoop(8) 帶上命令行參數 -t 後,會增加一列時間戳輸出 :

上述輸出進行了截斷(用 [...] 表示),但時間戳那列信息還是顯示了一個新的線索 :新進程的批量創建之間有 1 秒的間隔,而且這個模式不斷重複。通過瀏覽輸出可以發現,每秒會批量創建 30 個新的進程,然後停頓 1 秒,繼續批量創建 30 個新的進程。

上述輸出結果取自筆者在 Netflix 公司調查真實性能問題時使用 execsnoop(8) 的過程。這臺服務器的作用是進行微基準測試,但問題是每次基準測試的結果差異很大,影響了可信度。筆者在系統空閒時運行了 execsnoop(8),事實證明並非如我所想!每秒都有很多進程被創建出來,這些進程對基準測試造成了干擾。最終,我們發現,因爲有一個服務的配置不正確,導致它每秒都會被拉起、失敗,然後再被拉起,如此反覆。當把這個 服務徹底禁止之後,就沒有新的進程被創建出來了(同樣可以使用 execsnoop(8) 進行驗 證),基準測試的數值也穩定了下來。

execsnoop(8) 的輸出可以用來輔助支撐一個性能分析方法論:業務負載畫像(workloadcharacterization),本書中涉及的其他 BPF 工具的功能也都支持該方法論。業務負載畫像 方法論其實很簡單,就是給當前業務負載定性。理解了業務負載,很多時候就足夠解決 問題了,這避免了深入分析延遲問題,也不需要進行下鑽分析(drill-down analysis)。在本案例中,業務負載就是這些不斷有進程的創建。

請你嘗試在自己的系統上運行 execsnoop(8),並且讓它運行 1 小時,看看是否有所發現?

execsnoop(8) 會在每個進程創建時打印信息,而其他一些 BPF 工具則可以高效地計 算摘要統計信息。另一個可以快速上手的工具是 biolatency(8),它可以繪製塊設備 I/O(disk I/O)的延遲直方圖。

下面是在一臺生產環境中的數據庫服務器上運行 biolatency(8) 的輸出,該數據庫對 延遲非常敏感,因爲該服務的服務質量目標(service level agreement)只有幾毫秒。

當 biolatency(8) 工具運行時會監測塊 I/O 事件,它們的延遲信息通過 BPF 程序進行 計算和統計。當工具停止執行後(用戶按下 Ctrl+C 組合鍵),摘要信息就被打印出來了。筆者使用了命令行參數 -m 來使得統計值以毫秒爲單位輸出。

上面的輸出結果中有一些有趣的細節 :它呈現了雙峯分佈特徵,並且顯示了延遲離 羣點的存在。第一峯(圖中用 ASCII 字符展示)是 0 ~ 1 毫秒這個區間,在跟蹤時有共 計 16 335 個 I/O 事件。這個速度相當快,可能是因爲命中了存儲設備上的緩存或者使用的是閃存設備。第二峯是 32 ~ 63 毫秒這個區間,這相對此類存儲設備的預期性能慢了 不少,意味着可能有排隊發生。可以用更多的 BPF 工具深入調查進行確認。最後,對於 512 ~ 1023 毫秒區間,有 11 個 I/O 事件。這些極大的延遲稱爲延遲離羣點。現在我們知道了有這樣的離羣點存在,後面就可以使用其他 BPF 工具來進一步定位。對於數據庫 團隊,這是需要高優先級研究和解決的問題,因爲一旦數據庫阻塞在了這些 I/O 請求上, 數據庫的延遲服務質量承諾就無法達到了。

震撼全球的 Gregg 大師新作

面世即巔峯,硬核內容暢行全球

作爲性能分析領域享譽全球的專家,Brendan Gregg 也是BPF項目的核心開發者,同時也是經典暢銷著作《性能之巔:洞悉系統、企業與雲計算》的作者。

沒有人比他更適合來寫這樣一本利用 BPF 工具進行性能分析的書了!

書中有150多個可以立即使用的分析調試工具及其應用場景,並且提供開發自定義工具的分步指南。

其中有數十個強大的工具是專門爲本書而開發,並可下載使用!

瞭解更多BPF技術內幕,推薦閱讀《BPF之巔:洞悉Linux系統和應用性能》一書。

▊《BPF之巔:洞悉Linux系統和應用性能》

【美】Brendan Gregg 著

孫宇聰 呂宏利 劉曉舟 譯

  • Gregg大師新作,《性能之巔》再續新篇
  • 性能優化的萬用金典,150+分析調試工具深度剖析

本書作爲全面介紹 BPF 技術的圖書,從 BPF 技術的起源到未來發展方向都有涵蓋,不僅全面介紹了 BPF 的編程模型,還完整介紹了兩個主要的 BPF 前端編程框架 — BCC 和 bpftrace,更給出了一系列實現範例,生動展示了 BPF技術的實際能力和未來發展前景。

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