热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

​LinuxCPU性能优化指南

本文作者:allenxguo,腾讯QQ音乐后台开发工程师本文主要帮助理解CPU相关的性能指标,常见的CPU性能问题以及解决方案梳理。系统平均负载简介系统平均负载:是处于可运行或不可






本文作者:allenxguo,腾讯 QQ 音乐后台开发工程师


本文主要帮助理解 CPU 相关的性能指标,常见的 CPU 性能问题以及解决方案梳理。



系统平均负载



简介



系统平均负载:是处于可运行或不可中断状态的平均进程数。



可运行进程:使用 CPU 或等待使用 CPU 的进程



不可中断状态进程:正在等待某些 IO 访问,一般是和硬件交互,不可被打断(不可被打断的原因是为了保护系统数据一致,防止数据读取错误)



查看系统平均负载



首先 top
命令查看 进程运行状态
,如下:


PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

10760 user 20 0 3061604 84832 5956 S 82.4 0.6 126:47.61 Process

29424 user 20 0 54060 2668 1360 R 17.6 0.0 0:00.03 **top**


程序状态 Status
进程 可运行状态
R
不可中断运行
D
(后续讲解 top 时会详细说明)



top查看系统平均负载:


top - 13:09:42 up 888 days, 21:32, 8 users, load average: 19.95, 14.71, 14.01

Tasks: 642 total, 2 running, 640 sleeping, 0 stopped, 0 zombie

%Cpu0 : 37.5 us, 27.6 sy, 0.0 ni, 30.9 id, 0.0 wa, 0.0 hi, 3.6 si, 0.3 st

%Cpu1 : 34.1 us, 31.5 sy, 0.0 ni, 34.1 id, 0.0 wa, 0.0 hi, 0.4 si, 0.0 st

...

KiB Mem : 14108016 total, 2919496 free, 6220236 used, 4968284 buff/cache

KiB Swap: 0 total, 0 free, 0 used. 6654506 avail Mem


这里的 load average
就表示系统最近 1 分钟、5 分钟、15 分钟的系统瓶颈负载。



uptime查看系统瓶颈负载


[root /home/user]# uptime

13:11:01 up 888 days, 21:33, 8 users, load average: 17.20, 14.85, 14.10


查看 CPU 核信息


系统平均负载和 CPU 核数密切相关,我们可以通过以下命令查看当前机器 CPU 信息:



lscpu查看 CPU 信息:


[root@Tencent-SNG /home/user_00]# lscpu

Architecture: x86_64

CPU op-mode(s): 32-bit, 64-bit

Byte Order: Little Endian

CPU(s): 8

...

L1d cache: 32K

L1i cache: 32K

L2 cache: 4096K

NUMA node0 CPU(s): 0-7 // NUMA架构信息


cat /proc/cpuinfo查看每个 CPU 核的信息:


processor : 7 // 核编号7

vendor_id : GenuineIntel

cpu family : 6

model : 6

...


系统平均负载升高的原因



一般来说,系统平均负载升高意味着 CPU 使用率上升。但是他们没有必然联系,CPU 密集型计算任务较多一般系统平均负载会上升,但是如果 IO 密集型任务较多也会导致系统平均负载升高但是此时的 CPU 使用率不一定高,可能很低因为很多进程都处于不可中断状态, 等待 CPU 调度
也会升高系统平均负载。


所以假如我们系统平均负载很高,但是 CPU 使用率不是很高,则需要考虑是否系统遇到了 IO 瓶颈,应该优化 IO 读写速度。


所以系统是否遇到 CPU 瓶颈需要结合 CPU 使用率,系统瓶颈负载一起查看(当然还有其他指标需要对比查看,下面继续讲解)



案例问题排查



stress
是一个施加系统压力和压力测试系统的工具,我们可以使用 stress
工具压测试 CPU,以便方便我们定位和排查 CPU 问题。


yum install stress // 安装stress工具


stress 命令使用


