性能指标
平均负载
定义
平均负载是指单位时间内,系统处于可运行状态和不可中断状态的平均进程数,<br>也就是平均活跃进程数,它和 CPU 使用率并没有直接关系
可运行状态进程
可运行状态的进程,是指正在使用 CPU 或者正在等待 CPU 的进程,也就是我们常用 ps 命令看到的,处于 R 状态(Running 或 Runnable)的进程。
不可中断状态进程
不可中断状态的进程则是正处于内核态关键流程中的进程,并且这些流程是不可打断的,比<br>如最常见的是等待硬件设备的 I/O 响应,也就是我们在 ps 命令中看到的 D 状态<br>(Uninterruptible Sleep,也称为 Disk Sleep)的进程
CPU使用率
用户CPU
系统CPU
IOWAIT
软中断
而下半部则是由内核触发,也就是我们常说的软中断,特点是延迟执行。<br>以内核线程的方式执行,并且每个 CPU 都对应一个软中断内核线程,名字为 “ksoftirqd/CPU<br>编号”,比如说, 0 号 CPU 对应的软中断内核线程的名字就是 ksoftirqd/0。<br>
Linux 中的软中断包括网络收发、定时、调度、RCU 锁等各种类型,我们可以查看 proc 文<br>件系统中的 /proc/softirqs ,观察软中断的运行情况
/proc/interrupts 提供了硬中断的运行情况。
硬中断
上半部直接处理硬件请求,也就是我们常说的硬中断,特点是快速执行;
/proc/softirqs 提供了软中断的运行情况;<br>
窃取CPU
表示被其他虚拟机占用的 CPU 时间百分比,一般是在虚拟化中使用
节拍率HZ
为了维护 CPU 时间,Linux 通过事先定义的节拍率(内核中表示为 HZ),触发时间中<br>断,并使用全局变量 Jiffies 记录了开机以来的节拍数。每发生一次时间中断,Jiffies 的值<br>就加 1。
grep 'CONFIG_HZ=' /boot/config-$(uname -r)
节拍率 HZ 是内核的可配选项,可以设置为 100、250、1000 等。不同的系统可能设置不<br>同数值,你可以通过查询 /boot/config 内核选项来查看它的配置值。比如在我的系统中,<br>节拍率设置成了 250,也就是每秒钟触发 250 次时间中断
上下文切换
自愿上下文切换
指进程无法获取所需资源,导致的上下文切换。比如说, I/O、<br>内存等系统资源不足时,就会发生自愿上下文切换。
自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;
非自愿上下文切换
指进程由于时间片已到等原因,被系统强制调度,进而发生的<br>上下文切换。比如说,大量进程都在争抢 CPU 时,就容易发生非自愿上下文切换。
非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU<br>的确成了瓶颈;
进程上下文切换
进程是由内核来管理和调度的,进程的切换只能发生在内核态。进程的上下文不仅包括了虚拟内存、栈、全局变量等用户空间的资源,还包括了内核堆栈、<br>寄存器等内核空间的状态。:在保存当前进程的内核状态和 CPU 寄存器之前,需要先把该进程的虚拟内存、栈等保存下来;而加载了下一进程的内核态后,还需要刷新进程的虚拟内存和用户栈。
线程上下文切换
当进程只有一个线程时,可以认为进程就等于线程。当进程拥有多个线程时,这些线程会共享相同的虚拟内存和全局变量等资源。这些资源在上下文切换时是不需要修改的。另外,线程也有自己的私有数据,比如栈和寄存器等,这些在上下文切换时也是需要保存<br>的
中断上下文切换
为了快速响应硬件的事件,中断处理会打断进程的正常调度和执行,转而调用中断处理程<br>序,响应设备事件。而在打断其他进程时,就需要将进程当前的状态保存下来,这样在中断<br>结束后,进程仍然可以从原来的状态恢复运行。
中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看 /proc/interrupts 文<br>件来分析具体的中断类型。
CPU缓存命中率
CPU 缓存的速度介于 CPU 和内存之间,缓存的是热点的内存数<br>据。根据不断增长的热点数据,这些缓存按照大小不同分为 L1、L2、L3 等三级缓存,其中<br>L1 和 L2 常用在单核中, L3 则用在多核中。从 L1 到 L3,三级缓存的大小依次增大,相应的,性能依次降低(当然比内存还是好得<br>多)。而它们的命中率,衡量的是 CPU 缓存的复用情况,命中率越高,则表示性能越好
性能剖析
top/ps
top 显示了系统总体的 CPU 和内存使用情况,以及各个进程的资源使用情况。<br>ps 则只显示了每个进程的资源使用情况。
status 列含义<br>R 是 Running 或 Runnable 的缩写,表示进程在 CPU 的就绪队列中,正在运行或者正<br>在等待运行。<br>D 是 Disk Sleep 的缩写,也就是不可中断状态睡眠(Uninterruptible Sleep),一般表<br>示进程正在跟硬件交互,并且交互过程不允许被其他进程或中断打断。<br>Z 是 Zombie 的缩写,如果你玩过“植物大战僵尸”这款游戏,应该知道它的意思。它<br>表示僵尸进程,也就是进程实际上已经结束了,但是父进程还没有回收它的资源(比如进<br>程的描述符、PID 等)。<br>S 是 Interruptible Sleep 的缩写,也就是可中断状态睡眠,表示进程因为等待某个事件<br>而被系统挂起。当进程等待的事件发生时,它会被唤醒并进入 R 状态。<br>I 是 Idle 的缩写,也就是空闲状态,用在不可中断睡眠的内核线程上。前面说了,硬件交<br>互导致的不可中断进程用 D 表示,但对某些内核线程来说,它们有可能实际上并没有任<br>何负载,用 Idle 正是为了区分这种情况。要注意,D 状态的进程会导致平均负载升高,<br>I 状态的进程却不会。<br>第一个是 T 或者 t,也就是 Stopped 或 Traced 的缩写,表示进程处于暂停或者跟踪状<br>态<br>另一个是 X,也就是 Dead 的缩写,表示进程已经消亡,所以你不会在 top 或者 ps 命令<br>中看到它<br>
vmstat
是一个常用的系统性能分析工具,主要用来分析系统的内存使用情况,也常用来分
析 CPU 上下文切换和中断的次数
vmstat 5
cs(context switch)是每秒上下文切换的次数。<br> in(interrupt)则是每秒中断的次数。<br> r(Running or Runnable)是就绪队列的长度,也就是正在运行和等待 CPU 的进程 数。<br> b(Blocked)则是处于不可中断睡眠状态的进程数<br>
mpstat
一个常用的多核 CPU 性能分析工具,用来实时查看每个 CPU 的性能指标,以<br>及所有 CPU 的平均指标。
mpstat -P ALL 5
-P ALL 表示监控所有 CPU,后面数字 5 表示间隔 5 秒后输出一组数据
sar
sar 是一个系统活动报告工具,既可以实时查看系统的当前活动,又可以配置保存和报告历史统计数据。
# -n DEV 表示显示网络收发的报告,间隔 1 秒输出一组数据<br>$ sar -n DEV 1
pidstat
一个常用的进程性能分析工具,用来实时查看进程的 CPU、内存、I/O 以及上<br>下文切换等性能指标。
pidstat -u 5 1
间隔 5 秒后输出一组数据
pidstat -w -u 1 -t
-w 参数表示输出进程切换指标,而 -u 参数则表示输出 CPU 使用指标 -t显示线程
pidstat -d 1 10
-d 显示磁盘读写信息
strace
perf
perf top -g -p [pid]
输出结果中,第一行包含三个数据,分别是采样数(Samples)、事件类型(event)和事<br>件总数量(Event count)。比如这个例子中,perf 总共采集了 833 个 CPU 时钟事件,而<br>总事件数则为 97742399。<br>第一列 Overhead ,是该符号的性能事件在所有采样中的比例,用百分比来表示。<br>第二列 Shared ,是该函数或指令所在的动态共享对象(Dynamic Shared Object),<br>如内核、进程名、动态链接库名、内核模块名等。<br>第三列 Object ,是动态共享对象的类型。比如 [.] 表示用户空间的可执行程序、或者动<br>态链接库,而 [k] 则表示内核空间。<br>最后一列 Symbol 是符号名,也就是函数名。当函数名未知时,用十六进制的地址来表<br>示。<br>
perf record -g seleep 15 && perf report
# 记录性能事件,等待大约 15 秒后按 Ctrl+C 退出<br>$ perf record -g<br># 查看报告<br>$ perf report
execsnoop
一个专为短时进程设计的工具。它通过 ftrace 实时监控进程的 exec() 行<br>为,并输出短时进程的基本信息,包括进程 PID、父进程 PID、命令行参数以及执行的结<br>果。
proc文件系统
grep 'model name' /proc/cpuinfo | wc -l
查看cpu个数
watch -d cat /proc/interrupts
提供了一个cpu只读的中断使用情况
cat /proc/stat | grep ^cpu
user(通常缩写为 us),代表用户态 CPU 时间。注意,它不包括下面的 nice 时间,但<br>包括了 guest 时间。<br>nice(通常缩写为 ni),代表低优先级用户态 CPU 时间,也就是进程的 nice 值被调整<br>为 1-19 之间时的 CPU 时间。这里注意,nice 可取值范围是 -20 到 19,数值越大,优<br>先级反而越低。<br>system(通常缩写为 sys),代表内核态 CPU 时间。<br>idle(通常缩写为 id),代表空闲时间。注意,它不包括等待 I/O 的时间(iowait)。<br>iowait(通常缩写为 wa),代表等待 I/O 的 CPU 时间。<br>irq(通常缩写为 hi),代表处理硬中断的 CPU 时间。<br>softirq(通常缩写为 si),代表处理软中断的 CPU 时间。<br>steal(通常缩写为 st),代表当系统运行在虚拟机中的时候,被其他虚拟机占用的 CPU<br>时间。<br>guest(通常缩写为 guest),代表通过虚拟化运行其他操作系统的时间,也就是运行虚<br>拟机的 CPU 时间。<br>guest_nice(通常缩写为 gnice),代表以低优先级运行虚拟机的时间。
/proc/stat<br>提供的就是系统的 CPU 和任务统计信息,代为是user_hz 10ms
/proc/[pid]/stat
stress
一个 Linux 系统压力测试工具,这里我们用作异常进程模拟平均负载升高的场<br>景
stress --cpu 1 --timeout 600
模拟 CPU压力
stress-ng -i 1 --hdd 1 --timeout 600
模拟 I/O 压力,即不停地执行 sync:
1: 对于pidstat,vmstat,top无法定位到问题的时候。<br>2: 可以选择perf record -g 记录。<br>3: 用perf report查看是否可以定位到问题。<br>4: 用pstree | grep [xx],这样定位到具体的调用方法里。<br>5: 用grep [xx] -r [项目文件],找到具体代码位置
hping3
hping3 是一个可以构造 TCP/IP 协议数据包的工具,可以对系统进行安全审计、防火墙测试等。
# -S 参数表示设置 TCP 协议的 SYN(同步序列号),-p 表示目的端口为 80<br># -i u100 表示每隔 100 微秒发送一个网络帧<br># 注:如果你在实践过程中现象不明显,可以尝试把 100 调小,比如调成 10 甚至 1<br>$ hping3 -S -p 80 -i u100 192.168.0.30
tpcdump
tcpdump 是一个常用的网络抓包工具,常用来分析各种网络问题
# -i eth0 只抓取 eth0 网卡,-n 不解析协议名和主机名<br># tcp port 80 表示只抓取 tcp 协议并且端口号为 80 的网络帧<br>$ tcpdump -i eth0 -n tcp port 80
调优方法
CPU绑定
# cpu-list可以是0,1这样的一个核,也可以是1-2这样的,表示绑定在1和2上面<br># pid 表示进程号<br>taskset -cp cpu-list pid
进程CPU资源限制
中断负载均衡
CPU缓存
NUMA优化
CPU独占
一,隔离CPU,避免其它线程run在被隔离的CPU上.<br>二,绑定所有的interrupts到非隔离的CPU上,避免被隔离的CPU收到interrupt.<br>三,据你希望地,把特定的线程绑定到某一被隔离的CPU上.