2021-05-12 14:32:11
7 個使用 bcc/BPF 的效能分析神器
使用伯克利包過濾器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 的恢復能力,或者在核心中重定向封包以提高效能。
- 安全監控: 7x24 小時的自定義檢測和記錄核心空間與使用者空間內的可疑事件。
在可能的情況下,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 登入:
# /usr/share/bcc/tools/execsnoop
PCOMM PID PPID RET ARGS
sshd122347270/usr/sbin/sshd-D -R
unix_chkpwd 12236122340/usr/sbin/unix_chkpwd root nonull
unix_chkpwd 12237122340/usr/sbin/unix_chkpwd root chkexpiry
bash12239122380/bin/bash
id12241122400/usr/bin/id-un
hostname12243122420/usr/bin/hostname
pkg-config 12245122440/usr/bin/pkg-config --variable=completionsdir bash-completion
grepconf.sh 12246122390/usr/libexec/grepconf.sh -c
grep12247122460/usr/bin/grep-qsi ^COLOR.*none /etc/GREP_COLORS
tty12249122480/usr/bin/tty-s
tput 12250122480/usr/bin/tput colors
dircolors 12252122510/usr/bin/dircolors --sh /etc/DIR_COLORS
grep12253122390/usr/bin/grep-qi ^COLOR.*none /etc/DIR_COLORS
grepconf.sh 12254122390/usr/libexec/grepconf.sh -c
grep12255122540/usr/bin/grep-qsi ^COLOR.*none /etc/GREP_COLORS
grepconf.sh 12256122390/usr/libexec/grepconf.sh -c
grep12257122560/usr/bin/grep-qsi ^COLOR.*none /etc/GREP_COLORS
哇哦。 那是什麼? 什麼是 grepconf.sh
? 什麼是 /etc/GREP_COLORS
? 是 grep
在讀取它自己的組態檔……由 grep
執行的? 這究竟是怎麼工作的?
歡迎來到有趣的系統追蹤世界。 你可以學到很多關於系統是如何工作的(或者根本不工作,在有些情況下),並且發現一些簡單的優化方法。 execsnoop
通過跟蹤 exec()
系統呼叫來工作,exec()
通常用於在新進程中載入不同的程式程式碼。
2、 opensnoop
接著上面繼續,所以,grepconf.sh
可能是一個 shell 指令碼,對吧? 我將執行 file(1)
來檢查它,並使用opensnoop bcc 工具來檢視開啟的檔案:
# /usr/share/bcc/tools/opensnoop
PID COMM FD ERR PATH
12420file30/etc/ld.so.cache
12420file30/lib64/libmagic.so.1
12420file30/lib64/libz.so.1
12420file30/lib64/libc.so.6
12420file30/usr/lib/locale/locale-archive
12420file-12/etc/magic.mgc
12420file30/etc/magic
12420file30/usr/share/misc/magic.mgc
12420file30/usr/lib64/gconv/gconv-modules.cache
12420file30/usr/libexec/grepconf.sh
1systemd160/proc/565/cgroup
1systemd160/proc/536/cgroup
像 execsnoop
和 opensnoop
這樣的工具會將每個事件列印一行。上圖顯示 file(1)
命令當前開啟(或嘗試開啟)的檔案:返回的檔案描述符(“FD” 列)對於 /etc/magic.mgc
是 -1,而 “ERR” 列指示它是“檔案未找到”。我不知道該檔案,也不知道 file(1)
正在讀取的 /usr/share/misc/magic.mgc
檔案是什麼。我不應該感到驚訝,但是 file(1)
在識別檔案型別時沒有問題:
#file/usr/share/misc/magic.mgc /etc/magic
/usr/share/misc/magic.mgc: magic binary fileforfile(1) cmd (version 14)(little endian)
/etc/magic: magic text fileforfile(1) cmd, ASCII text
opensnoop
通過跟蹤 open()
系統呼叫來工作。為什麼不使用 strace -feopen file
命令呢? 在這種情況下是可以的。然而,opensnoop
的一些優點在於它能在系統範圍內工作,並且跟蹤所有進程的 open()
系統呼叫。注意上例的輸出中包括了從 systemd 開啟的檔案。opensnoop
應該系統開銷更低:BPF 跟蹤已經被優化過,而當前版本的 strace(1)
仍然使用較老和較慢的 ptrace(2)
介面。
3、 xfsslower
bcc/BPF 不僅僅可以分析系統呼叫。xfsslower 工具可以跟蹤大於 1 毫秒(引數)延遲的常見 XFS 檔案系統操作。
# /usr/share/bcc/tools/xfsslower 1
Tracing XFS operations slower than 1 ms
TIME COMM PID T BYTES OFF_KB LAT(ms) FILENAME
14:17:34systemd-journa 530 S 001.69 system.journal
14:17:35 auditd 651 S 002.43 audit.log
14:17:42 cksum 4167 R 5297601.04 at
14:17:45 cksum 4168 R 5326401.62[
14:17:45 cksum 4168 R 6553601.01 certutil
14:17:45 cksum 4168 R 6553601.01dir
14:17:45 cksum 4168 R 6553601.17 dirmngr-client
14:17:46 cksum 4168 R 6553601.06 grub2-file
14:17:46 cksum 4168 R 655361281.01 grub2-fstest
[...]
在上圖輸出中,我捕獲到了多個延遲超過 1 毫秒 的 cksum(1)
讀取操作(欄位 “T” 等於 “R”)。這是在 xfsslower
工具執行的時候,通過在 XFS 中動態地檢測核心函數實現的,並當它結束的時候解除該檢測。這個 bcc 工具也有其它檔案系統的版本:ext4slower
、btrfsslower
、zfsslower
和 nfsslower
。
這是個有用的工具,也是 BPF 追蹤的重要例子。對檔案系統效能的傳統分析主要集中在塊 I/O 統計資訊 —— 通常你看到的是由 iostat(1)
工具輸出,並由許多效能監視 GUI 繪製的圖表。這些統計資料顯示的是磁碟如何執行,而不是真正的檔案系統如何執行。通常比起磁碟來說,你更關心的是檔案系統的效能,因為應用程式是在檔案系統中發起請求和等待。並且,檔案系統的效能可能與磁碟的效能大為不同!檔案系統可以完全從記憶體快取中讀取資料,也可以通過預讀演算法和回寫快取來填充快取。xfsslower
顯示了檔案系統的效能 —— 這是應用程式直接體驗到的效能。通常這對於排除整個儲存子系統的問題是有用的;如果確實沒有檔案系統延遲,那麼效能問題很可能是在別處。
4、 biolatency
雖然檔案系統效能對於理解應用程式效能非常重要,但研究磁碟效能也是有好處的。當各種快取技巧都無法挽救其延遲時,磁碟的低效能終會影響應用程式。 磁碟效能也是容量規劃研究的目標。
iostat(1)
工具顯示了平均磁碟 I/O 延遲,但平均值可能會引起誤解。 以直方圖的形式研究 I/O 延遲的分布是有用的,這可以通過使用 [biolatency] 來實現18:
# /usr/share/bcc/tools/biolatency
Tracing block device I/O...HitCtrl-C to end.
^C
usecs : count distribution
0->1:0||
2->3:0||
4->7:0||
8->15:0||
16->31:0||
32->63:1||
64->127:63|****|
128->255:121|*********|
256->511:483|************************************|
512->1023:532|****************************************|
1024->2047:117|********|
2048->4095:8||
這是另一個有用的工具和例子;它使用一個名為 maps 的 BPF 特性,它可以用來實現高效的核心摘要統計。從核心層到使用者層的資料傳輸僅僅是“計數”列。 使用者級程式生成其餘的。
值得注意的是,這種工具大多支援 CLI 選項和引數,如其使用資訊所示:
# /usr/share/bcc/tools/biolatency -h
usage: biolatency [-h][-T][-Q][-m][-D][interval][count]
Summarize block device I/O latency as a histogram
positional arguments:
interval output interval,in seconds
count number of outputs
optional arguments:
-h,--help show this help message andexit
-T,--timestamp include timestamp on output
-Q,--queued include OS queued timein I/O time
-m,--milliseconds millisecond histogram
-D,--disks print a histogram per disk device
examples:
./biolatency # summarize block I/O latency as a histogram
./biolatency 110#print1 second summaries,10 times
./biolatency -mT 1#1s summaries, milliseconds,and timestamps
./biolatency -Q #include OS queued timein I/O time
./biolatency -D # show each disk device separately
它們的行為就像其它 Unix 工具一樣,以利於採用而設計。
5、 tcplife
另一個有用的工具是 tcplife ,該例顯示 TCP 對談的生命週期和吞吐量統計。
# /usr/share/bcc/tools/tcplife
PID COMM LADDR LPORT RADDR RPORT TX_KB RX_KB MS
12759sshd192.168.56.10122192.168.56.160639231863.82
12783sshd192.168.56.10122192.168.56.160640339174.53
12844wget10.0.2.153425054.204.39.1324431118705712.26
12851 curl 10.0.2.153425254.204.39.132443074505.90
在你說 “我不是可以只通過 tcpdump(8)
就能輸出這個?” 之前請注意,執行 tcpdump(8)
或任何封包嗅探器,在高封包速率的系統上的開銷會很大,即使 tcpdump(8)
的使用者層和核心層機制已經過多年優化(要不可能更差)。tcplife
不會測試每個封包;它只會有效地監視 TCP 對談狀態的變化,並由此得到該對談的持續時間。它還使用已經跟蹤了吞吐量的核心計數器,以及進程和命令資訊(“PID” 和 “COMM” 列),這些對於 tcpdump(8)
等線上嗅探工具是做不到的。
6、 gethostlatency
之前的每個例子都涉及到核心跟蹤,所以我至少需要一個使用者級跟蹤的例子。 這就是 gethostlatency,它檢測用於名稱解析的 gethostbyname(3)
和相關的庫呼叫:
# /usr/share/bcc/tools/gethostlatency
TIME PID COMM LATms HOST
06:43:3312903 curl 188.98 opensource.com
06:43:3612905 curl 8.45 opensource.com
06:43:4012907 curl 6.55 opensource.com
06:43:4412911 curl 9.67 opensource.com
06:45:0212948 curl 19.66 opensource.cats
06:45:0612950 curl 18.37 opensource.cats
06:45:0712952 curl 13.64 opensource.cats
06:45:1913139 curl 13.10 opensource.cats
是的,總是有 DNS 請求,所以有一個工具來監視系統範圍內的 DNS 請求會很方便(這只有在應用程式使用標準系統庫時才有效)。看看我如何跟蹤多個對 “opensource.com” 的查詢? 第一個是 188.98 毫秒,然後更快,不到 10 毫秒,毫無疑問,這是快取的作用。它還追蹤多個對 “opensource.cats” 的查詢,一個不存在的可憐主機名,但我們仍然可以檢查第一個和後續查詢的延遲。(第二次查詢後是否有一些否定快取的影響?)
7、 trace
好的,再舉一個例子。 trace 工具由 Sasha Goldshtein 提供,並提供了一些基本的 printf(1)
功能和自定義探針。 例如:
# /usr/share/bcc/tools/trace 'pam:pam_start "%s: %s", arg1, arg2'
PID TID COMM FUNC -
1326613266sshd pam_start sshd: root
在這裡,我正在跟蹤 libpam
及其 pam_start(3)
函數,並將其兩個引數都列印為字串。 libpam
用於插入式身份驗證模組系統,該輸出顯示 sshd 為 “root” 使用者呼叫了 pam_start()
(我登入了)。 其使用資訊中有更多的例子(trace -h
),而且所有這些工具在 bcc 版本庫中都有手冊頁和範例檔案。 例如 trace_example.txt
和 trace.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 軟體包的依賴關係。 我使用的系統是:
#uname-a
Linux localhost.localdomain 4.11.8-300.fc26.x86_64 #1 SMP ThuJun2920:09:48 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
#cat/etc/fedora-release
Fedora release 26(TwentySix)
以下是我所遵循的安裝步驟,但請參閱 INSTALL.md 獲取更新的版本:
#echo-e '[iovisor]nbaseurl=https://repo.iovisor.org/yum/nightly/f25/$basearchnenabled=1ngpgcheck=0'|sudotee/etc/yum.repos.d/iovisor.repo
# dnf install bcc-tools
[...]
Total download size:37 M
Installedsize:143 M
Isthis ok [y/N]: y
安裝完成後,您可以在 /usr/share
中看到新的工具:
#ls/usr/share/bcc/tools/
argdist dcsnoop killsnoop softirqs trace
bashreadline dcstat llcstat solisten ttysnoop
[...]
試著執行其中一個:
# /usr/share/bcc/tools/opensnoop
chdir(/lib/modules/4.11.8-300.fc26.x86_64/build):No such fileor directory
Traceback(most recent call last):
File"/usr/share/bcc/tools/opensnoop", line 126,in
b = BPF(text=bpf_text)
File"/usr/lib/python3.6/site-packages/bcc/__init__.py", line 284,in __init__
raiseException("Failed to compile BPF module %s"% src_file)
Exception:Failed to compile BPF module
執行失敗,提示 /lib/modules/4.11.8-300.fc26.x86_64/build
丟失。 如果你也遇到這個問題,那只是因為系統缺少核心標頭檔案。 如果你看看這個檔案指向什麼(這是一個符號連結),然後使用 dnf whatprovides
來搜尋它,它會告訴你接下來需要安裝的包。 對於這個系統,它是:
# dnf install kernel-devel-4.11.8-300.fc26.x86_64
[...]
Total download size:20 M
Installedsize:63 M
Isthis ok [y/N]: y
[...]
現在:
# /usr/share/bcc/tools/opensnoop
PID COMM FD ERR PATH
11792ls30/etc/ld.so.cache
11792ls30/lib64/libselinux.so.1
11792ls30/lib64/libcap.so.2
11792ls30/lib64/libc.so.6
[...]
執行起來了。 這是捕獲自另一個視窗中的 ls 命令活動。 請參閱前面的部分以使用其它有用的命令。
通過原始碼安裝
如果您需要從原始碼安裝,您還可以在 INSTALL.md 中找到文件和更新說明。 我在 Fedora 26 上做了如下的事情:
sudo dnf install -y bison cmake ethtool flex git iperf libstdc++-static
python-netaddr python-pip gccgcc-c++make zlib-devel
elfutils-libelf-devel
sudo dnf install -y luajit luajit-devel #forLua support
sudo dnf install -y
http://pkgs.repoforge.org/netperf/netperf-2.6.0-1.el6.rf.x86_64.rpm
sudo pip install pyroute2
sudo dnf install -y clang clang-devel llvm llvm-devel llvm-static ncurses-devel
除 netperf
外一切妥當,其中有以下錯誤:
Curl error (28):Timeout was reached for http://pkgs.repoforge.org/netperf/netperf-2.6.0-1.el6.rf.x86_64.rpm [Connection timed out after 120002 milliseconds]
不必理會,netperf
是可選的,它只是用於測試,而 bcc 沒有它也會編譯成功。
以下是餘下的 bcc 編譯和安裝步驟:
gitclone https://github.com/iovisor/bcc.git
mkdir bcc/build;cd bcc/build
cmake ..-DCMAKE_INSTALL_PREFIX=/usr
make
sudomake install
現在,命令應該可以工作了:
# /usr/share/bcc/tools/opensnoop
PID COMM FD ERR PATH
4131date30/etc/ld.so.cache
4131date30/lib64/libc.so.6
4131date30/usr/lib/locale/locale-archive
4131date30/etc/localtime
[...]
寫在最後和其他的前端
這是一個可以在 Fedora 和 Red Hat 系列作業系統上使用的新 BPF 效能分析強大功能的快速瀏覽。我演示了 BPF 的流行前端 bcc ,並包括了其在 Fedora 上的安裝說明。bcc 附帶了 60 多個用於效能分析的新工具,這將幫助您充分利用 Linux 系統。也許你會直接通過 SSH 使用這些工具,或者一旦 GUI 監控程式支援 BPF 的話,你也可以通過它們來使用相同的功能。
此外,bcc 並不是正在開發的唯一前端。ply 和 bpftrace,旨在為快速編寫自定義工具提供更高階的語言支援。此外,SystemTap 剛剛發布版本 3.2,包括一個早期的實驗性 eBPF 後端。 如果這個繼續開發,它將為執行多年來開發的許多 SystemTap 指令碼和 tapset(庫)提供一個安全和高效的生產級引擎。(隨同 eBPF 使用 SystemTap 將是另一篇文章的主題。)
如果您需要開發自定義工具,那麼也可以使用 bcc 來實現,儘管語言比 SystemTap、ply 或 bpftrace 要冗長得多。我的 bcc 工具可以作為程式碼範例,另外我還貢獻了用 Python 開發 bcc 工具的教學。 我建議先學習 bcc 的 multi-tools,因為在需要編寫新工具之前,你可能會從裡面獲得很多經驗。 您可以從它們的 bcc 儲存庫funccount,funclatency,funcslower,stackcount,trace ,argdist 的範例檔案中研究 bcc。
感謝 Opensource.com 進行編輯。
關於作者
Brendan Gregg 是 Netflix 的一名高階效能架構師,在那裡他進行大規模的計算機效能設計、分析和調優。
via:https://opensource.com/article/17/11/bccbpf-performance
作者:Brendan Gregg 譯者:yongshouzhang 校對:校對者ID
本文永久更新連結地址:http://www.linuxidc.com/Linux/2017-12/149480.htm
相關文章