《system performance:Enterprise and the Cloud》&《BPF PerformanceTools》,Linux性能分析大神Brendan Gregg写的两本书,都是Linux 性能调优的经典之作。前者侧重讲述分析策略,方法论以及一些常用工具,后者侧重介绍bcc/bpftrace工具,列举大量跟踪命令及分析脚本。两本书的结构很类似,可以分章节对比阅读,能够对系统各模块的性能分析/调优有一个从理论到实践的整体认识。这种经典读一遍肯定是不够的,很多内容需要对内核有深入理解才能看懂,这一系列仅记录一些能看懂且有启发的部分吧。
性能分析的目的是提高业务应用的性能和降低开销,通常用一系列可观测的指标来体现性能。这些指标包括:
性能分析及调优需要做的工作:
现实中的系统是十分复杂的,查找问题往往不知从哪下手。很多情况是以猜测开始的,例如会怀疑网络,IO,CPU等等,通过性能分析需要指出哪一个才是正确的方向。
性能问题有时也会源于复杂的交互,单独测试各子系统都是正常的,一但整体测试就会有问题。排查这样的问题需要了解各子系统相互作用的详细流程。
性能瓶颈也可能是复杂的,解决一个问题可能只是将瓶颈转移到其他地方,整体性能并没明显改善。
除过系统本身,造成性能问题的负载也是复杂的,很可能无法在实验室中制造这样的负载,或者仅是偶现问题难以复现。
解决性能问题要了解它的复杂性,往往没有唯一的正确答案,需要找到的是提升性能最大影响系统最小的方案。
动态跟踪是指软件在运行过程中,对其行为进行跟踪,观测,统计。传统的跟踪方式是通过代码中预埋观测点或者hook,运行时动态的使能,但要做到实时跟踪软件的所有函数并不影响其运行,这并不是一件容易的事,为此人们开发了无数特性及工具。
书里的例子很有意思,分析内核就想进入了一个漆黑的房间,里面有一些蜡烛被放在工程师们认为需要的地方,而动态跟踪像是一个手电筒,你可以指向任何一个地方。
BPF (BSD Packet Filter) ,1992 年提出,其目的是为了提供一种过滤包的方法,并且要避免从内核空间到用户空间的无用的数据包复制行为。它最初是由从用户空间注入到内核的一个简单的字节码构成,它在那个位置利用一个校验器进行检查 —— 以避免内核崩溃或者安全问题 —— 并附着到一个套接字上,接着在每个接收到的包上运行。几年后它被移植到 Linux 上,并且应用于一小部分应用程序上(例如,tcpdump)。其简化的语言以及存在于内核中的即时编译器(JIT),使 BPF 成为一个性能卓越的工具。
eBPF (extended BPF),2013 年,Alexei Starovoitov 对 BPF 进行彻底地改造,并增加了新的功能,改善了它的性能,这个新版本被命名为 eBPF。随后的发展BPF程序可被附着在越来越多的接口上(kprobe,tracepoint,perf_event,xdp...)。其应用主要集中在两个领域,1.网络编程,2.内核跟踪。
BPF Compiler Collection https://github.com/iovisor/bcc , 基于bpf的内核跟踪工具
https://github.com/iovisor/bpftrace , 基于bpf的内核跟踪工具
https://github.com/wkz/ply , 基于bpf的轻量级内核跟踪工具
https://github.com/brendangregg/perf-tools ,基于ftrace 接口封装的脚本工具集,简化kprobe uprobe tracepoint 的使用,提供一些常用的分析脚本iolatency,opensnoop,cachestat,funccount 等。可用于bpf 工具的补充,以及当bpf报错时可利用ftrace排查问题。
https://sourceware.org/systemtap/ , 封装kprobe uprobe等API,以.ko形式动态加载跟踪代码,实现跟踪。可通过脚本进行复杂的跟踪逻辑开发,提供一些常用分析函数。