7 個使用 bcc/BPF 的效能分析神器

Brendan Gregg發表於2017-12-13

使用伯克利包過濾器 Berkeley Packet Filter(BPF)編譯器集合Compiler Collection(BCC)工具深度探查你的 Linux 程式碼。

在 Linux 中出現的一種新技術能夠為系統管理員和開發者提供大量用於效能分析和故障排除的新工具和儀表盤。它被稱為增強的伯克利資料包過濾器 enhanced Berkeley Packet Filter(eBPF,或 BPF),雖然這些改進並不是由伯克利開發的,而且它們不僅僅是處理資料包,更多的是過濾。我將討論在 Fedora 和 Red Hat Linux 發行版中使用 BPF 的一種方法,並在 Fedora 26 上演示。

BPF 可以在核心中執行由使用者定義的沙盒程式,可以立即新增新的自定義功能。這就像按需給 Linux 系統新增超能力一般。 你可以使用它的例子包括如下:

  • 高階效能跟蹤工具:對檔案系統操作、TCP 事件、使用者級事件等的可程式設計的低開銷檢測。
  • 網路效能: 儘早丟棄資料包以提高對 DDoS 的恢復能力,或者在核心中重定向資料包以提高效能。
  • 安全監控: 7×24 小時的自定義檢測和記錄核心空間與使用者空間內的可疑事件。

在可能的情況下,BPF 程式必須通過一個核心驗證機制來保證它們的安全執行,這比寫自定義的核心模組更安全。我在此假設大多數人並不編寫自己的 BPF 程式,而是使用別人寫好的。在 GitHub 上的 BPF Compiler Collection (bcc) 專案中,我已釋出許多開原始碼。bcc 為 BPF 開發提供了不同的前端支援,包括 Python 和 Lua,並且是目前最活躍的 BPF 工具專案。

7 個有用的 bcc/BPF 新工具

為了瞭解 bcc/BPF 工具和它們的檢測內容,我建立了下面的圖表並新增到 bcc 專案中。

Linux bcc/BPF 跟蹤工具圖

這些是命令列介面工具,你可以通過 SSH 使用它們。目前大多數分析,包括我的老闆,都是用 GUI 和儀表盤進行的。SSH 是最後的手段。但這些命令列工具仍然是預覽 BPF 能力的好方法,即使你最終打算通過一個可用的 GUI 使用它。我已著手向一個開源 GUI 新增 BPF 功能,但那是另一篇文章的主題。現在我想向你分享今天就可以使用的 CLI 工具。

1、 execsnoop

從哪兒開始呢?如何檢視新的程式。那些會消耗系統資源,但很短暫的程式,它們甚至不會出現在 top(1) 命令或其它工具中的顯示之中。這些新程式可以使用 execsnoop 進行檢測(或使用行業術語說,可以被追蹤traced)。 在追蹤時,我將在另一個視窗中通過 SSH 登入:

哇哦。 那是什麼? 什麼是 grepconf.sh? 什麼是 /etc/GREP_COLORS? 是 grep 在讀取它自己的配置檔案……由 grep 執行的? 這究竟是怎麼工作的?

歡迎來到有趣的系統追蹤世界。 你可以學到很多關於系統是如何工作的(或者根本不工作,在有些情況下),並且發現一些簡單的優化方法。 execsnoop 通過跟蹤 exec() 系統呼叫來工作,exec() 通常用於在新程式中載入不同的程式程式碼。

2、 opensnoop

接著上面繼續,所以,grepconf.sh 可能是一個 shell 指令碼,對吧? 我將執行 file(1) 來檢查它,並使用opensnoop bcc 工具來檢視開啟的檔案:

execsnoopopensnoop 這樣的工具會將每個事件列印一行。上圖顯示 file(1) 命令當前開啟(或嘗試開啟)的檔案:返回的檔案描述符(“FD” 列)對於 /etc/magic.mgc 是 -1,而 “ERR” 列指示它是“檔案未找到”。我不知道該檔案,也不知道 file(1) 正在讀取的 /usr/share/misc/magic.mgc 檔案是什麼。我不應該感到驚訝,但是 file(1) 在識別檔案型別時沒有問題:

