服务端优化系统-CPU

[toc]

服务端优化系统-CPU

CPU占用率高的解决思路

CPU使用率

Linux作为一个多任务操作系统,将每个CPU时间划分成很短的时间片段,再通过调度器轮流分配给各个任务使用,造成多任务同时运行的错觉。

Linux使用节拍率(HZ)来维护CPU时间,每次触发时间中断,Jiffies变量会加一。Jiffies是一个全局变量,记录的是开机以来的节拍数。我们可以通过查询/boot/config-$(uname -r)内核文件来查看节拍率, 可以看到我主机的节拍率是250HZ,也就是每秒会触发250次时间中断。

grep '' /boot/config-$(uname -r)  - 查询所有参数

grep 'CONFIG_HZ=' /boot/config-$(uname -r) - 节拍率查询
CONFIG_HZ=1000

但是由于节拍率是内核选项参数,用户空间不能直接访问。为了方便用户空间程序,内核提供一个用户空间的节拍率USER_HZ,USER_HZ总是等于100,也就是1/100秒。

不同场景的CPU使用率含义

mpstat

下面主要介绍一下几个常用的场景:

  • user(us, usr): 表示用户态时间。不包括nice时间
  • nice(ni): 表示低优先级用户态时间.
  • system(sys): 内核态CPU时间
  • idle: 空闲时间。不包含等待IO时间(iowait)
  • iowait(wa): 等待IO的CPU时间
  • irq(hi): 处理硬件中断的CPU时间
  • sofirq(si): 处理软中断的CPU时间

CPU使用率的计算公式

查看/proc/stat文件查看相关的CPU时间信息

cat /proc/stat

man proc查看相关类字段说明

man proc

根据说明,我们可以知道,这些数值的单位是100HZ,以及各个场景的CPU时间(开机以来的总时间)

根据这些数据,我们可以很轻易的算出各个场景的平均CPU使用率。

CPU 使用率 = 1 - (空闲时间 / 总 CPU 时间)

但是由于/proc/stat中的数据是自开机以来的总时间,不能准确的表示当前CPU的平均使用率,所以为了准确表示CPU的平均的使用率,我们需要取一段小的时间间隔的两次值,做差后,在计算出这段时间内的平均CPU使用率, 即:

平均CPU使用率 = 1 - (空闲时间new - 空闲时间old) / (总CPU时间new - 总CPU时间old)

查看平均使用率

使用top查看系统平均CPU使用率和进程的CPU平均使用率

$ top

使用ps查看进程的CPU平均使用率

$ ps -aux

使用pidstat查看进程的CPU平均使用率

$ pidstat -u

使用mpstat查看系统平均CPU使用率和各个逻辑CPU平均使用率(指标最全)

$ mpstat -P ALL

基础命令

查询CPU,具体多少核,频率,型号,特性等


cat /proc/cpuinfo

查看CPU内存频率

cat /proc/cpuinfo |grep MHz|uniq

查看内存

cat /proc/meminfo

查看当前内存大小,已用空间等

dmidecode -t memory

查看系统运行时间(单位:秒):


cat /proc/uptime

查看内核IO地址映射:

cat /proc/iomem

查看上一次登陆:

last /var/log/wtmp

如果不存在,直接 touch 生成。可用 rm 删除

查看内核版本:


cat /proc/version

查看内核函数:

cat /proc/kallsyms

查看系统启动参数:

cat /proc/cmdline

磁盘信息(这个文件一般人看不懂,有工具就是分析这个文件得到磁盘性能信息的):

cat /proc/diskstats

查看中断:

cat /proc/interrupts

清空内存:

echo 2 > /proc/sys/vm/overcommit_memory

案例分析(CPU使用率过高怎么办?)

安装perf

CentOS/RHEL 安装

yum install perf 安装出错可以走下边命令

yum update && yum install perf

perf -v
perf version 3.10.0-1160.6.1.el7.x86_64.debug

Ubuntu 安装 16.04

  • 安装老失败
# 第一种
apt update && apt upgrade
apt-get install linux-tools-common linux-tools-generic linux-cloud-tools-generic linux-tools-`uname -r`

perf

apt install linux-tools-common

sudo apt-get install linux-tools-4.4.0-117-generic linux-cloud-tools-4.4.0-117-generic linux-tools-generic linux-cloud-tools-generic



# 第二种
要获得最新版本的perf而不考虑内核版本(perf版本独立于内核版本):
git clone https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
cd linux/tools/perf
make
cp perf /usr/bin

