Linux系统性能分析笔记

查看CPU数量

总核数 = 物理CPU个数 X 每颗物理CPU的核数
总逻辑CPU数 = 物理CPU个数 X 每颗物理CPU的核数 X 超线程数

  1. 查看物理CPU个数
    cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

  2. 查看每个物理CPU中core的个数(即核数)
    cat /proc/cpuinfo| grep "cpu cores"| uniq

  3. 查看逻辑CPU的个数
    cat /proc/cpuinfo| grep "processor"| wc -l

平均负载

  1. uptime
    输出17:06:20 up 2 days, 17:39, 1 user, load average: 1.75, 1.59, 1.31
    分别表示当前时间,系统运行时间,正在登录用户数,过去 1 分钟,5 分钟,15 分钟的平均负载
    运行man uptime可以得到平均负载的定义:

    System load averages is the average number of processes that are either in a runnable or uninterruptable state. A process in a runnable state is either using the CPU or waiting to use the CPU. A process in uninterruptable state is waiting for some I/O access, eg waiting for disk. The averages are taken over the three time intervals.
    Load averages are not normalized for the number of CPUs in a system, so a load average of 1 means a single CPU system is loaded all the time while on a 4 CPU system it means it was idle 75% of the time.

    除了正在运行的进程,还有不可中断进程.不可中断状态的进程是正处于内核态关键流程中的进程,并且这些流程是不可打断的,最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态(Uninterruptible Sleep,也称为 Disk Sleep)的进程。
    当平均负载大于CPU数量时表示出现了过载.

  2. 压力测试工具stress
    需要通过包管理器进行安装.
    使用指令stress --cpu 1 --timeout 600可以施加1个CPU的负载,持续600秒.
    使用指令stress -i 1 --timeout 600模拟io负载.
    使用指令stress -c 8 --timeout 600模拟8个进程.

    使用uptimempstat -P ALL可以对CPU的状态进行实时的查看.

  3. 使用pidstat查看当前进程占用CPU的情况
    使用pidstat -u 5 2命令可以每5s统计一次当前CPU使用情况, 共显示两次.
    使用pidstat -d可以查看当前进程的IO情况

CPU上下文切换

系统中的上下文切换可以分为:系统权限模式切换,进程上下文切换,线程上下文切换,中断上下文切换
线程是调度的基本单位,而进程则是资源拥有的基本单位. 同进程内的线程切换,要比多进程间的切换消耗更少的资源.

  1. 使用vmstat查看系统整体CPU切换情况
    运行vmstat 5可以得到如下的结果:

    procs ———–memory———- —swap– —–io—- -system– ——cpu—–
    r b swpd free buff cache si so bi bo in cs us sy id wa st
    0 0 0 699912 1015920 6586312 0 0 5 19 3 14 4 7 88 0 0
    0 0 0 685852 1015920 6586344 0 0 0 171 671 1588 2 1 97 0 0
    0 0 0 686720 1015924 6586340 0 0 0 42 551 1473 1 1 98 0 0
    0 0 0 698912 1015924 6586368 0 0 0 7 816 3540 8 2 90 0 0

    以下是man vmstat中对于输出参数的说明.

    FIELD DESCRIPTION FOR VM MODE
    Procs

    r: The number of runnable processes (running or waiting for run time).  
    b: The number of processes in uninterruptible sleep.  
    

    Memory

    swpd: the amount of virtual memory used.  
    free: the amount of idle memory.  
    buff: the amount of memory used as buffers.  
    cache: the amount of memory used as cache.  
    inact: the amount of inactive memory.  (-a option)  
    active: the amount of active memory.  (-a option)  
    

    Swap

    si: Amount of memory swapped in from disk (/s).  
    so: Amount of memory swapped to disk (/s).  
    

    IO

    bi: Blocks received from a block device (blocks/s).  
    bo: Blocks sent to a block device (blocks/s).  
    

    System

    in: The number of interrupts per second, including the clock.  
    cs: The number of context switches per second.  
    

    CPU

    These are percentages of total CPU time.  
    us: Time spent running non-kernel code.  (user time, including nice time)  
    sy: Time spent running kernel code.  (system time)  
    id: Time spent idle.  Prior to Linux 2.5.41, this includes IO-wait time.  
    wa: Time spent waiting for IO.  Prior to Linux 2.5.41, included in idle.  
    st: Time stolen from a virtual machine.  Prior to Linux 2.6.11, unknown.  
    
  • cs(context switch)是每秒上下文切换的次数。
  • in(interrupt)则是每秒中断的次数。
  • r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程数。
  • b(Blocked)则是处于不可中断睡眠状态的进程数.
  1. 使用pidstat -w 5查看每个进程的CPU切换情况
    主要输出中有cswch/s和nvcswch/s两列
    cswch/s 表示每秒任务所做的自愿上下文切换的总数。当任务阻塞时会发生自愿上下文切换,因为它需要的资源不可用。
    nvcswch/s 每秒任务所做的非自愿上下文切换的总数。 当任务执行一段时间时,会发生非自愿的上下文切换,因为系统会给每个进程分配时间片段,时间片段到达限定之后就会跳转到别的进程, 作为系统实现多任务的一种方式.
    pidstat -w只显示进程之间的切换次数,pidstat -wt可以将线程之间的切换次数也计算入内.
    在终端对其排序可使用pidstat -w | sort -k4 -g,表示对第4行排正序

  2. 使用sysbench模拟系统多进程调度
    sysbench --num-threads=64 --max-time=60 --max-requests=100000 --test=threads run指令可以模拟多线程压力测试.

  3. 查看中断切换情况
    watch -d cat /proc/interrupts查看中断信息. /proc是linux系统提供的虚拟空间, 用于用户空间和内核空间的通信.

  4. 查看proc中的文件
    /proc/stat CPU整体活动信息
    /proc/<pid>/stat 进程活动信息
    /proc/<pid>/task/<tid>/stat 线程活动信息

