使用USE法分析Linux系统性能

一张源自USE法的Linux检查清单表。用来检查系统健康状态,发现常见资源瓶颈和错误的方法。性能工具常有改进并不断有新工具问世,因此你应当把这些工具当作需要更新的起点。同样,也可以开发出新的观测框架和工具,使得使用USE法更加容易。

物理资源

模块类型指标
CPU利用率每个CPU:mpstat -P ALL,(取剩下部分)%idle; sar -P ALL,%idle
系统范围:vmstat 1,id项; sar -u,%idle项; dstat -c,idl项
每个进程:top,%CPU项;htop,%CPU项;ps -o pcpupidstat 1,%CPU项
每个内核线程:top/htop(按K转换显示),找到VIRT==0(启发式)
CPU饱和度系统范围:vmstat 1,r > CPU数量[^1];sar -q,runq-sz > CPU数量;
dstat -p,run > CPU数量
每个进程:/proc/PID/shedstat第二项(sched_info.run_delay);getdelays.c,CPU[^2];perf sched latency(显示每次调试的平均和最大的延时);动态跟踪,例如SystemTap中schedtimes.stp.queued(us)[^3]
CPU错误如果处理器特定错误事件(CPC)可用,使用perf(LPE);例如,AMD64的"04Ah Single-bit ECC Errors Recorded by Scrubber"[^4]
内存容量利用率系统范围:free -m,Mem:(主存),Swap:(虚存);vmstat 1,free项(主存),swap项(虚存);sar -r,%memused项;dstat -m,free项;
slabtop -s c 检查 kmem slab 使用情况
每个进程:top/htop,RES项(驻留主存),VIRT项(虚存),Mem项为系统范围内的总计
内存容量饱和度系统范围:vmstat 1,si/so项(交换);sar -B,pgscank项+pgscand项(扫描);sar -W
每个进程:getdelays.c,SWAP项[^2];/proc/PID/stat中第10项(min_flt)可以得到将要缺页率,或者使用动态跟踪[^5];dmesg | grep killed(OOM进程终结者)
内存容量错误dmesg可以得到物理失效;动态跟踪,例如,使用uprobes获得失败的malloc()数量(DTrace/SystemTap)
网络接口利用率ip -s link,RX/TX 吞吐量除以最大带宽;sar -n DEV项,rx/tx kB/s 除以最大带宽;/proc/net/dev,RX/TX 吞吐量字节数除以最大值
网络接口饱和度ifconfig,overruns项,dropped项[^6]; netstat -s,重新传输段数;sar -n EDEV项,*drop/s项,*fifo/s项;/proc/net/dev,RX/TX 丢包;动态跟踪其他 TCP/IP 栈排除情况
网络接口错误ifconfig,errors项,dropped项[^6]; netstat -i,RX-ERR/TX-ERR;ip -s link,errors项,sar -n EDEV所有项;/proc/net/dev,errs,drop;
其他计数器可能可以在 /sys/class/net/... 下找到;动态跟踪驱动函数的返回值
存储设备I/O利用率系统范围:iostat -xz 1,%util;sar -d %util;
每个进程:iotop/proc/PID/sched se.statistics.iowait_sum
存储设备I/O饱和度iostat -xnz 1,avgqu-sz > 1,或者较高的await;sar -d的相同项;LPE块探针以获取队列长度/延时;动态/静态跟踪 I/O 子系统(包括LPE块探针)
存储设备I/O错误/sys/devices/.../ioerr_cnt;smartctl;动态/静态跟踪 I/O 子系统响应代码[^7]
存储容量使用率swap: swapon -s;free; /proc/meminfo SwapFree/SwapTotal;文件系统:df -h
存储容量饱和度不太确定这项是否有意义——一旦满会返回ENOSPC
存储容量文件系统:错误strace跟踪 ENOSPC;动态跟踪 ENOSPC;/var/log/messages errs,取决于文件系统;应用程序日志错误
存储控制器使用率iostat -xz 1,把设备的数值加起来与已知的每张卡 IOPS/吞吐量进行对比
存储控制器饱和度/错误参见存储设备 I/O 饱和度和错误
网络控制器使用率从ip -s link(或者 sar,或者 /proc/net/dev)和已知控制器的最大吞吐量推断出接口类型
网络控制器饱和率/错误参见网络接口饱和度和错误
CPU互联使用率LPE(CPC)获得 CPU 互联端口,用吞吐量除以最大值
CPU互联饱和度LPE(CPC)获得停滞周期
CPU互联错误LPE(CPC)得到的所有信息
内存互联使用率LPE(CPC)获得内存总线,用吞吐量除以最大值;或者大于 10 的 CPI;CPC 可能有本地和远程计数器的对比
I/O互联使用率LPE(CPC)获得吞吐量除以最大值(如果能够获得);通过 iostat/ip/... 获得的已知吞吐量进行推断
内存& I/O互联饱和度LPE (CPC)获得停滞周期
内存& I/O互联错误LPE(CPC)得到的所有信息

  1. 列 r 报告了那些正在等待以及正在 CPU 上运行的线程。参见第 6 章中关于 vmstat(1) 的描述。

  2. 使用延时核算,参见第 4 章。

  3. 还有一个为 perf(1) 服务的跟踪点 sched:sched_process_wait;由于调试事件很频繁,跟踪时注意额外的开销。

  4. 在最新的 Intel 和 AMD 处理器手册中没有很多错误相关的事件。

  5. 可以通过查看谁造成了次要缺页,来展示谁正在消耗内存并导致饱和。在 htop(1) 中应该可以通过 MINFLT 一项得到。

  6. 丢弃的报文被包含在了饱和度和错误的指标内,因为饱和及错误都有可能造成报文的丢弃。

  7. 这包括了跟踪 I/O 子系统中不同层次的函数:块设备、SCSI、SATA、IDE......有些静态探针可用(LPEscsi 和 block跟踪事件),否则就使用动态跟踪。

    一般说明:上面并未包含 uptime 命令的 load average 项,原因是 Linux 的负载均衡包括了处于无法中断状态的 I/O 任务。

    LPE:Linux 性能事件(Linux Performance Events)是一个强大的观测工具,它读取 CPC 并且可以使用动态和静态跟踪技术。它的接口即 perf(1) 命令。它在第6章有介绍。

    CPC:CPU 性能计数器(CPU performance counter)。参见第 6 章,用法参考 perf(1)。

    I/O互联:包括了 CPU 到 I/O 的控制器总线、I/O 控制器,以及设备总线(例如PCIe)。

    动态跟踪:可以开发自定义的指标。参见第 4 章以及后面几章内的例子。Linux 上的动态跟踪工具包括了LPE、DTrace、SystemTap 和 LTTng。

    对于任何资源施加限制的环境(例如云计算),对每一种资源控制采用USE法。这些资源控制和资源限制有可能在物理资源完全耗尽之前就被触发。

