bcc:驯服 Linux 4.3+ 跟踪superpower

这是我昨晚在硅谷 Linux 技术聚会上演示的一些新开源工具的快速浏览。这些使用最近 Linux 中添加的新 eBPF 功能,包括 Linux 4.3。
总结磁盘I/O延迟的分布:

# ./biolatency
跟踪块设备 I/O... 按 Ctrl-C 结束。
^C
     usecs:计数分布
       0 -> 1 : 0 | |
       2 -> 3 : 0 | |
       4 -> 7 : 0 | |
       8 -> 15 : 0 | |
      16 -> 31 : 0 | |
      32 -> 63 : 0 | |
      64 -> 127 : 1 | |
     128 -> 255 : 12 |******** |
     256 -> 511 : 15 |********** |
     512 -> 1023 : 43 |************************************|
    1024 -> 2047 : 52 |******************************************|
    2048 -> 4095 : 47 |**********************************|
    4096 -> 8191 : 52 |******************************************|
    8192 -> 16383 : 36 |************************** |
   16384 -> 32767 : 15 |********** |
   32768 -> 65535 : 2 |* |
   65536 -> 131071 : 2 |* |

跟踪每个磁盘的 I/O:

# ./biosnoop
TIME(s) COMM PID 磁盘 T 扇区字节 LAT(ms)
0.000004001 监督 1950 xvda1 W 13092560 4096 0.74
0.000178002 监督 1950 xvda1 W 13092432 4096 0.61
0.001469001 监督 1956 xvda1 W 13092440 4096 1.24
0.001588002 监督 1956 xvda1 W 13115128 4096 1.09
1.022346001 监督 1950 xvda1 W 13115272 4096 0.98
1.022568002 监督 1950 xvda1 W 13188496 4096 0.93
1.023534000 监督 1956 xvda1 W 13188520 4096 0.79
1.023585003 监督 1956 xvda1 W 13189512 4096 0.60

跟踪 open() 系统调用:

# ./opensnoop
PID COMM FD ERR 路径
17326 <...> 7 0 /sys/kernel/debug/tracing/trace_pipe
17358 运行 3 0 /lib/x86_64-linux-gnu/libtinfo.so.5
17358  run                 3   0 /lib/x86_64-linux-gnu/libdl.so.2
17358  run                 3   0 /lib/x86_64-linux-gnu/libc.so.6
17358  run                -1   6 /dev/tty
17358  run                 3   0 /proc/meminfo
17358  run                 3   0 /etc/nsswitch.conf

Counting VFS operation types:

# ./vfsstat
TIME         READ/s  WRITE/s CREATE/s   OPEN/s  FSYNC/s
18:35:35:       241       15        4       99        0
18:35:36:       232       10        4       98        0
18:35:37:       244       10        4      107        0
18:35:38:       235       13        4       97        0
18:35:39:      6749     2633        4     1446        0
18:35:40:       277       31        4      115        0

计算每秒匹配“tcpsend”的内核函数调用:

# ./funccount -i 1 'tcp*send*'
Tracing... Ctrl-C to end.

ADDR             FUNC                          COUNT
ffffffff816d2281 tcp_send_delayed_ack             30
ffffffff816d6c81 tcp_v4_send_check                31
ffffffff816c2f61 tcp_sendmsg                      31
ffffffff816bf851 tcp_send_mss                     31

ADDR             FUNC                          COUNT
ffffffff816d1db1 tcp_send_fin                      3
ffffffff816d0f71 tcp_send_ack                     18
ffffffff816d2281 tcp_send_delayed_ack            214
ffffffff816c2f61 tcp_sendmsg                     231
ffffffff816bf851 tcp_send_mss                    231
ffffffff816d6c81 tcp_v4_send_check               255

ADDR             FUNC                          COUNT
ffffffff816d0f71 tcp_send_ack                      2
ffffffff816d2281 tcp_send_delayed_ack              9
ffffffff816c2f61 tcp_sendmsg                      30
ffffffff816bf851 tcp_send_mss                     30

计时 tcp_sendmsg() 延迟(调用持续时间),以微秒为单位:

# ./funclatency -u tcp_sendmsg
Tracing tcp_sendmsg... Hit Ctrl-C to end.
^C
     usecs           : count     distribution
       0 -> 1        : 20778    |**************************************|
       2 -> 3        : 15429    |****************************          |
       4 -> 7        : 355      |                                      |
       8 -> 15       : 171      |                                      |
      16 -> 31       : 106      |                                      |
      32 -> 63       : 9        |                                      |

分离…
…所有这些工具都有手册页,并且大多数还有帮助信息:

# ./funclatency -h
usage: funclatency [-h] [-p PID] [-i INTERVAL] [-T] [-u] [-m] [-r] pattern

时间核函数和打印延迟作为直方图
位置参数:

  pattern               search expression for kernel functions