opensnoop 通過跟蹤 open() 系統呼叫來工作。為什麼不使用 strace -feopen file 命令呢? 在這種情況下是可以的。然而,opensnoop 的一些優點在於它能在系統範圍內工作,並且跟蹤所有程式的 open() 系統呼叫。注意上例的輸出中包括了從 systemd 開啟的檔案。opensnoop 應該系統開銷更低:BPF 跟蹤已經被優化過,而當前版本的 strace(1) 仍然使用較老和較慢的 ptrace(2) 介面。

3、 xfsslower

bcc/BPF 不僅僅可以分析系統呼叫。xfsslower 工具可以跟蹤大於 1 毫秒(引數)延遲的常見 XFS 檔案系統操作。

在上圖輸出中,我捕獲到了多個延遲超過 1 毫秒 的 cksum(1) 讀取操作(欄位 “T” 等於 “R”)。這是在 xfsslower 工具執行的時候,通過在 XFS 中動態地檢測核心函式實現的,並當它結束的時候解除該檢測。這個 bcc 工具也有其它檔案系統的版本:ext4slowerbtrfsslowerzfsslowernfsslower

這是個有用的工具,也是 BPF 追蹤的重要例子。對檔案系統效能的傳統分析主要集中在塊 I/O 統計資訊 —— 通常你看到的是由 iostat(1) 工具輸出,並由許多效能監視 GUI 繪製的圖表。這些統計資料顯示的是磁碟如何執行,而不是真正的檔案系統如何執行。通常比起磁碟來說,你更關心的是檔案系統的效能,因為應用程式是在檔案系統中發起請求和等待。並且,檔案系統的效能可能與磁碟的效能大為不同!檔案系統可以完全從記憶體快取中讀取資料,也可以通過預讀演算法和回寫快取來填充快取。xfsslower 顯示了檔案系統的效能 —— 這是應用程式直接體驗到的效能。通常這對於排除整個儲存子系統的問題是有用的;如果確實沒有檔案系統延遲,那麼效能問題很可能是在別處。

4、 biolatency

雖然檔案系統效能對於理解應用程式效能非常重要,但研究磁碟效能也是有好處的。當各種快取技巧都無法挽救其延遲時,磁碟的低效能終會影響應用程式。 磁碟效能也是容量規劃研究的目標。

iostat(1) 工具顯示了平均磁碟 I/O 延遲,但平均值可能會引起誤解。 以直方圖的形式研究 I/O 延遲的分佈是有用的,這可以通過使用 [biolatency] 來實現18

這是另一個有用的工具和例子;它使用一個名為 maps 的 BPF 特性,它可以用來實現高效的核心摘要統計。從核心層到使用者層的資料傳輸僅僅是“計數”列。 使用者級程式生成其餘的。

值得注意的是,這種工具大多支援 CLI 選項和引數,如其使用資訊所示:

它們的行為就像其它 Unix 工具一樣,以利於採用而設計。

5、 tcplife

另一個有用的工具是 tcplife ,該例顯示 TCP 會話的生命週期和吞吐量統計。

在你說 “我不是可以只通過 tcpdump(8) 就能輸出這個?” 之前請注意,執行 tcpdump(8) 或任何資料包嗅探器,在高資料包速率的系統上的開銷會很大,即使 tcpdump(8) 的使用者層和核心層機制已經過多年優化(要不可能更差)。tcplife 不會測試每個資料包;它只會有效地監視 TCP 會話狀態的變化,並由此得到該會話的持續時間。它還使用已經跟蹤了吞吐量的核心計數器,以及程式和命令資訊(“PID” 和 “COMM” 列),這些對於 tcpdump(8) 等線上嗅探工具是做不到的。

6、 gethostlatency

之前的每個例子都涉及到核心跟蹤,所以我至少需要一個使用者級跟蹤的例子。 這就是 gethostlatency,它檢測用於名稱解析的 gethostbyname(3) 和相關的庫呼叫:

是的,總是有 DNS 請求,所以有一個工具來監視系統範圍內的 DNS 請求會很方便(這隻有在應用程式使用標準系統庫時才有效)。看看我如何跟蹤多個對 “opensource.com” 的查詢? 第一個是 188.98 毫秒,然後更快,不到 10 毫秒,毫無疑問,這是快取的作用。它還追蹤多個對 “opensource.cats” 的查詢,一個不存在的可憐主機名,但我們仍然可以檢查第一個和後續查詢的延遲。(第二次查詢後是否有一些否定快取的影響?)

7、 trace

好的,再舉一個例子。 trace 工具由 Sasha Goldshtein 提供,並提供了一些基本的 printf(1) 功能和自定義探針。 例如:

