「Linux Performance」- 处理器性能排查(经验总结)

基础知识

平均负载 => Load Average

上下文切换(自愿、非自愿) => Context switch

处理器使用率(相关指标) => CPU utilization

不可中断进程、僵尸进程 => Linux process states

软中断 => interrupts and softirqs

处理器缓存命中率、

排查工具

经验总结

第一步、检查平均负载

当系统平均负载较高时,使用 mpstat -P ALL 查看负载较高的原因(比如 usr、sys、iowait 比例),以确定是进程数过度,还是 IO 压力较大。

然后使用 pidstat -u 查看进程的处理器资源使用情况,定位使用处理器资源较多的进程。

=> 接下来要确定为什么进程会使用过多资源(CPU 或 I/O)

第二步、检查上下文切换

使用 vmstat 查看上下文切换状态、运行中进程数量、不可中断进程数量、中断次数,找到数据异常的地方。比如:进程数远高于处理器数,会带来负载;上下问切换数量过高带来的负载;如果中断次数过多,查看 /proc/interrupts分析中断类型;

通过 /proc/softirqs 与 /proc/interrupts 了解中断信息。

然后使用 pidstat -w -t 查看进程(及线程)的上下文切换情况,关注 自愿上下文切换(等待资源) 与 非自愿上下文切换(进程争抢) 数量。

=> 接下来要分析,资源使用在那些地方(分析应用的函数调用)

第三步、分析函数调用

使用 perf record -g 和 perf report -g 查看函数调用,找到占用资源最多的函数调用。

第四步、追查系统调用

使用 strace -f -p 追踪系统调用,查看进程的参数设置。

其他问题排查

使用率高,但是无法找到相关应用:程序运行时间短;程序在频繁的重启;

处理器的性能指标及检查工具

性能分析的工具选择

从性能指标出发,确定可用工具

load average => uptime / top

cpu utilization => vmstat / mpstat / top / sar / /proc/stat

process cpu utilzation => top / pidstat / ps / htop / atop

system context switch => vmstat

process context switch => pidstat

softirqs => top / /proc/softirqs / mpstat

interrupts => vmstat / /proc/interrupts

networking => dstat / sar / tcpdump

I/O => dstat / sar

the number of cpu => lscpu / /proc/cpuinfo

events => perf / execsnoop

从可用工具出发,明确检测指标

uptime => 平均负载

top => 平均负载,运行队列,整体处理器使用率,进程状态及进程的处理器使用率

htop => top 的增强版本,显示更加直观

atop => 各种资源的全面监控

vmstat => 系统整体的处理器使用率、上下文切换次数、中断次数,以及运行和不可终端的进程数

mpstat => 每个处理器的使用率,软中断次数

pidstat => 进程和线程的处理器使用率、中断及上下文切换次数

/proc/softirqs => 软中断类型,及处理器累计的中断次数

/proc/interrupts => 硬中断类型,及处理器上累计的中断次数

ps => 进程状态,处理器使用率等等

pstree => 进程的父子关系

dstat => 系统整体的处理器使用率

sar => 系统整理的处理器使用率,包括可配置的历史数据

strace => 进程的系统调用

perf => 处理器性能事件刨析,如调用链,CPU 缓存,CPU 调度

execsnoop => 监控短时进程,exec 系统调用

如何迅速分析 CPU 的性能瓶颈

虽然 CPU 的性能指标比较多,但既然都是描述系统的 CPU 性能,它们就不会是完全孤立的,很多指标间都有一定的关联。想弄清楚性能指标的关联性,就要通晓每种性能指标的工作原理。

例如,用户 CPU 使用率高,我们应该去排查进程的用户态而不是内核态。因为用户 CPU 使用率反映的就是用户态的 CPU 使用情况,而内核态的 CPU 使用情况只会反映到系统 CPU 使用率上。

top、vmstat、pidstat 几乎包含了所有重要的 CPU 性能指标

性能优化方法论

1)如何判断性能优化是否有效,优化后,到底能提升多少性能
2)如果有多个性能问题同时发生,你应该先优化哪一个
3)当有多种方法可以选择时,应该选择哪种方案

如何评估性能优化的效果?

1)确定性能的量化指标
不要局限在单一维度的指标上:应用程序的维度,我们可以用吞吐量和请求延迟来评估应用程序的性能;系统资源的维度,我们可以用 CPU 使用率来评估系统的 CPU 使用情况;

2)测试优化前的性能指标

3)测试优化后的性能指标

多个性能问题同时存在

并不是所有的性能问题都值得优化,找出最重要的、可以最大程度提升性能的问题

有多种优化方法时,要如何选择

一般情况下,我们当然想选能最大提升性能的方法,这其实也是性能优化的目标。

最直观来说,性能优化并非没有成本。也就是说,很可能你优化了一个指标,另一个指标的性能却变差了。

所以,在考虑选哪个性能优化方法时,你要综合多方面的因素。

应用程序和系统资源

应用程序优化

应用程序的性能优化也包括很多种方法:
1)编译器优化
2)算法优化
3)异步处理,使用异步处理,可以避免程序因为等待某个资源而一直阻塞,从而提升程序的并发处理能力。比如,把轮询替换为事件通知,就可以避免轮询耗费 CPU 的问题
4)多线程代替多进程,降低上下文切换的成本
5)善用缓存,加快程序的处理速度

系统资源优化

系统层面的 CPU 优化方法也有不少:
1)CPU 绑定:把进程绑定到一个或者多个 CPU 上,可以提高 CPU 缓存的命中率,减少跨 CPU 调度带来的上下文切换问题
2)CPU 独占:跟 CPU 绑定类似,进一步将 CPU 分组,并通过 CPU 亲和性机制为其分配进程。这样,这些 CPU 就由指定的进程独占,换句话说,不允许其他进程再来使用这些 CPU。
3)优先级调整:使用 nice 调整进程的优先级,正值调低优先级,负值调高优先级。
4)为进程设置资源限制:使用 Linux cgroups 来设置进程的 CPU 使用上限,可以防止由于某个应用自身的问题,而耗尽系统资源。
5)NUMA(Non-Uniform Memory Access)优化:支持 NUMA 的处理器会被划分为多个 node,每个 node 都有自己的本地内存空间。NUMA 优化让 CPU 尽可能只访问本地内存。
6)中断负载均衡:软中断、硬中断的中断处理程序都可能会耗费大量的 CPU。开启 irqbalance 服务或者配置 smp_affinity 可以把中断处理过程自动负载均衡到多个 CPU 上。

千万避免过早优化

1)优化会带来复杂性的提升,降低可维护性;
2)需求不是一成不变的。针对当前情况进行的优化,很可能并不适应快速变化的新需求