CPU使用率

  1. 查看系统节拍率
    时钟节拍是特定的周期性中断,时钟节拍率越快,系统的额外开销就越大。越慢则系统响应速度越慢.
    cat /boot/config-$(uname -r) | grep CONFIG_HZ= 可以查看节拍率, 数值表示每秒钟CPU时间中断次数.
    cat /proc/timer_list |grep jiffies 可以查看jiffies的值, 表示启动以来触发的时间中断次数.

  2. 使用cat /proc/stat |grep ^cpu 查看CPU情况
    得到如下结果:

    cpu 5126936 5712 7710142 117664694 595706 0 64856 0 0 0
    cpu0 1469407 1059 2327228 28911946 68524 0 22051 0 0 0
    cpu1 1504594 1668 2536510 28675459 53180 0 22960 0 0 0
    cpu2 698222 1269 468605 31543635 49917 0 14812 0 0 0
    cpu3 1454710 1714 2377798 28533652 424084 0 5031 0 0 0

    使用man proc可以得到每一列参数的说明:

    user   (1) Time spent in user mode.  
    nice   (2) Time spent in user mode with low priority (nice).  
    system (3) Time spent in system mode.  
    idle   (4) Time spent in the idle task.  This value should be USER_HZ times the second entry in the /proc/uptime   pseudo-file.  
    iowait (since Linux 2.5.41)  
           (5) Time waiting for I/O to complete.  
    irq (since Linux 2.6.0-test4)  
           (6) Time servicing interrupts.   
    softirq (since Linux 2.6.0-test4)  
           (7) Time servicing softirqs.  
    steal (since Linux 2.6.11)  
           (8) Stolen time, which is the time spent in other operating systems when running in a virtualized environment  
    guest (since Linux 2.6.24)  
           (9) Time spent running a virtual CPU for guest operating systems under the control of the Linux kernel.
    guest_nice (since Linux 2.6.33)  
           (10) Time spent running a niced guest (virtual CPU for guest operating systems under the control of the Linux kernel).  
    

    CPU使用率的计算去除idle的那一部分即可.
    但是直接针对这个文件进行计算得到的是开机以来的CPU使用率, 需要查看当前CPU使用率的时候,可以取一段时间, 然后根据这段时间内数据的变化来计算出平均的CPU使用率.
    在使用top指令进行查看的时候, 计算的是3s内的CPU平均使用率.

    查看占用CPU最多的函数

    1. 使用perf指令
      安装perf的时候需要注意, perf与内核的关联十分紧密, 通常会需要sudo apt-get install linux-tools-$(uname -r)
      如果包管理器中找不到对应内核的perf,可以从linux源码中的linux/tools/perf文件夹编译运行.
      运行perf top会列出使用资源最高的函数, 最后一列会列出函数名, 函数名未知的列出内存地址.
      执行perf record ls -g可以记录执行ls语句时候的系统调用情况, 结束后使用perf report可以看到结果
      perf top -g -p 1302可以看到pid为1302的进程函数调用情况
    2. exescoop工具
      exescoop是用于检查进程外部exec调用的工具. 有时候系统CPU占用很高, 但是单个进程查不出来, 这时候就有可能是进程在不断的调用比较小的外部进程, 或者是程序在不断的崩溃重启.
    3. pstree可以用于查看进程树