perf --version
perf version 4.18.20

通过我们上面提及的相关工具找出CPU使用率高的进程之后,我们需要知道这个进程中的哪个函数占用了过高的CPU,然后才能更高效、更有针对性的进行优化。

下面主要介绍一款相关的分析工具perf.

perf 以性能事件采样为基础,不仅可以分析系统的各种事件和内核性能,还可以用来分析指定应用程序的性能问题。

perf每隔一个固定的时间,就在CPU上(每个核上都有)产生一个中断,在中断上看看,当前是哪个pid,哪个函数,然后给对应的pid和函数加一个统计值,这样,我们就知道CPU有百分几的时间在某个pid,或者某个函数上了。

我们主要使用perf一下命令:

# 实时显示占用CPU时间最多的函数或指令及调用关系
$ perf top -g 

由于perf top不能保存数据,不能用于离线后者后续的分析,perf提供了另外两个命令:

  • perf record: 记录系统的性能信息,退出后,将数据保存在执行命令的当前文件夹的perf.data文件中
  • perf report: 展示perf record命令记录的数据

字段说明:

  • symbol: 符号名,也就是函数名,当函数名未知时,使用16进制地址表示
  • Children: 表示该符号名下调用函数性能事件在所有采样中的比例

我们主要关注上述的两个指标,找出占比最高的行,即可确定CPU占用最高的函数,然后就可以去应用程序源码中寻找,然后进行相关优化。

测试Web服务器的服务性能

# 并发10个请求测试Nginx性能,总共测试100个请求
$ ab -c 10 -n 100 http://Web服务器IP:10000/

为了持续的给Nginx服务器增压,我们使用以下命令,并发10个请求,持续10分钟

$ ab -c 10 -t 600 http://Web服务器IP:10000/

然后我们在Nginx服务器使用perf命令查找php-fpm进程中,占用CPU最多的函数

$ sudo perf top -g

perf report 可以查看具体的占用率高的函数

因为短时应用就可以导致这样的问题:

应用里直接调用了其他的二进制程序,这些程序运行时间通常较短,通过top等工具很难发现 应用本身在不停的崩溃重启,而启动过程的资源初始化,可能会占用相当多的CPU. 这类问题的分析方法:

使用perf top或者execsnoop命令找出短时进程 通过pstree命令查找短时进程的父进程,最后对其父进程进行相关的分析和优化.

模拟 Nginx 压力

我们以 Nginx + PHP 的 Web 服务为例,来看看当你发现 CPU 使用率过高的问题后,如何使用 top 等工具找出异常进程,又如何利用 perf 找出引发性能问题的函数。

# 并发 10 个请求测试 Nginx 性能,总共测试 100 个请求
$ ab -c 10 -n 100 http://192.168.0.10:10000/
This is ApacheBench, Version 2.3 <$Revision: 1706008 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, 
...
Requests per second:    11.63 [#/sec] (mean)
Time per request:       859.942 [ms] (mean)
...

可以发现 Nginx 的处理能力很差,通过 top 命令分析,得知 php-fpm 进程导致,接下来我们使用 perf 来分析一下具体哪些函数导致 CPU 高。

-g 开启调用关系分析,-p 指定 php-fpm 的进程号 21515

$ perf top -g -p 21515

通过 perf 分析到耗时严重的函数,再结合源代码进行定位分析,找出问题原因即可。

小结

我们需要弄清楚各个场景下各个CPU使用率指标用户的含义,这个会给我们分析问题的时候提供一个很明确的方向。

CPU 使用率是最直观和最常用的系统性能指标,更是我们在排查性能问题时,通常会关注的第一个指标。所以我们要搞清楚 user、nice、system、iowait、irq、sortirq 这几种不同 CPU 的使用率,比如说:

  • 用户CPU或者nice CPU很高,说明用户态进程占用CPU较多,应该重点排查进程的性能问题
  • 系统CPU过高,说明内核态占用较多的内存,应该重点排查内核线程或者系统调用的性能问题
  • IO等待CPU过高,说明IO等待时间过长,应该重点排查系统存储IO、网络IO是否除了问题
  • 软中断、硬件中断CPU过高,说明中断处理程序占用了过多的CPU,应该重点排查内核中的中断服务程序

参考文章

胡梦旭博客
请先登录后发表评论
  • latest comments
  • 总共0条评论