在這裡,我正在跟蹤 libpam 及其 pam_start(3) 函式,並將其兩個引數都列印為字串。 libpam 用於插入式身份驗證模組系統,該輸出顯示 sshd 為 “root” 使用者呼叫了 pam_start()(我登入了)。 其使用資訊中有更多的例子(trace -h),而且所有這些工具在 bcc 版本庫中都有手冊頁和示例檔案。 例如 trace_example.txttrace.8

通過包安裝 bcc

安裝 bcc 最佳的方法是從 iovisor 倉儲庫中安裝,按照 bcc 的 INSTALL.md 進行即可。IO Visor 是包括了 bcc 的 Linux 基金會專案。4.x 系列 Linux 核心中增加了這些工具所使用的 BPF 增強功能,直到 4.9 新增了全部支援。這意味著擁有 4.8 核心的 Fedora 25 可以執行這些工具中的大部分。 使用 4.11 核心的 Fedora 26 可以全部執行它們(至少在目前是這樣)。

如果你使用的是 Fedora 25(或者 Fedora 26,而且這個帖子已經在很多個月前釋出了 —— 你好,來自遙遠的過去!),那麼這個通過包安裝的方式是可以工作的。 如果您使用的是 Fedora 26,那麼請跳至“通過原始碼安裝”部分,它避免了一個已修復的已知錯誤。 這個錯誤修復目前還沒有進入 Fedora 26 軟體包的依賴關係。 我使用的系統是:

以下是我所遵循的安裝步驟,但請參閱 INSTALL.md 獲取更新的版本:

安裝完成後,您可以在 /usr/share 中看到新的工具:

試著執行其中一個:

執行失敗,提示 /lib/modules/4.11.8-300.fc26.x86_64/build 丟失。 如果你也遇到這個問題,那只是因為系統缺少核心標頭檔案。 如果你看看這個檔案指向什麼(這是一個符號連結),然後使用 dnf whatprovides 來搜尋它,它會告訴你接下來需要安裝的包。 對於這個系統,它是:

現在:

執行起來了。 這是捕獲自另一個視窗中的 ls 命令活動。 請參閱前面的部分以使用其它有用的命令。

通過原始碼安裝

如果您需要從原始碼安裝,您還可以在 INSTALL.md 中找到文件和更新說明。 我在 Fedora 26 上做了如下的事情:

netperf 外一切妥當,其中有以下錯誤:

不必理會,netperf 是可選的,它只是用於測試,而 bcc 沒有它也會編譯成功。

以下是餘下的 bcc 編譯和安裝步驟:

現在,命令應該可以工作了:

寫在最後和其他的前端

這是一個可以在 Fedora 和 Red Hat 系列作業系統上使用的新 BPF 效能分析強大功能的快速瀏覽。我演示了 BPF 的流行前端 bcc ,幷包括了其在 Fedora 上的安裝說明。bcc 附帶了 60 多個用於效能分析的新工具,這將幫助您充分利用 Linux 系統。也許你會直接通過 SSH 使用這些工具,或者一旦 GUI 監控程式支援 BPF 的話,你也可以通過它們來使用相同的功能。

此外,bcc 並不是正在開發的唯一前端。plybpftrace,旨在為快速編寫自定義工具提供更高階的語言支援。此外,SystemTap 剛剛釋出版本 3.2,包括一個早期的實驗性 eBPF 後端。 如果這個繼續開發,它將為執行多年來開發的許多 SystemTap 指令碼和 tapset(庫)提供一個安全和高效的生產級引擎。(隨同 eBPF 使用 SystemTap 將是另一篇文章的主題。)

如果您需要開發自定義工具,那麼也可以使用 bcc 來實現,儘管語言比 SystemTap、ply 或 bpftrace 要冗長得多。我的 bcc 工具可以作為程式碼示例,另外我還貢獻了用 Python 開發 bcc 工具的教程。 我建議先學習 bcc 的 multi-tools,因為在需要編寫新工具之前,你可能會從裡面獲得很多經驗。 您可以從它們的 bcc 儲存庫funccountfunclatencyfuncslowerstackcounttraceargdist 的示例檔案中研究 bcc。

感謝 Opensource.com 進行編輯。

關於作者

Brendan Gregg 是 Netflix 的一名高階效能架構師,在那裡他進行大規模的計算機效能設計、分析和調優。

相關文章