软件资源

模块类型指标
内核态互斥量使用率内核编译带 CONFIG_LOCK_STAT=y 的情况下,使用 /proc/lock_stat 里的 holdtime-total 项除以 acquisitions 项(另外参考 holdtime-min、holdtime-max)[^1];对锁函数或者指令(可能有)进行动态跟踪
内核态互斥量饱和度内核编译带 CONFIG_LOCK_STAT=y 的情况下,使用 /proc/lock_stat 里的 waittime-total 项除以 contentions 项(另外参考waittime-min、waittime-max);对锁函数或者指令(可能有)进行动态跟踪;旋转情况也可以通过剖析显示出来(perf record -a -g -F 997...、oprofile、DTrace、SystemTap)
内核态互斥量错误动态跟踪(例如递归进入互斥量);其他错误可能会造成内核锁起/恐慌,可以使用kdump/crash进行调试
用户态互斥量使用率valgrind --tool=drd --exclusive-threshold=...... (持有时间);对加锁到解锁这段的函数时间进行动态跟踪
用户态互斥量饱和度valgrind --tool=drd 可以根据持有时间推断竞争的情况;对同步函数进行动态跟踪得到等待时间;进行剖析(oprofile、PEL......)用户调用栈得到旋转等待的情况
用户态互斥量错误valgrind --tool=drd 提示的各种错误;动态跟踪 pthread_mutex_lock() 的返回值,如EAGAIN、EINVAL、EPERM、EDEADLK、ENOMEM、EOWNEREAD 等
任务容量使用率top/htop,Tasks 项(当前);sysctl kernel.threads-max 项,/proc/sys/kernel/threads-max(最大值)
任务容量饱和度被阻塞在内存分配上的线程数;这个时候页面扫描器应该正在运行(sar -B,pgscan*),或者使用动态跟踪检查
任务容量错误“can't fork()” 错误;用户态线程:pthread_create() 错误返回值如 EAGAIN、EINVAL......;内核组:动态跟踪 kernel_thread() 函数的 ENOMEM 返回值
文件描述符使用率系统范围:sar -v,file-nr 项和 /proc/sys/fs/file-max 相比较;dstat --fs,files项;或者是 /proc/sys/fs/file-nr
每个线程:ls /proc/PID/fd | wc -l 对比 ulimt -n
文件描述符饱和度这一项没有意义
文件描述符错误在返回文件描述符的系统调用上(例如 open()、accept()......)使用 strace errno == EMFILE
  1. 内核锁分析以前是通过 lockmeter 进行的,它有一个接口调用 lockstat。

anzhihe安志合个人博客,版权所有丨 如未注明,均为原创 丨转载请注明转自:https://chegva.com/3431.html | ☆★★每天进步一点点,加油!★★☆

您可能还感兴趣的文章!

发表评论

电子邮件地址不会被公开。 必填项已用*标注