optional arguments:
  -h, --help            show this help message and exit
  -p PID, --pid PID     trace this PID only
  -i INTERVAL, --interval INTERVAL
                        summary interval, seconds
  -T, --timestamp       include timestamp on output
  -u, --microseconds    microsecond histogram
  -m, --milliseconds    millisecond histogram
  -r, --regexp          use regular expressions. Default is "*" wildcards
                        only.

examples:
    ./funclatency do_sys_open       # time the do_sys_open() kenel function
    ./funclatency -u vfs_read       # time vfs_read(), in microseconds
    ./funclatency -m do_nanosleep   # time do_nanosleep(), in milliseconds
    ./funclatency -mTi 5 vfs_read   # output every 5 seconds, with timestamps
    ./funclatency -p 181 vfs_read   # time process 181 only
    ./funclatency 'vfs_fstat*'      # time both vfs_fstat() and vfs_fstatat()

Linux 4.3+, eBPF
Linux 4.3 中的新功能是能够从 Extended Berkeley Packet Filters (eBPF) 程序打印字符串。这只是一个小的补充,但我需要许多工具。 eBPF 是一个虚拟机,用于运行用户定义的沙盒字节码,并带有用于数据存储的映射。我在 eBPF 中写过它:一小步。
eBPF 增强了 Linux Tracing,允许小程序在 Tracing 事件上执行。在我上面的工具中,eBPF 让我可以使用自定义时间戳标记事件、存储直方图、过滤事件,并且只将汇总信息发送到用户级别。这些功能以尽可能低的间接成本为我提供了我想要的信息。
虽然 eBPF 提供了惊人的超能力,但有一个问题:很难通过其汇编或 C 接口使用。挑战吸引了我,但它可能是一种残酷的体验,尤其是如果您直接编写 eBPF 程序集(例如,请参见 sock_example.c 中的 bpf_insn_prog;我还没有从头开始编写其中一个可以编译的代码)。 C 接口更好(参见 samples/bpf 中的其他示例),但它仍然很费力且难以使用。
输入密件抄送
BPF Compiler Collection (bcc) 项目为 eBPF 提供了一个前端,使编写程序更加容易。它使用 C 作为后端工具,使用 Python 作为前端接口。我在本文开头的工具都使用了bcc,可以在github上bcc的工具目录中找到。还浏览该目录以查找 _example.txt 文件。
我修改了右侧的图表(来自 Velocity 2015)以显示 bcc 所扮演的角色:它提高了 eBPF 的可用性。
密件抄送还处于早期阶段,现在设置和使用并不容易,即使您使用的是 Linux 4.3+(例如,这里是我自己的笔记)。将来,这应该像添加包一样简单。这将只添加用户级软件:内核部分(eBPF)已经在 Linux 内核中。
就像 bcc 的一个示例一样,这是我的biolatency tool的完整代码,我在这篇文章的顶部展示了它:
很多代码是处理命令行参数的逻辑。C 检测代码以 bpf_text 的形式在线定义。我想改进一些事情,比如切换到跟踪点而不是 kprobes,但到目前为止这还不错。我可以在其中编写工具。
bcc 还可以比我这里的示例做更多的事情:它也可以用于高级网络流量控制。有关这些功能的更多信息,请参阅IO Visor项目。
即使很少有人学习 bcc 编程,它也应该通过使用它的工具看到成功。在像 Netflix 这样的公司,只需我们几个人学习 bcc/eBPF 就可以对公司产生重大影响:我们可以开发工具供其他人使用,并为我们的其他分析软件(例如Vector)开发插件。我们创造的很多东西都是开源的,所以其他人也会受益。
其他示踪剂和工具
bcc 不会是 eBPF 的唯一接口。已经有将其引入 Linux perf_events 的工作。很高兴看到带有语法的跟踪器(如 SystemTap 或 ktap)支持 eBPF,这将使临时工具更容易编写。(也许 bcc 将来会提供自己的语法。)eBPF 应该使其他跟踪器的其他增强成为可能。
我之前创建了perf-tools,这是一个用于 Linux 系统的主要基于 ftrace 的跟踪工具的集合。使用 eBPF 和 bcc,我最终会将其中一些工具切换到 eBPF,在那里它们将具有更多功能,更易于维护,并且开销更低。例如,我的 perf-tools iolatency工具,相当于 biolatency,在用户级别处理每个磁盘事件,花费了可衡量的开销(我在工具及其手册页中警告过)。bcc biolatency 版本的开销应该可以忽略不计。
使用 bcc/eBPF,我还将创建许多以前不可能(或不切实际)做的新工具。
感谢 PLUMgrid 的 Alexei Starovoitov 和 Brenden Blanco 以及其他人开发 eBPF 和 bcc,以及 Deirdré Straughan 对这篇文章的编辑。

转载翻译自: https://www.brendangregg.com