基础知识
平均负载 => 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)需求不是一成不变的。针对当前情况进行的优化,很可能并不适应快速变化的新需求