使用 bcc、BPF 在 Linux 中分析性能的 7 个工具
简介
Linux 中出现了一项新技术,可以为系统管理员和开发人员提供大量用于性能分析和故障排除的新工具和仪表板。它被称为增强型 Berkeley 数据包过滤器(eBPF,或简称 BPF),尽管这些增强功能不是在 Berkeley 开发的,但它们不仅仅对数据包进行操作,而且它们所做的不仅仅是过滤。我将讨论一种在Fedora
和 Red Hat
系列 Linux
发行版上使用BPF
的方法,并在 Fedora 26
上进行演示。
BPF 可以在内核中运行用户定义的沙盒程序,以立即添加新的自定义功能。这就像按需为Linux
添加超能力。您可以使用它的示例包括:
- 高级性能跟踪工具:文件系统操作、
TCP
事件、用户级事件等的程序化低开销检测。 - 网络性能:尽早丢弃数据包以提高
DDOS
弹性,或在内核中重定向数据包以提高性能。 - 安全监控:
24x7
自定义监控和可疑内核和用户空间事件的日志记录。
BPF
程序必须通过内核验证程序以确保它们可以安全运行,这使其成为比编写自定义内核模块更安全的选择(在可能的情况下)。我怀疑大多数人不会自己编写BPF
程序,但会使用其他人的程序。我在 GitHub 上作为BPF Compiler Collection (bcc)项目的开源发布了很多。bcc
为BPF
开发提供了不同的前端,包括Python 和 Lua
,并且是目前BPF
工具最活跃的项目。
7 个有用的新 bcc/BPF 工具
为了理解bcc/BPF
工具以及它们的作用,我创建了下图并将其添加到bcc
项目中:
这些是您可以通过 SSH
(安全外壳)使用的命令行界面(CLI)
工具。现在很多分析,包括在我的雇主那里,都是使用 GUI
和仪表板进行的。SSH
是最后的手段。但是这些CLI
工具仍然是预览 BPF
功能的好方法,即使您最终打算仅在可用时通过GUI
使用它们。我已经开始向开源GUI
添加BPF
功能,但这是另一篇文章的主题。现在我想分享您今天可以使用的 CLI
工具。
1.执行监听(execsnoop)
从哪儿开始?观看新流程怎么样?它们会消耗系统资源,但它们的生命周期很短,不会出现在top
或其他工具中。可以使用execsnoop
对它们进行检测(或者,使用行业术语,可以跟踪它们)。在跟踪时,我将在另一个窗口中通过SSH
登录:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | # /usr/share/bcc/tools/execsnoop PCOMM PID PPID RET ARGS sshd 12234 727 0 /usr/sbin/sshd -D -R unix_chkpwd 12236 12234 0 /usr/sbin/unix_chkpwd root nonull unix_chkpwd 12237 12234 0 /usr/sbin/unix_chkpwd root chkexpiry bash 12239 12238 0 /bin/bash id 12241 12240 0 /usr/bin/id -un hostname 12243 12242 0 /usr/bin/hostname pkg-config 12245 12244 0 /usr/bin/pkg-config --variable=completionsdir bash-completion grepconf.sh 12246 12239 0 /usr/libexec/grepconf.sh -c grep 12247 12246 0 /usr/bin/grep -qsi ^COLOR.*none /etc/GREP_COLORS tty 12249 12248 0 /usr/bin/tty -s tput 12250 12248 0 /usr/bin/tput colors dircolors 12252 12251 0 /usr/bin/dircolors --sh /etc/DIR_COLORS grep 12253 12239 0 /usr/bin/grep -qi ^COLOR.*none /etc/DIR_COLORS grepconf.sh 12254 12239 0 /usr/libexec/grepconf.sh -c grep 12255 12254 0 /usr/bin/grep -qsi ^COLOR.*none /etc/GREP_COLORS grepconf.sh 12256 12239 0 /usr/libexec/grepconf.sh -c grep 12257 12256 0 /usr/bin/grep -qsi ^COLOR.*none /etc/GREP_COLORS |
grepconf.sh
是什么?什么是/etc/GREP_COLORS
?grep
真的是通过运行grep
来读取它自己的配置文件吗?那是如何工作的?
欢迎体验系统跟踪的乐趣。您可以了解很多关于系统如何真正工作(或不工作,视情况而定)的信息,并在此过程中发现一些简单的优化。execsnoop通过跟踪exec()系统调用来工作,该系统调用通常用于在新进程中加载不同的程序代码。
2. 开启监听(opensnoop)
从上面继续,那么,grepconf.sh
很可能是一个 shell
脚本,对吧?我将运行file(1)进行检查,并使用opensnoop bcc 工具查看正在打开的文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # /usr/share/bcc/tools/opensnoop PID COMM FD ERR PATH 12420 file 3 0 /etc/ld.so.cache 12420 file 3 0 /lib64/libmagic.so.1 12420 file 3 0 /lib64/libz.so.1 12420 file 3 0 /lib64/libc.so.6 12420 file 3 0 /usr/lib/locale/locale-archive 12420 file -1 2 /etc/magic.mgc 12420 file 3 0 /etc/magic 12420 file 3 0 /usr/share/misc/magic.mgc 12420 file 3 0 /usr/lib64/gconv/gconv-modules.cache 12420 file 3 0 /usr/libexec/grepconf.sh 1 systemd 16 0 /proc/565/cgroup 1 systemd 16 0 /proc/536/cgroup |
execsnoop和opensnoop等工具为每个事件打印一行。这显示了file(1)正在打开(或试图打开)的文件:返回的文件描述符(FD
列)对于/etc/magic.mgc
是-1
,ERR
列表示它不是“文件成立。” 我不知道那个文件,也不知道file(1)正在读取的/usr/share/misc/magic.mgc
。我不应该感到惊讶,但是file(1)识别文件类型没有问题:
1 2 3 | # file /usr/share/misc/magic.mgc /etc/magic /usr/share/misc/magic.mgc: magic binary file for file(1) cmd (version 14) (little endian) /etc/magic: magic text file for file(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
文件系统操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 | # /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:34 systemd-journa 530 S 0 0 1.69 system.journal 14:17:35 auditd 651 S 0 0 2.43 audit.log 14:17:42 cksum 4167 R 52976 0 1.04 at 14:17:45 cksum 4168 R 53264 0 1.62 [ 14:17:45 cksum 4168 R 65536 0 1.01 certutil 14:17:45 cksum 4168 R 65536 0 1.01 dir 14:17:45 cksum 4168 R 65536 0 1.17 dirmngr-client 14:17:46 cksum 4168 R 65536 0 1.06 grub2-file 14:17:46 cksum 4168 R 65536 128 1.01 grub2-fstest [...] |
在上面的输出中,我发现许多延迟超过1
毫秒的cksum(1)
读取(“T”表示类型 ==“R”)。这通过在xfsslower
工具运行时动态检测XFS
中的内核函数来实现,并在它结束时撤消该检测。此密件抄送工具也有适用于其他文件系统的版本:ext4slower
、btrfsslower
、zfsslower
和nfsslower
。
这是一个有用的工具,也是BPF
跟踪的一个重要示例。文件系统性能的传统分析侧重于块 I/O 统计信息——您通常会看到由iostat(1)
工具打印并由许多性能监控GUI
绘制的信息。这些统计数据显示了磁盘的性能,但并不是真正的文件系统。通常您更关心文件系统的性能而不是磁盘,因为它是应用程序向其发出请求和等待的文件系统。文件系统的性能可能与磁盘的性能大不相同!文件系统可以完全从内存缓存中读取,也可以通过预读算法填充该缓存并用于回写缓存。xfsslower
显示文件系统性能——应用程序直接体验到的性能。这对于免除整个存储子系统的责任通常很有用;如果真的没有文件系统延迟,那么性能问题很可能出在其他地方。
4.biolatency
尽管文件系统性能对于了解应用程序性能很重要,但研究磁盘性能也有其优点。当各种缓存技巧无法再隐藏其延迟时,糟糕的磁盘性能最终会影响应用程序。磁盘性能也是容量规划的一个研究对象。
iostat (1)
工具显示平均磁盘 I/O
延迟,但平均值可能具有误导性。以直方图的形式研究I/O
延迟的分布可能很有用,这可以使用biolatency
来完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | # /usr/share/bcc/tools/biolatency Tracing block device I/O... Hit Ctrl-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 | | |
这是另一个有用的工具和另一个有用的例子;它使用称为映射的BPF
功能,可用于实现高效的内核摘要统计。从内核层到用户层的数据传输仅仅是计数
列;用户级程序生成其余部分。
值得注意的是,许多这些工具都支持CLI
选项和参数,如它们的USAGE
消息所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | # /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 and exit -T, --timestamp include timestamp on output -Q, --queued include OS queued time in 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 1 10 # print 1 second summaries, 10 times ./biolatency -mT 1 # 1s summaries, milliseconds, and timestamps ./biolatency -Q # include OS queued time in I/O time ./biolatency -D # show each disk device separately |
它们的行为与其他 Unix
工具一样是设计使然,以帮助采用。
5.tcplife
另一个有用的工具和示例是tcplife
,这次显示了 TCP
会话的生命周期和吞吐量统计信息:
1 2 3 4 5 6 | # /usr/share/bcc/tools/tcplife PID COMM LADDR LPORT RADDR RPORT TX_KB RX_KB MS 12759 sshd 192.168.56.101 22 192.168.56.1 60639 2 3 1863.82 12783 sshd 192.168.56.101 22 192.168.56.1 60640 3 3 9174.53 12844 wget 10.0.2.15 34250 54.204.39.132 443 11 1870 5712.26 12851 curl 10.0.2.15 34252 54.204.39.132 443 0 74 505.90 |
在你说:“我不能为此抓取tcpdump(8)
输出吗?”请注意,运行tcpdump(8)
或任何数据包嗅探器在高数据包速率系统上可能会产生明显的开销,即使tcpdump(8)
的用户级和内核级机制多年来一直在优化(它可能比更差)。tcplife
不会检测每个数据包;它只是为了提高效率而监视 TCP
会话状态的变化,并且由此计算会话的持续时间。它还使用已经跟踪吞吐量的内核计数器,以及进程和命令信息(“PID”和“COMM”列)
,这些信息不可用于在线嗅探工具,如tcpdump(8)
。
6.获取主机延迟
前面的每个示例都涉及内核跟踪,因此我至少需要一个用户级跟踪示例。这是gethostlatency
,它检测gethostbyname(3)
和相关库调用以进行名称解析:
1 2 3 4 5 6 7 8 9 10 | # /usr/share/bcc/tools/gethostlatency TIME PID COMM LATms HOST 06:43:33 12903 curl 188.98 opensource.com 06:43:36 12905 curl 8.45 opensource.com 06:43:40 12907 curl 6.55 opensource.com 06:43:44 12911 curl 9.67 opensource.com 06:45:02 12948 curl 19.66 opensource.cats 06:45:06 12950 curl 18.37 opensource.cats 06:45:07 12952 curl 13.64 opensource.cats 06:45:19 13139 curl 13.10 opensource.cats |
是的,它始终是DNS
,因此拥有一个在系统范围内监视DNS
请求的工具会很方便(这仅适用于应用程序使用标准系统库的情况)。看看我是如何跟踪多次查找到opensource.com
的?第一次用了188.98
毫秒,后来就快多了,不到 10
毫秒,毫无疑问缓存了。它还追踪到opensource.cats
的多次查找,遗憾的是这个主机并不存在,但我们仍然可以检查第一次和后续查找的延迟。(第二次查找后是否有一点负缓存?)
7.trace
好吧,再举一个例子。跟踪工具由Sasha Goldshtein
贡献,并提供一些基本的printf(1)
功能和自定义探测器。例如:
1 2 3 | # /usr/share/bcc/tools/trace 'pam:pam_start "%s: %s", arg1, arg2' PID TID COMM FUNC - 13266 13266 sshd pam_start sshd: root |
在这里,我正在跟踪libpam
及其pam_start(3)
函数并将其两个参数打印为字符串。Libpam
用于可插入身份验证模块系统,输出显示 sshd
为“根”用户(我已登录)调用了pam_start()
。USAGE
消息(“trace -h”)
中有更多示例,此外,所有这些工具在 bcc
存储库中都有手册页和示例文件;例如,trace_example.txt
和trace.8
。
通过包安装bcc
安装 bcc
的最佳方法是按照bcc INSTALL.md
中的说明从 iovisor
存储库中安装。IO Visor
是包含 bcc 的 Linux 基金会项目。这些工具使用的BPF
增强功能已添加到4.x
系列 Linux
内核中,最高可达 4.9
。这意味着具有4.8
内核的 Fedora 25
可以运行这些工具中的大部分;Fedora 26
及其 4.11
内核可以运行它们(至少目前是这样)。
如果您使用的是 Fedora 25(或 Fedora 26
,这篇文章是几个月前发布的——你好,来自遥远的过去!),那么这种打包方法应该会奏效。如果您使用的是 Fedora 26
,请跳至通过源代码安装
部分,这可避免已知和已修复的
错误。该错误修复目前尚未进入Fedora 26
软件包依赖项。我使用的系统是:
1 2 3 4 | # uname -a Linux localhost.localdomain 4.11.8-300.fc26.x86_64 #1 SMP Thu Jun 29 20:09:48 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux # cat /etc/fedora-release Fedora release 26 (Twenty Six) |
以下是我遵循的安装步骤,但请参阅INSTALL.md
以获取更新版本:
1 2 3 4 5 6 | # echo -e '[iovisor]\nbaseurl=https://repo.iovisor.org/yum/nightly/f25/$basearch\nenabled=1\ngpgcheck=0' | sudo tee /etc/yum.repos.d/iovisor.repo # dnf install bcc-tools [...] Total download size: 37 M Installed size: 143 M Is this ok [y/N]: y |
安装后,您应该会在/usr/share
中看到新工具:
1 2 3 4 | # ls /usr/share/bcc/tools/ argdist dcsnoop killsnoop softirqs trace bashreadline dcstat llcstat solisten ttysnoop [...] |