04CPU使用率分析-Linux性能优化

Posted by 刘勇(lyonger) on 2019-11-30

节拍率

  • 为了维护CPU时间,Linux通过事先定义的节拍率(内核中表示HZ)来触发时间中断,并使用全局变量Jiffies来记录开机以后的节拍次数。每发生一次时间中断,jiffies的值就加1.
  • 节拍率HZ是内核的可配置参数,可以设置为100、250、1000等。而用户空间的节拍率USER_HZ固定为100,你可以通过/boot/config内核选项来查看。
1
grep 'CONFIG_HZ' /boot/config-$(uname -r)
  • 以下展示率各个CPU的节拍率,一般性能分析工具给出的都是间隔一段时间的平均CPU使用率,比如top是每隔3秒的平均值,PS使用的是整个进程的生命周期。
1
2
3
4
5
6
# 只保留各个 CPU 的数据
$ cat /proc/stat | grep ^cpu
# 第一行表示的是所有CPU的累加,其他则是不同场景下CPU的累加节拍数,单位是USER_HZ(1/100秒)
cpu 280580 7407 286084 172900810 83602 0 583 0 0 0
cpu0 144745 4181 176701 86423902 52076 0 301 0 0 0
cpu1 135834 3226 109383 86476907 31525 0 282 0 0 0

CPU使用率高如何定位?

  • 通过top、ps、pidstat定位具体是哪个进程的CPU高,是内核态还是用户态占用高。那如果找到了哪个进程占用CPU高,那如何定位到是哪个函数占用CPU高呢?
  • 我们一般不建议直接在线上环境使用GDB或者STRACE命令,毕竟会临时中断程序,那么我们可以使用perf命令来分析,工具安装:
1
2
#perf工具安装
sudo apt install linux-tools-common
  • perf top命令类似于top,它能够实时显示占用CPU时钟最多的函数或者指令,用来查找热点函数,如下界面:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
$ perf top
Samples: 833 of event 'cpu-clock', Event count (approx.): 97742399
Overhead Shared Object Symbol
7.28% perf [.] 0x00000000001f78a4
4.72% [kernel] [k] vsnprintf
4.32% [kernel] [k] module_get_kallsym
3.65% [kernel] [k] _raw_spin_unlock_irqrestore

#如果采用太少,比如几十个的话,参考意义不大。
#第一行包含三个数据,分别是采样数(Samples)、事件类型(event)、时间总数量(Event count),这个例子中perf总共采集了833个CPU时钟事件、总事件数则为97742399。
#第一列Overhead:代表该符合的性能事件在所有采用中的比例,用百分比表示。
#第二列Shared:该函数或者指令所在的动态共享对象,如内核、进程名、动态链接库名、内核模块等。
#第三列Object:动态共享对象的类型,比如[.]代表用户空间的可执行程序或者动态链接库,而[k]则表示内核空间。
#第四列Symbol:符号名,也就是函数名,当函数名未知时,用十六进制的地址表示。
  • perf top不能离线分析,我们可以使用perf record top -g -p pid来进行采用,-g参数开启调用关系采用,在report中按方向键选中并回车可看到调用关系。
1
2
3
4
$ perf record # 按 Ctrl+C 终止采样
[ perf record: Woken up 1 times to write data ]
[ perf record: Captured and wrote 0.452 MB perf.data (6093 samples) ]
$ perf report # 展示类似于 perf top 的报告

如果找不到哪个进程CPU使用率高?

  • 碰到无法解释的CPU使用率情况时,首先要想到有可能是短时应用导致的问题,比如有下面2情况:
    • 应用里直接调用了其他二进制程序,这些程序通常运行时间比较短,通过top等工具不容易发现。
    • 应用本身在不停地奔溃重启,而启动过程地资源初始化,很可能会占用相当多地CPU。
  • 对于这种情况,我们可以用pstree或者execsnoop找到它们地父进程,再从父进程所在应用入手,排查问题。

小结

  • 用户CPU和Nice CPU高,说明用户态进程占用CPU高,所以重点排查进程的性能问题。
  • 系统CPU高,说明内核态占用CPU高,应重点排查内核线程或者系统调用的性能问题。
  • I/O等待CPU高,说明等待I/O的时间比较长,应该重点排查系统存储是否有瓶颈。
  • 软中断或者硬中断高,说明软中断或者硬中断处理程序占用CPU高,应该重点排查内核的中断服务程序。

推荐阅读



支付宝打赏 微信打赏

赞赏一下