Linux CPU 性能优化指南

Posted 腾讯技术工程

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux CPU 性能优化指南相关的知识,希望对你有一定的参考价值。


PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND13:11:01 up 888 days, 21:33, 8 users, load average: 17.20, 14.85, 14.10
// --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、进程数过多的问题

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMANDr b swpd free buff cache si so bi bo in cs us sy id wa st3 0 0 157256 3241604 5144444 0 0 20 0 26503 33960 18 7 75 0 06 0 0 162044 3241816 5144456 0 0 8 120 30683 38861 17 10 73 0 0

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

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

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

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

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

  • r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st2  0      0 514540 3364828 5323356    0    0    10    16    0    0  4  1 95  0  01  0      0 514316 3364932 5323408    0    0     8     0 27900 34809 17 10 73  0  01  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查看上下文切换信息:

  • r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st2  0      0 318792 3385728 5474272    0    0    10    16    0    0  4  1 95  0  01  0      0 307492 3385756 5474316    0    0     8     0 15710 20569 20  8 72  0  01  0      0 330032 3385824 5474376    0    0     8    16 21573 26844 19  9 72  0  02  0      0 321264 3385876 5474396    0    0    12     0 21218 26100 20  7 73  0  06  0      0 320172 3385932 5474440    0    0    12     0 19363 23969 19  8 73  0  014  0      0 323488 3385980 5474828    0    0    64   788 111647 3745536 24 61 15  0  014  0      0 323576 3386028 5474856    0    0     8     0 118383 4317546 25 64 11  0  016  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 Command10:35:02 0 3383478 67.33 100.00 0.00 100.00 1 sysbench
    10:35:01 UID PID cswch/s nvcswch/s Command10:45:39 0 3509357 - 1.00 0.00 kworker/2:210:45:39 0 - 3509357 1.00 0.00 |__kworker/2:210:45:39 0 - 3509702 38478.00 45587.00 |__sysbench10: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/interruptsRES:  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 cpucpu  6392076667 1160 3371352191 52468445328 3266914 37086 36028236 20721765 0 0cpu0 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),代表以低优先级运行虚拟机的时间。

    这里我们可以使用toppspidstat等工具方便的查询这些数据,可以很方便的看到 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 -tCounting cache functions... Output every 1 seconds.TIME         HITS   MISSES  DIRTIES    RATIO   BUFFERS_MB   CACHE_MB08:28:57      415        0        0   100.0%            1        19108:28:58      411        0        0   100.0%            1        19108:28:59      362       97        0    78.9%            0          808:29:00      411        0        0   100.0%            0          908:29:01      775    20489        0     3.6%            0         8908:29:02      411        0        0   100.0%            0         8908:29:03     6069        0        0   100.0%            0         8908:29:04    15249        0        0   100.0%            0         8908:29:05      411        0        0   100.0%            0         8908:29:06      411        0        0   100.0%            0         8908: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 提供动态抓取数据包的能力
    IOdstat、sar2 者都提供了详细的 IO 整体情况
    CPU 信息/proc/cpuinfo
    lscpu
    都可以查看 CPU 信息
    系统分析perf
    execsnoop
    perf 分析各种内核函数调用、热点函数信息
    execsnoop 监控短时进程

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

    性能工具CPU 性能指标
    uptime5、10、15 分钟内的平均负载展示
    top平均负载、运行队列、CPU 各项使用率、进程状态和 CPU 使用率
    htoptop 增强版,以不同颜色区分不同类型进程,展示更直观
    atopCPU、内存、磁盘、网络资源全访问监控,十分齐全
    vmstat系统整体 CPU 使用率、上下文切换次数、中断次数,还包括处于运行(r)和不可中断状态(b)的进程数量
    pidstat进程、线程(-t)的每个 CPU 占用信息,中断上下文切换次数
    /proc/softirqs展示每个 CPU 上的软中断类型及次数
    /proc/inerrupts展示每个 CPU 上的硬中断类型及次数
    ps每个进程的状态和 CPU 使用率
    pstree进程的父子关系展示
    dstat系统整体 CPU 使用率(以及相关 IO、网络信息)
    sar系统整体 CPU 使用率,以及使用率历史信息
    strace跟踪进程的系统调用
    perfCPU 性能事件分析,例如:函数调用链、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 性能优化实战


    Java性能优化权威指南-读书笔记-操作系统性能监控工具

    一:CPU

    1. 用户态CPU是指执行应用程序代码的时间占总CPU时间的百分比。

    系统态CPU是指应用执行操作系统调用的时间占总CPU时间的百分比。系统态CPU高意味着共享资源有竞争或者I/O设备之间有大量的交互。

    提高应用性能和扩展性的一个目标就是尽可能降低系统态CPU使用率。

    2. CPU运行队列就是那些已经准备好运行、正等待可用CPU的轻量级进程。

    当运行队列长度达到处理器的4被或者更多时,系统的相应就非常迟缓了。

    解决运行队列长有两种办法:

    1). 增加CPU以分担负载;

    2). 分析系统中运行的应用,改进CPU使用率;

    1. vmstat

    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 104956    868 825812    0    0     1     5   16   25  0  0 100  0  0

    r:CPU运行队列长度,值是运行队列中轻量级进程的实际数量

    us:用户态CPU使用率

    sy:系统态CPU使用率

    id:CPU空闲率

    2. top

    top - 09:42:04 up 3 days, 3 min,  1 user,  load average: 0.00, 0.01, 0.05
    Tasks: 108 total,   3 running, 105 sleeping,   0 stopped,   0 zombie
    %Cpu(s):  0.0 us,  0.0 sy,  0.0 ni,100.0 id,  0.0 wa,  0.0 hi,  0.0 si,  0.0 st
    KiB Mem :  1015472 total,   104568 free,    84224 used,   826680 buff/cache
    KiB Swap:        0 total,        0 free,        0 used.   727760 avail Mem 
    
      PID USER      PR  NI    VIRT    RES    SHR S %CPU %MEM     TIME+ COMMAND                                                                                          
      784 root      20   0  553064  16340   5748 S  0.0  1.6   0:21.48 tuned                                                                                            
      743 root      20   0  110512  13140    676 S  0.0  1.3   0:00.13 dhclient                                                                                         
     9678 polkitd   20   0  527456  13128   4680 S  0.0  1.3   0:00.09 polkitd                                                                                          
        1 root      20   0   43684   6176   3804 S  0.0  0.6   0:05.08 systemd                                                                                          
    

    上半部分是整个系统的统计信息,下半部分是进程的统计信息。

    二:内存

    1. 系统在使用页面交换或虚拟内存时,访问swap中内存以及JVM垃圾回收swap中内存时,都存在内存置换,性能肯定有问题;

    2.

    以上是关于Linux CPU 性能优化指南的主要内容,如果未能解决你的问题,请参考以下文章

    linux性能优化cpu 磁盘IO MEM

    Linux性能优化的全景指南

    Linux性能优化从入门到实战:07 CPU篇:CPU性能优化方法

    Linux调度系统全景指南(下篇)

    Linux按照CPU内存磁盘IO网络性能监测

    Linux性能优化从入门到实战:03 CPU篇:CPU上下文切换