// --cpu 8:8个进程不停的执行sqrt()计算操作

// --io 4:4个进程不同的执行sync()io操作(刷盘)

// --vm 2:2个进程不停的执行malloc()内存申请操作

// --vm-bytes 128M:限制1个执行malloc的进程申请内存大小

stress --cpu 8 --io 4 --vm 2 --vm-bytes 128M --timeout 10s

我们这里主要验证 CPU、IO、进程数过多的问题



CPU 问题排查



使用 stress -c 1
模拟 CPU 高负载情况,然后使用如下命令观察负载变化情况:



uptime:使用 uptime
查看此时系统负载:


# -d 参数表示高亮显示变化的区域

$ watch -d uptime

... load average: 1.00, 0.75, 0.39


mpstat:使用 mpstat -P ALL 1
则可以查看每一秒的 CPU 每一核变化信息,整体和 top
类似,好处是可以把每一秒(自定义)的数据输出方便观察数据的变化,最终输出平均数据:


13:14:53 CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle

13:14:58 all 12.89 0.00 0.18 0.00 0.00 0.03 0.00 0.00 0.00 86.91

13:14:58 0 100.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00

13:14:58 1 0.40 0.00 0.20 0.00 0.00 0.20 0.00 0.00 0.00 99.20

由以上输出可以得出结论,当前系统负载升高,并且其中 1 个核跑满主要在执行用户态任务,此时大多数属于业务工作。所以此时需要查哪个进程导致单核 CPU 跑满:



pidstat:使用 pidstat -u 1
则是每隔 1 秒输出当前系统进程、CPU 数据:


13:18:00 UID PID %usr %system %guest %CPU CPU Command

13:18:01 0 1 1.00 0.00 0.00 1.00 4 systemd

13:18:01 0 3150617 100.00 0.00 0.00 100.00 0 stress

...


top:当然最方便的还是使用 top
命令查看负载情况:


top - 13:19:06 up 125 days, 20:01, 3 users, load average: 0.99, 0.63, 0.42

Tasks: 223 total, 2 running, 221 sleeping, 0 stopped, 0 zombie

%Cpu(s): 14.5 us, 0.3 sy, 0.0 ni, 85.1 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st

KiB Mem : 16166056 total, 3118532 free, 9550108 used, 3497416 buff/cache

KiB Swap: 0 total, 0 free, 0 used. 6447640 avail Mem



PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND

3150617 root 20 0 10384 120 0 R 100.0 0.0 4:36.89 stress


此时可以看到是 stress
占用了很高的 CPU。



IO 问题排查



我们使用 stress -i 1
来模拟 IO 瓶颈问题,即死循环执行 sync 刷盘操作: uptime
:使用 uptime
查看此时系统负载:


$ watch -d uptime

..., load average: 1.06, 0.58, 0.37


mpstat:查看此时 IO 消耗,但是实际上我们发现这里 CPU 基本都消耗在了 sys 即系统消耗上。


Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle

Average: all 0.33 0.00 12.64 0.13 0.00 0.00 0.00 0.00 0.00 86.90

Average: 0 0.00 0.00 99.00 1.00 0.00 0.00 0.00 0.00 0.00 0.00

Average: 1 0.00 0.00 0.33 0.00 0.00 0.00 0.00 0.00 0.00 99.67

IO 无法升高的问题:



iowait 无法升高的问题,是因为案例中 stress 使用的是 sync()
系统调用,它的作用是刷新缓冲区内存到磁盘中。对于新安装的虚拟机,缓冲区可能比较小,无法产生大的 IO 压力,这样大部分就都是系统调用的消耗了。所以,你会看到只有系统 CPU 使用率升高。解决方法是使用 stress 的下一代 stress-ng,它支持更丰富的选项,比如 stress-ng -i 1 --hdd 1 --timeout 600
(--hdd 表示读写临时文件)。


Average: CPU %usr %nice %sys %iowait %irq %soft %steal %guest %gnice %idle

