本文以系统为中心, 结合日常工作和用例, 由浅入深地介绍了性能分析的一些方法和体会, 希望对想了解系统性能分析的同学有所帮助。
01
入门篇
01
资源角度
USE
产品跑在系统的各种资源上面, 从系统资源的角度入门性能分析是个不错的选择, 我们以业界知名大牛 Brendan Gregg 的 USE 方法开始, USE 特点就是简单有效适合入门, 用 Brendan 的话描述 USE 的效果:
I find it solves about 80% of server issues with 5% of the effort.
USE 从系统资源的角度, 包括但不限于 CPU, 内存, 磁盘, 网络等, 关注以下3个方面:
- Utilization (U): as a percent over a time interval. eg, "one disk is running at 90% utilization". 大多数情况可以合理推测利用率高可能会影响性能
- Saturation (S): as a queue length. eg, "the CPUs have an average run queue length of four". 资源竞争的激烈程度
- Errors (E). scalar counts. eg, "this network interface has had fifty late collisions". Errors 相对直观
CPU
对于 CPU, 主要关注以下指标:
- Utilization. CPU 的利用率
- Saturation. 可以是 load average, runqueue length, sched latency 等
CPU 利用率用 top 看下:
top - 17:13:49 up 83 days, 23:10, 1 user, load average: 433.52, 422.54, 438.70 Tasks: 2765 total, 23 running, 1621 sleeping, 0 stopped, 34 zombie %Cpu(s): 23.4 us, 9.5 sy, 0.0 ni, 65.5 id, 0.7 wa, 0.0 hi, 1.0 si, 0.0 st
CPU 利用率拆分成了更细粒度的几部分:
- us, sys, ni - 对应 un-niced user, kernel, niced user 的 CPU 利用率
- id, wa - 对应到 idle, io wait 的比例, io wait 本质上也是一种 idle, 区别在于对应 cpu 上有等待 io 的任务
- hi, si - 对应 hardirq, softirq 的比例
- st - 因为超卖等原因, hypervisor 从该 vm 偷走的时间 (todo: docker)
继续看 load average, 3 个数值分别对应到系统 1/5/15 分钟内的系统平均 load, load 是个比较模糊的概念, 可以简单认为是对资源有需求的任务数, 包括 on cpu, runnable 的任务, 也包括等待 IO 及任意 D 状态的任务. load 使用采样的方式, 每隔 5 秒采样一样, 越近的采样权重越大, 这样从 1/5/15 的趋势可以看出系统压力的变化。
load average: 433.52, 422.54, 438.70
在这台 128 个 CPU 的机器上, loadavg 看起来有些偏高, 但是具体影响目前不得而知, 性能低是相对具体目标而言的, load 高只是现象, 它可能相关也可能无关, 但至少是值得注意的。
再看下 dstat 关于任务状态的统计:
- run - 对应到/proc/stat 里面的 procs_running, 也就是 runnable 任务数
- blk - 对应到/proc/stat 里面的 procs_blocked, 阻塞在 I/O 的任务数
实际上和 loadavg 没有本质区别, 只是 load 模糊了 runnable 和 D 状态, 同时 load 使用 1/5/15 分钟的力度, 而 dstat 可以使用更细粒度, 如果只看某一时间点用 load, 如果要观察长时间的变化使用 dstat (/proc/stat)。
#dstat -tp ----system---- ---procs--- time |run blk new 07-03 17:56:50|204 1.0 202 07-03 17:56:51|212 0 238 07-03 17:56:52|346 1.0 266 07-03 17:56:53|279 5.0 262 07-03 17:56:54|435 7.0 177 07-03 17:56:55|442 3.0 251 07-03 17:56:56|792 8.0 419 07-03 17:56:57|504 16 152 07-03 17:56:58|547 3.0 156 07-03 17:56:59|606 2.0 212 07-03 17:57:00|770 0 186
内存
这里主要关注内存容量方面, 不关注访存的性能。
- Utilization. 内存利用率
- Saturation. 这里主要考察内存回收算法的效率
简单的内存利用率用 free 命令:
- total - MemTotal + SwapTotal, 一般来说 MemTotal 会略小于真实的物理内存
- free - 未使用的内存. Linux 倾向于缓存更多页面以提高性能, 所以不能简通过 free 来判断内存是否不足
- buff/cache - 系统缓存, 一般不需要严格区分 buffer 和 cache
- available - 估计的可用物理内存大小
- used - 等于 total - free - buffers - cache
- Swap - 该机器上未配置
#free -g total used free shared buff/cache available Mem: 503 193 7 2 301 301 Swap: 0 0 0
更详细的信息可以直接去读/proc/meminfo:
#cat /proc/meminfo MemTotal: 527624224 kB MemFree: 8177852 kB MemAvailable: 316023388 kB Buffers: 23920716 kB Cached: 275403332 kB SwapCached: 0 kB Active: 59079772 kB Inactive: 431064908 kB Active(anon): 1593580 kB Inactive(anon): 191649352 kB Active(file): 57486192 kB Inactive(file): 239415556 kB Unevictable: 249700 kB Mlocked: 249700 kB SwapTotal: 0 kB SwapFree: 0 kB [...]