Linux 性能分析 60 秒
下表用于 Linux 服务器出现问题之后,快速排查和诊断问题的原因。
| command | summary | chapter | |
|---|---|---|---|
| uptime | 查看 1 分钟、5 分钟、15 分钟的负载(load)的平均值 | 6.6.1 | |
| dmesg -T | tail | 查看是否包括 OOM 等事件的内核错误 | 7.5.11 |
| vmstat -SM 1 | 查看运行队列长度、swap、内存、io、CPU 等总体情况 | 7.5.1 | |
| mpstat -P ALL 1 | 按照每个 CPU(核数)为粒度统计 CPU 负载情况,可以定位单个 CPU 是否繁忙从而决定是否线程的扩展性较差 | 6.6.3 | |
| pidstat 1 | 统计每个进程 CPU 使用情况,用于识别意外的 CPU 消费者,以及每个进程的用户的 sys/usr 使用时间 | 6.6.7 | |
| iostat -xz 1 | 磁盘 I/O 统计:IOPS、吞吐量、平均等待时间 | 9.6.1 | |
| free -m | 显示内存使用情况,包括文件系统和缓存 | 8.6.2 | |
| sar -n DEV 1 | 网络设备 I/O:数据包和吞吐量 | 10.6.6 | |
| sar -n TCP,ETCP 1 | TCP统计:连接率、重传情况 | 10.6.6 | |
| top | 系统概览 | 6.6.6 |
方法
本章主要介绍性能优化的方法,包括一些背景知识:概念、术语、统计数据和可视化,涵盖了后面章节深入到实施之前的相关理论知识。
目标
- 了解关键性能指标:延时(lantency)、使用率、饱和度。
- 培养对测量时间速度的感觉,精确到 ns 。
- 学习调优的权衡、目标、以及何时停止分析。
- 识别是工作负载的问题,还是架构问题。
- 考虑资源分析与工作负载分析。
- 使用不同的性能方法,包括:USE 方法、工作负载特征归纳、延时分析、静态性能调优和性能箴言。
- 理解统计学和排队理论的基本知识。
核心术语
- IOPS:每秒发生的输入/输出操作的次数,是数据传输率的一种度量方法,对于磁盘的读写, IOPS 指的是每秒读和写的次数。
- 吐吞量:评价工作执行的速率,尤其是在数据传输方面,这个术语用于描述数据传输的速度(byte/s 或 bit/s)。在某些情况下(如数据库),吞吐量指的是操作的速度(每秒操作数或每秒业务数,qps or tps)。
- 响应时间:完成一次操作的时间。包括用于等待和服务的时间,也包括用来返回结果的时间。
- 延时:延时是描述操作中用来等待服务的时间。在某些情况下,它指的是整个操作时间,等同于响应时间。例子参见 2.3 节。
- 使用率:对于服务所请求的资源,使用率描述在给定的时间区间内资源的繁忙程度。对于提供存储的资源来说,使用率指的就是所消耗的存储容量(例如,内存使用率)。
- 饱和度:指的是某一资源无法提供服务的工作的排队程度。
- 瓶颈:在系统性能里,瓶颈指的是限制系统性能的那个资源。分辨和移除系统瓶颈是提高系统性能的一项重要工作。
- 工作负载:系统的输入或者是对系统所施加的负载叫作工作负载。对于数据库来说,工作负载就是客户端发出的数据库请求和命令。
- 缓存:用于复制或者缓冲一定量数据的高速存储区域,目的是为了避免对较慢的存储层级的直接访问,从而提高性能。出于经济考虑,缓存区的容量要比更慢一级的存储容量小。
概念
延时的时间量级(相对时间比例)
| 事件 | 延时 | 相对时间比例 |
|---|---|---|
| 1 个 CPU 时钟周期 | 0.3 ns | 1s |
| L1 cache 访问 | 0.9 ns | 3s |
| L2 cache 访问 | 3 ns | 10s |
| L3 cache 访问 | 10 ns | 33s |
| 主存访问(从 CPU 访问 DRAM) | 100 ns | 6分钟 |
| 固态硬盘 I/O(闪存) | 10 ~ 100 us | 9 ~ 90 小时 |
| 旋转硬盘 I/O | 1 ~ 10 ms | 1 ~ 12 月 |
| 互联网网络访问:从旧金山到纽约 | 40 ms | 4 年 |
| 互联网网络访问:从旧金山到英国 | 81 ms | 8 年 |
| 轻量级硬件虚拟化重启 | 100 ms | 11 年 |
| 互联网网络访问:从旧金山到澳大利亚 | 183 ms | 19 年 |
| 操作系统虚拟化系统重启 | 小于 1 s | 105 年 |
| 基于 TCP 定时器的重传 | 1 ~ 3 s | 105 ~ 317 年 |
| SCSI 命令超时 | 30 s | 3000 年 |
| 硬件虚拟化系统重启 | 40 s | 4000 年 |
| 物理系统重启 | 5 m | 32000 年 |
可以看出,1 个 CPU 周期的时间是非常短暂的。从硬盘到网络访问,相对于 CPU 时钟周期都太慢了。
关于投资回报率
书中举了一个例子,从纽约交易所和伦敦交易所的直连光缆正在规划当中,花费预计 3 亿美元,只为了减少 6ms 的传输延迟。
amalgamated-contemplation.com/2011/09/13/…
决策何时停止进行性能分析?
- 当你已经分析出了大部分性能问题时,例如占比超过 66%,就没有必要纠结于剩下的 33% 了。
- 当潜在的投资回报率低于分析问题的成本时。
- 当其它地方有更大的投资回报率时。
缓存
命中率 = 命中次数 / (命中次数 + 失效次数)
失效率:表示每秒缓存失效的次数。
两者之间的关系和比较:假设 A 和 B 两个程序同时实现了缓存硬盘当中的数据功能。 A 的命中率为 90%, B 的命中率为 80%,那是否意味着 A 一定比 B 要更好了?答案是否定的,引入失效率这个指标之后,A 的失效率是 200次/s,而 B 为 20次/s,因此 B 执行的磁盘读取次数比 A 少 10 倍,因此 B 的性能会更好。
因此,我们需要根据总的运行时间来进行衡量。
总的运行时间 = (命中率 * 命中延迟)+ (失效率 * 失效延迟)
算法
MRU(最近最常使用算法):指的是一种缓存保留策略。 LRU(最近最少使用算法):指的是一种缓存回收策略。 MFU(最常使用算法) LFU(最不常使用算法)
缓存的热、冷、温
冷:冷缓存通常是空的,或者是缓存了一些无效的数据,命中率接近于 0。 热:已经包含了最常用的数据,并且有着很高的缓存命中率,例如:超过 99%。 温:已经填充了部分有用的数据,但是缓存命中率还未达到预想的高度。 热度:指的是缓存偏向于热或者冷。
对于缓存系统,“冷启动”,即在访问缓存之前,能够尽快地将其变为热缓存,是需要重点考虑和评估的。可以使用缓存预热方案,但需要考虑预热完成的时间。
一个例子,有一个 128GB DRAM 服务器作为文件系统的缓存,600GB SSD 作为二级缓存,HHD 作为最底层的存储器。假设缓存预热程序采用随机读写的方式,每秒读操作约 2000 次,按照 8KB 的 I/O 大小,这意味着变温的速度仅为 16MB/s,600GB 二级缓存需要 10 小时完成预热,128GB 一级缓存需要 2 小时完成预热。
哲学启示
1、已知的已知:有些东西你知道。例如,你知道使用
lscpu查看 CPU 基本信息。 2、已知的未知:有些东西你明确的知道你自己还不知道。例如,你知道能够用 profile 去检查是什么导致 CPU busy,但是你还未做这件事情。 3、未知的未知:有些东西你不知道自己不知道。例如,你不知道过多的中断调用会导致消耗大量的 CPU,因此就没有去做检查。 "在性能领域,你知道的越多,你不知道的就越多"(其它领域也类似)
值得借鉴和学习的方法
Ad Hoc 核对清单法
团队当中可以积累一些性能诊断的 check list,例如:“运行 iostat -x 1 检查 r_await 列。如果该列持续超过 10(单位:ms),那么说明原因有可能是磁盘太慢或是磁盘负载过高”。
USE 方法
USE (utilization、saturation、errors)方法,简而言之就是:对所有的资源,查看它的使用率、饱和度和错误。
- 资源:硬件或软件资源,CPU、内存...
- 使用率:在规定的时间间隔内,资源用于服务工作的时间百分比。需要注意的是使用率高并意味着有性能瓶颈,只要还能够接收工作的任务并能够正常工作就行。反之,不能接受更多工作的程度被称为饱和度(也可以认为是“系统压力”)。
- 饱和度:资源不能再服务额外更多工作的程度,通常的表现是等待队列里面有很多任务在进行排队。**。
- 错误:错误事件的个数。
查看任何指标时,需要警惕某些监测工具返回的一段时间的均值,这样有可能会带来问题是,无法从数据上判断出某个特定的时间段内单个指标值非常高的情况。
大致流程:列出需要检测的资源->查看 error->查看饱和度->查看使用率。
可以通过 Gregg 的官网进一步学习各种资源下,使用 USE 方法的详细分析手段:www.brendangregg.com/USEmethod/u…
介绍了 netflix 使用 USE 方法和 Altas 工具对微服务进行监测: netflixtechblog.com/introducing…
RED 方法(Rate、Error、Duration)
一种专门为微服务架构而设计的,尤其是针对于 cloud native 当中的微服务进行监控。对于每个服务,检查清秀率、错误和持续时间。
- 请求率:每秒服务请求数量。
- 错误:失败的请求数。
- 持续时间:请求完成的时间。(除了平均数,还需要使用分布统计,如百分位数)
由 Tom Wilkie 创建的,为 Prometheus 开发了 USE 和 RED 方法的实现,并集成到了 Grafana 当中。
github.com/Netflix/vec… 这是 netfilx 的一套性能监控和可视化框架,不过根据 github 上的最新说明,该项目已经合并至 pcp.io/index.html
FlameScope is a visualization tool for exploring different time ranges as Flame Graphs, allowing quick analysis of performance issues such as perturbations, variance, single-threaded execution, and more. github.com/Netflix/fla…
上述 3 个工具结合起来使用流程。使用 Atlas 识别出一个有问题的微服务,然后使用 vector 进行一步缩小范围至某个资源上,并使用 flamescope 分析出消耗该资源的代码位置,最后使用 github.com/iovisor/bcc 工具和自定义 bpftrace 工具进行检测。
BCC 的安装方法
什么是 BCC? BCC工具全称BPF Compiler Collection (BCC),是一个很强大的库,强大的内核分析工具eBPF就是基于BCC开发的,利用这个库可以从底层获取操作系统性能信息,网络性能信息等许多与内核交互的信息。bcc 的设计初衷是为了方便的创建高效内核跟踪和操作程序的工具包,包括一些开箱即用的工具和示例。 它基于 eBPF 开发(需要 Linux 3.15 及更高版本)。 bcc 使用的大部分内容都需要 Linux 4.1 及更高版本。
更多资料:
ebpf & bcc 中文教程及手册 blog.cyru1s.com/posts/ebpf-…
ebpf 简史 linux.cn/article-903… :完整地介绍 BPF(BSD/Berkeley Packet Filter)的来龙去脉。
BCC 工具官网 github.com/iovisor/bcc…
安装方法
注意:eBPF 需要较新的 Linux kernel 支持。 因此首先要确保你的内核版本足够新,至少要在 4.1 以上,最好在 4.10 以上。
ref: bcc/ebpf 安装及示例(2019)arthurchiao.art/blog/bcc-eb…
ubutun 下安装
uname -r
5.4.0-42-generic
更换镜像源,否则安装下载速度过慢。
# backup source image file
sudo cp /etc/apt/sources.list /etc/apt/sources.list.bak
sudo vim /etc/apt/sources.list
更换内容如下:
#添加阿里源
deb <http://mirrors.aliyun.com/ubuntu/> focal main restricted universe multiverse
deb-src <http://mirrors.aliyun.com/ubuntu/> focal main restricted universe multiverse
deb <http://mirrors.aliyun.com/ubuntu/> focal-security main restricted universe multiverse
deb-src <http://mirrors.aliyun.com/ubuntu/> focal-security main restricted universe multiverse
deb <http://mirrors.aliyun.com/ubuntu/> focal-updates main restricted universe multiverse
deb-src <http://mirrors.aliyun.com/ubuntu/> focal-updates main restricted universe multiverse
deb <http://mirrors.aliyun.com/ubuntu/> focal-proposed main restricted universe multiverse
deb-src <http://mirrors.aliyun.com/ubuntu/> focal-proposed main restricted universe multiverse
deb <http://mirrors.aliyun.com/ubuntu/> focal-backports main restricted universe multiverse
deb-src <http://mirrors.aliyun.com/ubuntu/> focal-backports main restricted universe multiverse
#添加清华源
deb <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal main restricted universe multiverse
# deb-src <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal main restricted universe multiverse
deb <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal-updates main restricted universe multiverse
# deb-src <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal-updates main restricted universe multiverse
deb <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal-backports main restricted universe multiverse
# deb-src <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal-backports main restricted universe multiverse
deb <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal-security main restricted universe multiverse
# deb-src <https://mirrors.tuna.tsinghua.edu.cn/ubuntu/> focal-security main restricted universe multiverse multiverse
刷新镜像源:sudo apt-get update
安装 bcc:sudo apt-get install bpfcc-tools linux-headers-$(uname -r)
查看 bcc 工具相关命令:
find / | bpfcc
# output
/usr/sbin/filelife-bpfcc
/usr/sbin/javathreads-bpfcc
/usr/sbin/cachestat-bpfcc
/usr/sbin/funclatency-bpfcc
/usr/sbin/cobjnew-bpfcc
/usr/sbin/ext4dist-bpfcc
/usr/sbin/trace-bpfcc
/usr/sbin/tclcalls-bpfcc
/usr/sbin/criticalstat-bpfcc
/usr/sbin/llcstat-bpfcc
/usr/sbin/tcptracer-bpfcc
/usr/sbin/dcsnoop-bpfcc
/usr/sbin/softirqs-bpfcc
/usr/sbin/javaflow-bpfcc
/usr/sbin/rubyflow-bpfcc
/usr/sbin/execsnoop-bpfcc
/usr/sbin/tcpsubnet-bpfcc
/usr/sbin/pythonstat-bpfcc
/usr/sbin/tcpconnect-bpfcc
/usr/sbin/pythongc-bpfcc
/usr/sbin/syscount-bpfcc
/usr/sbin/dbstat-bpfcc
/usr/sbin/gethostlatency-bpfcc
/usr/sbin/dcstat-bpfcc
/usr/sbin/profile-bpfcc
/usr/sbin/cpudist-bpfcc
/usr/sbin/argdist-bpfcc
/usr/sbin/rubycalls-bpfcc
/usr/sbin/nodegc-bpfcc
/usr/sbin/pidpersec-bpfcc
/usr/sbin/syncsnoop-bpfcc
# 省略...
测试一个命令:
biosnoop-bpfcc
# output
TIME(s) COMM PID DISK T SECTOR BYTES LAT(ms)
2.203901 dd 197126 sda R 29252744 131072 0.07
2.204265 dd 197126 sda R 29253000 131072 0.05
2.204549 dd 197126 sda R 29253256 131072 0.05
2.204831 dd 197126 sda R 29253512 131072 0.05
2.205221 dd 197126 sda R 29253768 131072 0.06
2.205660 dd 197126 sda R 29254024 131072 0.05
2.205944 dd 197126 sda R 29254280 131072 0.05
2.206238 dd 197126 sda R 29254536 131072 0.07
2.206526 dd 197126 sda R 29254792 131072 0.05
2.206859 dd 197126 sda R 29255048 131072 0.06
微基准测试
微基准测试是测量的最简单人造场景的工作负载性能,它与宏观基准测试不同,后者通常是在测试真实世界的工作负载。
微基准测试由于干涉因素很少,所以在执行和理解上都相对简单。一个常用的微基准测试是 Linux iperf,可用它执行 TCP 吞吐量测试,用于检查相关负载下 TCP 计数器从而识别外部网络的瓶颈。
下面是一些典型的微基准测试示例:
- 系统调用时间:fork(2)\execve(2)\open(2)
- 文件系统读取:从缓存过的文件读取,读取的数据大小从 1B 变化到 1MB
- 网络吞吐量:针对于不同的 socket 缓冲区的尺寸测试 TCP 端对端数据传输