Average: all 0.25 0.00 0.44 26.22 0.00 0.00 0.00 0.00 0.00 73.09

Average: 0 0.00 0.00 1.02 98.98 0.00 0.00 0.00 0.00 0.00 0.00


pidstat:同上(略)



可以看出 CPU 的 IO 升高导致系统平均负载升高。我们使用 pidstat
查找具体是哪个进程导致 IO 升高的。



top:这里使用 top 依旧是最方面的查看综合参数,可以得出 stress
是导致 IO 升高的元凶。



pidstat 没有 iowait 选项:可能是 CentOS 默认的 sysstat
太老导致,需要升级到 11.5.5 之后的版本才可用。



进程数过多问题排查



进程数过多这个问题比较特殊,如果系统运行了很多进程超出了 CPU 运行能,就会出现等待 CPU 的进程。使用 stress -c 24
来模拟执行 24 个进程(我的 CPU 是 8 核) uptime
:使用 uptime
查看此时系统负载:


$ watch -d uptime

..., load average: 18.50, 7.13, 2.84


mpstat:同上(略)



pidstat:同上(略)



可以观察到此时的系统处理严重过载的状态,平均负载高达 18.50



top:我们还可以使用 top
命令查看此时 Running
状态的进程数,这个数量很多就表示系统正在运行、等待运行的进程过多。



总结


通过以上问题现象及解决思路可以总结出:




  1. 平均负载高有可能是 CPU 密集型进程导致的




  2. 平均负载高并不一定代表 CPU 使用率高,还有可能是 I/O 更繁忙了




  3. 当发现负载高的时候,你可以使用 mpstat、pidstat 等工具,辅助分析负载的来源





总结工具: mpstat
pidstat
top
uptime



CPU 上下文切换



CPU 上下文:CPU 执行每个任务都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮它设置好 CPU 寄存器和程序计数器(Program Counter,PC)包括 CPU 寄存器在内都被称为 CPU 上下文。



