打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
使用 bcc/BPF 在 Linux 中分析性能的 7 个工具
userphoto

2023.06.20 湖北

关注

Linux 中出现了一项新技术,可以为系统管理员和开发人员提供大量用于性能分析和故障排除的新工具和仪表板。它被称为增强型 Berkeley 数据包过滤器(eBPF,或简称 BPF),尽管这些增强功能不是在 Berkeley 开发的,但它们不仅仅对数据包进行操作,而且它们所做的不仅仅是过滤。我将讨论一种在FedoraRed 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 登录:

# /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 工具查看正在打开的文件:

# /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

execsnoopopensnoop等工具为每个事件打印一行。这显示了**file(1)正在打开(或试图打开)的文件:返回的文件描述符(FD列)对于/etc/magic.mgc-1ERR列表示它不是“文件成立。” 我不知道那个文件,也不知道file(1)正在读取的/usr/share/misc/magic.mgc。我不应该感到惊讶,但是file(1)**识别文件类型没有问题:

# 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 文件系统操作:

# /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中的内核函数来实现,并在它结束时撤消该检测。此密件抄送工具也有适用于其他文件系统的版本:ext4slowerbtrfsslowerzfsslowernfsslower

这是一个有用的工具,也是BPF跟踪的一个重要示例。文件系统性能的传统分析侧重于块 I/O 统计信息——您通常会看到由iostat(1)工具打印并由许多性能监控GUI绘制的信息。这些统计数据显示了磁盘的性能,但并不是真正的文件系统。通常您更关心文件系统的性能而不是磁盘,因为它是应用程序向其发出请求和等待的文件系统。文件系统的性能可能与磁盘的性能大不相同!文件系统可以完全从内存缓存中读取,也可以通过预读算法填充该缓存并用于回写缓存。xfsslower显示文件系统性能——应用程序直接体验到的性能。这对于免除整个存储子系统的责任通常很有用;如果真的没有文件系统延迟,那么性能问题很可能出在其他地方。

4.biolatency

尽管文件系统性能对于了解应用程序性能很重要,但研究磁盘性能也有其优点。当各种缓存技巧无法再隐藏其延迟时,糟糕的磁盘性能最终会影响应用程序。磁盘性能也是容量规划的一个研究对象。

iostat (1)工具显示平均磁盘 I/O 延迟,但平均值可能具有误导性。以直方图的形式研究I/O延迟的分布可能很有用,这可以使用biolatency来完成:

# /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消息所示:

# /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 会话的生命周期和吞吐量统计信息:

# /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)和相关库调用以进行名称解析:

# /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)功能和自定义探测器。例如:

# /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.txttrace.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 软件包依赖项。我使用的系统是:

# 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以获取更新版本:

# 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中看到新工具:

# 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 file or directory
Traceback (most recent call last):
  File '/usr/share/bcc/tools/opensnoop', line 126in <module>
    b = BPF(text=bpf_text)
  File '/usr/lib/python3.6/site-packages/bcc/__init__.py', line 284in __init__
    raise Exception('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
Installed size: 63 M
Is this ok [y/N]: y
[...]

现在:

# /usr/share/bcc/tools/opensnoop
PID    COMM               FD ERR PATH
11792  ls                  3   0 /etc/ld.so.cache
11792  ls                  3   0 /lib64/libselinux.so.1
11792  ls                  3   0 /lib64/libcap.so.2
11792  ls                  3   0 /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 gcc gcc-c++ make zlib-devel \
  elfutils-libelf-devel
sudo dnf install -y luajit luajit-devel  # for Lua 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编译和安装步骤:

git clone https://github.com/iovisor/bcc.git
mkdir bcc/build; cd bcc/build
cmake .. -DCMAKE_INSTALL_PREFIX=/usr
make
sudo make install

此时,命令应该起作用:

# /usr/share/bcc/tools/opensnoop
PID    COMM               FD ERR PATH
4131   date                3   0 /etc/ld.so.cache
4131   date                3   0 /lib64/libc.so.6
4131   date                3   0 /usr/lib/locale/locale-archive
4131   date                3   0 /etc/localtime
[...]

最后的话和其他前端

这是对可在FedoraRed Hat系列操作系统上使用的新BPF性能分析超级功能的快速浏览。我向BPF演示了流行的bcc前端,并包含了 Fedora 的安装说明。bcc 带有60 多个用于性能分析的新工具,它们将帮助您充分利用Linux系统。也许您会直接通过SSH使用这些工具,或者一旦它们支持BPF,您可能会通过监视GUI使用相同的功能。

此外,bcc 并不是唯一正在开发的前端。有plybpftrace,旨在提供用于快速编写自定义工具的高级语言。此外,SystemTap刚刚发布了3.2 版,其中包括一个早期的实验性eBPF后端。如果继续开发它,它将提供一个生产安全和高效的引擎,用于运行多年来开发的许多SystemTap脚本和tapsets(库)。(将 SystemTapeBPF 结合使用将是另一篇文章的好主题。)

如果您需要开发自定义工具,您也可以使用 bcc,尽管该语言目前比 SystemTapply bpftrace冗长得多。我的密件抄送工具可以用作代码示例,另外我还贡献了一个使用Python 开发密件抄送工具的教程。](https://github.com/iovisor/bcc/blob/master/docs/tutorial_bcc_python_developer.md)我建议首先学习 bcc 多功能工具,因为在需要编写新工具之前,您可能会从中学到很多东西。您可以从 bcc 存储库中的示例文件中研究多功能工具:funccount、funclatency、funcslower、stackcount、trace和argdist。


本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
深入理解 BPF:一个阅读清单 | Linux 中国
嵌入式Qt4.7.1安装详解
linux2.6内核编译方法详述
搭建uClinux+arm+skyeye软硬件开发环境
CLFS1&CLFS2工具链比较
Fedora中Vmware Tools的安装、卸载 、以及无法登陆图形界面
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服