CPU 上下文切换:CPU 上下文切换,就是先把前一个任务的 CPU 上下文(也就是 CPU 寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。



CPU 上下文切换:分为 进程上下文切换
线程上下文切换
以及 中断上下文切换



进程上下文切换



从用户态切换到内核态需要通过 系统调用
来完成,这里就会发生进程上下文切换(特权模式切换),当切换回用户态同样发生上下文切换。



一般每次上下文切换都需要几十纳秒到数微秒的 CPU 时间,如果切换较多还是很容易导致 CPU 时间的浪费在寄存器、内核栈以及虚拟内存等资源的保存和恢复上,这里同样会导致 系统平均负载升高


Linux 为每个 CPU 维护一个就绪队列,将 R 状态进程按照优先级和等待 CPU 时间排序,选择最需要的 CPU 进程执行。这里运行进程就涉及了进程上下文切换的时机:




  1. 进程时间片耗尽、。




  2. 进程在系统资源不足(内存不足)。





  3. 进程主动 sleep



  4. 有优先级更高的进程执行。




  5. 硬中断发生。





线程上下文切换


线程和进程:




  1. 当进程只有一个线程时,可以认为进程就等于线程。




  2. 当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源。这些资源在上下文切换时是不需要修改的。




  3. 线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换时也是需要保存的。




所以线程上下文切换包括了 2 种情况:




  1. 不同进程的线程,这种情况等同于进程切换。




  2. 通进程的线程切换,只需要切换线程私有数据、寄存器等不共享数据。





中断上下文切换


中断处理会打断进程的正常调度和执行,转而调用中断处理程序,响应设备事件。而在打断其他进程时,就需要将进程当前的状态保存下来,这样在中断结束后,进程仍然可以从原来的状态恢复运行。


对同一个 CPU 来说,中断处理比进程拥有更高的优先级,所以中断上下文切换并不会与进程上下文切换同时发生。由于中断会打断正常进程的调度和执行,所以大部分中断处理程序都短小精悍,以便尽可能快的执行结束。



查看系统上下文切换



vmstat:工具可以查看系统的内存、CPU 上下文切换以及中断次数:


// 每隔1秒输出

$ vmstat 1

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

r b swpd free buff cache si so bi bo in cs us sy id wa st

3 0 0 157256 3241604 5144444 0 0 20 0 26503 33960 18 7 75 0 0

17 0 0 159984 3241708 5144452 0 0 12 0 29560 37696 15 10 75 0 0

6 0 0 162044 3241816 5144456 0 0 8 120 30683 38861 17 10 73 0 0


cs:则为每秒的上下文切换次数。



in:则为每秒的中断次数。



r:就绪队列长度,正在运行或等待 CPU 的进程。



b:不可中断睡眠状态的进程数,例如正在和硬件交互。



pidstat:使用 pidstat -w
选项查看具体进程的上下文切换次数:


$ pidstat -w -p 3217281 1

10:19:13 UID PID cswch/s nvcswch/s Command

10:19:14 0 3217281 0.00 18.00 stress

10:19:15 0 3217281 0.00 18.00 stress

10:19:16 0 3217281 0.00 28.71 stress


其中 cswch/s
nvcswch/s
表示自愿上下文切换和非自愿上下文切换。



自愿上下文切换:是指进程无法获取所需资源,导致的上下文切换。比如说, I/O、内存等系统资源不足时,就会发生自愿上下文切换。



非自愿上下文切换:则是指进程由于时间片已到等原因,被系统强制调度,进而发生的上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换



案例问题排查



这里我们使用 sysbench
工具模拟上下文切换问题。



先使用 vmstat 1
查看当前上下文切换信息:


$ vmstat 1

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

r b swpd free buff cache si so bi bo in cs us sy id wa st

2 0 0 514540 3364828 5323356 0 0 10 16 0 0 4 1 95 0 0

1 0 0 514316 3364932 5323408 0 0 8 0 27900 34809 17 10 73 0 0

1 0 0 507036 3365008 5323500 0 0 8 0 23750 30058 19 9 72 0 0


然后使用 sysbench --threads=64 --max-time=300 threads run
模拟 64 个线程执行任务,此时我们再次 vmstat 1
查看上下文切换信息:


$ vmstat 1

procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----

r b swpd free buff cache si so bi bo in cs us sy id wa st

2 0 0 318792 3385728 5474272 0 0 10 16 0 0 4 1 95 0 0

1 0 0 307492 3385756 5474316 0 0 8 0 15710 20569 20 8 72 0 0

1 0 0 330032 3385824 5474376 0 0 8 16 21573 26844 19 9 72 0 0

2 0 0 321264 3385876 5474396 0 0 12 0 21218 26100 20 7 73 0 0

6 0 0 320172 3385932 5474440 0 0 12 0 19363 23969 19 8 73 0 0

14 0 0 323488 3385980 5474828 0 0 64 788 111647 3745536 24 61 15 0 0

14 0 0 323576 3386028 5474856 0 0 8 0 118383 4317546 25 64 11 0 0

16 0 0 315560 3386100 5475056 0 0 8 16 115253 4553099 22 68 9 0 0

我们可以明显的观察到:




  1. 当前 cs、in 此时剧增。




  2. sy+us 的 CPU 占用超过 90%。




  3. r 就绪队列长度达到 16 个超过了 CPU 核心数 8 个。





分析 cs 上下文切换问题



我们使用 pidstat
查看当前 CPU 信息和具体的进程上下文切换信息:


// -w表示查看进程切换信息,-u查看CPU信息,-t查看线程切换信息

$ pidstat -w -u -t 1



10:35:01 UID PID %usr %system %guest %CPU CPU Command

10:35:02 0 3383478 67.33 100.00 0.00 100.00 1 sysbench



10:35:01 UID PID cswch/s nvcswch/s Command

10:45:39 0 3509357 - 1.00 0.00 kworker/2:2

10:45:39 0 - 3509357 1.00 0.00 |__kworker/2:2

10:45:39 0 - 3509702 38478.00 45587.00 |__sysbench

10:45:39 0 - 3509703 39913.00 41565.00 |__sysbench


所以我们可以看到大量的 sysbench
线程存在很多的上下文切换。



分析 in 中断问题



我们可以查看系统的 watch -d cat /proc/softirqs
以及 watch -d cat /proc/interrupts
来查看系统的软中断和硬中断(内核中断)。我们这里主要观察 /proc/interrupts
即可。


$ watch -d cat /proc/interrupts

RES: 900997016 912023527 904378994 902594579 899800739 897500263 895024925 895452133 Rescheduling interrupts

这里明显看出重调度中断(RES)增多,这个中断表示唤醒空闲状态 CPU 来调度新任务执行,



总结




  1. 自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题。




  2. 非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈。





  3. 中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts
    文件来分析具体的中断类型。




CPU 使用率



除了系统负载、上下文切换信息,最直观的 CPU 问题指标就是 CPU 使用率信息。Linux 通过 /proc
虚拟文件系统向用户控件提供系统内部状态信息,其中 /proc/stat
则是 CPU 和任务信息统计。


$ cat /proc/stat | grep cpu

cpu 6392076667 1160 3371352191 52468445328 3266914 37086 36028236 20721765 0 0

cpu0 889532957 175 493755012 6424323330 2180394 37079 17095455 3852990 0 0

...

这里每一列的含义如下:




  1. user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但包括了 guest 时间。




  2. nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优先级反而越低。




  3. system(通常缩写为 sys),代表内核态 CPU 时间。




  4. idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。




  5. iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。




  6. irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。




  7. softirq(通常缩写为 si),代表处理软中断的 CPU 时间。




  8. steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU 时间。




  9. guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚拟机的 CPU 时间。




  10. guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。





这里我们可以使用 top
ps
pidstat
等工具方便的查询这些数据,可以很方便的看到 CPU 使用率很高的进程,这里我们可以通过这些工具初步定为,但是具体的问题原因还需要其他方法继续查找。



这里我们可以使用 perf top
方便查看热点数据,也可以使用 perf record
可以将当前数据保存起来方便后续使用 perf report
查看。



CPU 使用率问题排查


这里总结一下 CPU 使用率问题及排查思路:




  1. 用户 CPU 和 Nice CPU 高,说明用户态进程占用了较多的 CPU,所以应该着重排查进程的性能问题。




  2. 系统 CPU 高,说明内核态占用了较多的 CPU,所以应该着重排查内核线程或者系统调用的性能问题。




  3. I/O 等待 CPU 高,说明等待 I/O 的时间比较长,所以应该着重排查系统存储是不是出现了 I/O 问题。




  4. 软中断和硬中断高,说明软中断或硬中断的处理程序占用了较多的 CPU,所以应该着重排查内核中的中断服务程序。





CPU 问题排查套路



CPU 使用率


CPU 使用率主要包含以下几个方面:




  1. 用户 CPU 使用率,包括用户态 CPU 使用率(user)和低优先级用户态 CPU 使用率(nice),表示 CPU 在用户态运行的时间百分比。用户 CPU 使用率高,通常说明有应用程序比较繁忙。




  2. 系统 CPU 使用率,表示 CPU 在内核态运行的时间百分比(不包括中断)。系统 CPU 使用率高,说明内核比较繁忙。




  3. 等待 I/O 的 CPU 使用率,通常也称为 iowait,表示等待 I/O 的时间百分比。iowait 高,通常说明系统与硬件设备的 I/O 交互时间比较长。




  4. 软中断和硬中断的 CPU 使用率,分别表示内核调用软中断处理程序、硬中断处理程序的时间百分比。它们的使用率高,通常说明系统发生了大量的中断。




  5. 除在虚拟化环境中会用到的窃取 CPU 使用率(steal)和客户 CPU 使用率(guest),分别表示被其他虚拟机占用的 CPU 时间百分比,和运行客户虚拟机的 CPU 时间百分比。





平均负载


反应了系统的整体负载情况,可以查看过去 1 分钟、过去 5 分钟和过去 15 分钟的平均负载。



上下文切换


上下文切换主要关注 2 项指标:




  1. 无法获取资源而导致的自愿上下文切换。




  2. 被系统强制调度导致的非自愿上下文切换。





CPU 缓存命中率



CPU 的访问速度远大于内存访问,这样在 CPU 访问内存时不可避免的要等待内存响应。为了协调 2 者的速度差距出现了 CPU 缓存(多级缓存)。如果 CPU 缓存命中率越高则性能会更好,我们可以使用以下工具查看 CPU 缓存命中率, 工具地址
、 项目地址 perf-tools


# ./cachestat -t

Counting cache functions... Output every 1 seconds.

TIME HITS MISSES DIRTIES RATIO BUFFERS_MB CACHE_MB

08:28:57 415 0 0 100.0% 1 191

08:28:58 411 0 0 100.0% 1 191

08:28:59 362 97 0 78.9% 0 8

08:29:00 411 0 0 100.0% 0 9

08:29:01 775 20489 0 3.6% 0 89

08:29:02 411 0 0 100.0% 0 89

08:29:03 6069 0 0 100.0% 0 89

08:29:04 15249 0 0 100.0% 0 89

08:29:05 411 0 0 100.0% 0 89

08:29:06 411 0 0 100.0% 0 89

08:29:07 411 0 3 100.0% 0 89

[...]


总结



通过性能指标查工具(CPU 相关)



































































性能指标 工具 说明

平均负载


uptime


top





uptime 简单展示最近一段时间的平均负载


top 展示更多指标




CPU 使用率


vmstat


mpstat


top


sar


/proc/stat





top、vmstat、mpstat 只可以动态查看当前,而 sar 可以查看历史


/proc/stat 是其他性能工具的数据来源




进程 CPU 使用率


top


pidstat


ps


htop


atop





top、ps 可以以排序方式展示进程 CPU、pidstat 不可排序展示


htop、atop 则以不同颜色展示各类数据更直观




系统上下文切换

vmstat

展示上下文切换此时、运行状态、不可中断状态进程数量

进程上下文切换

pidstat

展示项很多,包括进程上下文切换信息

软中断


top


/proc/softirqs


mpstat





top 可查看软中断 CPU 使用率


/proc/softirqs 和 mpstat 则可以查看每个 CPU 上的累计信息




硬中断


vmstat


/proc/interrupts





vmstat 查看总中断次数信息


/proc/interrupts 查看各种中断在每个 CPU 核心上的累计信息




网络


dstat


sar


tcpdump





dstat、sar 较详细的展示出总的网络收发情况


tcpdump 提供动态抓取数据包的能力




IO

dstat、sar

2 者都提供了详细的 IO 整体情况

CPU 信息


/proc/cpuinfo


lscpu




都可以查看 CPU 信息

系统分析


perf


execsnoop





perf 分析各种内核函数调用、热点函数信息


execsnoop 监控短时进程





根据工具查性能指标(CPU 相关)







































































性能工具 CPU 性能指标

uptime

5、10、15 分钟内的平均负载展示

top

平均负载、运行队列、CPU 各项使用率、进程状态和 CPU 使用率

htop

top 增强版,以不同颜色区分不同类型进程,展示更直观

atop

CPU、内存、磁盘、网络资源全访问监控,十分齐全

vmstat

系统整体 CPU 使用率、上下文切换次数、中断次数,还包括处于运行(r)和不可中断状态(b)的进程数量

pidstat

进程、线程(-t)的每个 CPU 占用信息,中断上下文切换次数

/proc/softirqs

展示每个 CPU 上的软中断类型及次数

/proc/inerrupts

展示每个 CPU 上的硬中断类型及次数

ps

每个进程的状态和 CPU 使用率

pstree

进程的父子关系展示

dstat

系统整体 CPU 使用率(以及相关 IO、网络信息)

sar

系统整体 CPU 使用率,以及使用率历史信息

strace

跟踪进程的系统调用

perf

CPU 性能事件分析,例如:函数调用链、CPU 缓存命中率、CPU 调度等

execsnoop

短时进程分析


CPU 问题排查方向


有了以上性能工具,在实际遇到问题时我们并不可能全部性能工具跑一遍,这样效率也太低了,所以这里可以先运行几个常用的工具 top、vmstat、pidstat 分析系统大概的运行情况然后在具体定位原因。


top 系统CPU => vmstat 上下文切换次数 => pidstat 非自愿上下文切换次数 => 各类进程分析工具(perf strace ps execsnoop pstack)



top 用户CPU => pidstat 用户CPU => 一般是CPU计算型任务



top 僵尸进程 => 各类进程分析工具(perf strace ps execsnoop pstack)



top 平均负载 => vmstat 运行状态进程数 => pidstat 用户CPU => 各类进程分析工具(perf strace ps execsnoop pstack)



top 等待IO CPU => vmstat 不可中断状态进程数 => IO分析工具(dstat、sar -d)



top 硬中断 => vmstat 中断次数 => 查看具体中断类型(/proc/interrupts)



top 软中断 => 查看具体中断类型(/proc/softirqs) => 网络分析工具(sar -n、tcpdump) 或者 SCHED(pidstat 非自愿上下文切换)


CPU 问题优化方向


性能优化往往是多方面的,CPU、内存、网络等都是有关联的,这里暂且给出 CPU 优化的思路,以供参考。



程序优化




  1. 基本优化:程序逻辑的优化比如减少循环次数、减少内存分配,减少递归等等。





  2. 编译器优化:开启编译器优化选项例如 gcc -O2
    对程序代码优化。




  3. 算法优化:降低苏研发复杂度,例如使用 nlogn
    的排序算法,使用 logn
    的查找算法等。



  4. 异步处理:例如把轮询改为通知方式




  5. 多线程代替多进程:某些场景下多线程可以代替多进程,因为上下文切换成本较低




  6. 缓存:包括多级缓存的使用(略)加快数据访问





系统优化




  1. CPU 绑定:绑定到一个或多个 CPU 上,可以提高 CPU 缓存命中率,减少跨 CPU 调度带来的上下文切换问题




  2. CPU 独占:跟 CPU 绑定类似,进一步将 CPU 分组,并通过 CPU 亲和性机制为其分配进程。




  3. 优先级调整:使用 nice 调整进程的优先级,适当降低非核心应用的优先级,增高核心应用的优先级,可以确保核心应用得到优先处理。




  4. 为进程设置资源限制:使用 Linux cgroups 来设置进程的 CPU 使用上限,可以防止由于某个应用自身的问题,而耗尽系统资源。




  5. NUMA 优化:支持 NUMA 的处理器会被划分为多个 Node,每个 Node 有本地的内存空间,这样 CPU 可以直接访问本地空间内存。




  6. 中断负载均衡:无论是软中断还是硬中断,它们的中断处理程序都可能会耗费大量的 CPU。开启 irqbalance 服务或者配置 smp_affinity,就可以把中断处理过程自动负载均衡到多个 CPU 上。




参考


极客时间:Linux 性能优化实战








推荐阅读
  • 微软评估和规划(MAP)的工具包介绍及应用实验手册
    本文介绍了微软评估和规划(MAP)的工具包,该工具包是一个无代理工具,旨在简化和精简通过网络范围内的自动发现和评估IT基础设施在多个方案规划进程。工具包支持库存和使用用于SQL Server和Windows Server迁移评估,以及评估服务器的信息最广泛使用微软的技术。此外,工具包还提供了服务器虚拟化方案,以帮助识别未被充分利用的资源和硬件需要成功巩固服务器使用微软的Hyper - V技术规格。 ... [详细]
  • 本文介绍了设计师伊振华受邀参与沈阳市智慧城市运行管理中心项目的整体设计,并以数字赋能和创新驱动高质量发展的理念,建设了集成、智慧、高效的一体化城市综合管理平台,促进了城市的数字化转型。该中心被称为当代城市的智能心脏,为沈阳市的智慧城市建设做出了重要贡献。 ... [详细]
  • 本文介绍了如何找到并终止在8080端口上运行的进程的方法,通过使用终端命令lsof -i :8080可以获取在该端口上运行的所有进程的输出,并使用kill命令终止指定进程的运行。 ... [详细]
  • 本文介绍了三种方法来实现在Win7系统中显示桌面的快捷方式,包括使用任务栏快速启动栏、运行命令和自己创建快捷方式的方法。具体操作步骤详细说明,并提供了保存图标的路径,方便以后使用。 ... [详细]
  • 成功安装Sabayon Linux在thinkpad X60上的经验分享
    本文分享了作者在国庆期间在thinkpad X60上成功安装Sabayon Linux的经验。通过修改CHOST和执行emerge命令,作者顺利完成了安装过程。Sabayon Linux是一个基于Gentoo Linux的发行版,可以将电脑快速转变为一个功能强大的系统。除了作为一个live DVD使用外,Sabayon Linux还可以被安装在硬盘上,方便用户使用。 ... [详细]
  • 本文介绍了在CentOS上安装Python2.7.2的详细步骤,包括下载、解压、编译和安装等操作。同时提供了一些注意事项,以及测试安装是否成功的方法。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • 配置IPv4静态路由实现企业网内不同网段用户互访
    本文介绍了通过配置IPv4静态路由实现企业网内不同网段用户互访的方法。首先需要配置接口的链路层协议参数和IP地址,使相邻节点网络层可达。然后按照静态路由组网图的操作步骤,配置静态路由。这样任意两台主机之间都能够互通。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 合并列值-合并为一列问题需求:createtabletab(Aint,Bint,Cint)inserttabselect1,2,3unionallsel ... [详细]
  • 本文介绍了MVP架构模式及其在国庆技术博客中的应用。MVP架构模式是一种演变自MVC架构的新模式,其中View和Model之间的通信通过Presenter进行。相比MVC架构,MVP架构将交互逻辑放在Presenter内部,而View直接从Model中读取数据而不是通过Controller。本文还探讨了MVP架构在国庆技术博客中的具体应用。 ... [详细]
  • 使用C++编写程序实现增加或删除桌面的右键列表项
    本文介绍了使用C++编写程序实现增加或删除桌面的右键列表项的方法。首先通过操作注册表来实现增加或删除右键列表项的目的,然后使用管理注册表的函数来编写程序。文章详细介绍了使用的五种函数:RegCreateKey、RegSetValueEx、RegOpenKeyEx、RegDeleteKey和RegCloseKey,并给出了增加一项的函数写法。通过本文的方法,可以方便地自定义桌面的右键列表项。 ... [详细]
  • [译]技术公司十年经验的职场生涯回顾
    本文是一位在技术公司工作十年的职场人士对自己职业生涯的总结回顾。她的职业规划与众不同,令人深思又有趣。其中涉及到的内容有机器学习、创新创业以及引用了女性主义者在TED演讲中的部分讲义。文章表达了对职业生涯的愿望和希望,认为人类有能力不断改善自己。 ... [详细]
  • 拥抱Android Design Support Library新变化(导航视图、悬浮ActionBar)
    转载请注明明桑AndroidAndroid5.0Loollipop作为Android最重要的版本之一,为我们带来了全新的界面风格和设计语言。看起来很受欢迎࿰ ... [详细]
author-avatar
空白画叶子
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有