登录
推荐 文章 Go 技术 课程 下载 专题 AI
首页 >  文章 >  linux

Linux vmstat 的 si 和 so 怎么判断交换抖动

来源:17golang原创

时间:2026-10-07 01:09:21 116浏览 收藏

我第一次在生产机上看到 swpd 很大时,直觉是“机器正在疯狂换页”。后来连续看了几十秒才发现,si 和 so 一直是 0:那只是一些冷页仍留在交换区,并不等于系统正在抖动。真正值得警惕的是交换流量持续发生,尤其是页面刚换出又很快被换回,同时业务延迟、任务阻塞或内存压力也在上升。

官方资料:https://man7.org/linux/man-pages/man8/vmstat.8.html、https://docs.kernel.org/accounting/psi.html

判断交换抖动没有一个适用于所有机器的固定 si/so 阈值。先用 vmstat -y -w -t 1 60 连续采样:如果 si、so 在多个采样周期反复或同时非零,并伴随 b、wa、memory PSI 或业务延迟上升,就应按交换抖动排查;只有 swpd 非零而 si/so 长期为 0,通常不是抖动。

先分清 swpd、si 和 so 各自回答什么

vmstat 的这三个字段很容易被混在一起。swpd 是当前已经占用的交换空间,是一个存量;si 是每秒从交换设备读回内存的量,so 是每秒从内存写到交换设备的量,它们是采样周期内的流量。si、so 的显示单位受 -S 选项影响,因此跨机器比较前要先确认单位。

这也解释了一个常见现象:系统以前有过内存压力,部分长期不用的匿名页被换出,后来压力已经消失,但这些冷页没有被访问,于是 swpd 仍不为 0,si、so 却保持为 0。此时为了把 swpd 清零而直接执行 swapoff,可能反而制造新的内存风险。

vmstat 中物理内存、交换设备、si、so、swpd 与任务压力的静态关系图
图1:结构图。swpd 表示交换区中的存量,si 与 so 表示两个方向的速率;任务阻塞和 I/O 等待是判断影响面的辅助信号。这不是终端截图或运行结果。

用 60 秒采样避开第一行平均值

我现在排查时会先保留一分钟原始观察窗口,而不是截取单行。vmstat 手册明确说明:第一份报告是从上次开机到现在的平均值,后续报告才对应指定的采样间隔。使用 procps-ng 的 -y 可以直接省略第一份报告,-w 避免大数值挤乱列宽,-t 便于把波动与业务事件对齐。

# 每秒采样一次,共观察 60 个有效周期
vmstat -y -w -t 1 60

检查时先盯住 si 和 so 的连续性,再看同一行的 b 与 wa。单个采样点非零只能说明那个瞬间发生了换页,不能独立证明抖动。若系统里的 vmstat 不支持 -y,可以运行普通的 vmstat 1 61,人工忽略第一份数据,不要把开机以来的平均值与一秒采样混在一起。

按四种形态判断交换压力

观察形态更可能的含义判断
swpd > 0,si/so 长时间为 0冷页留在交换区,当前没有明显交换流量通常不是抖动
si 或 so 偶尔出现一次,随后归零进程启动、恢复访问冷页或短时内存峰值继续观察,不凭单点下结论
so 连续非零,si 很少,内存压力上升内核正在持续回收匿名页,工作集可能逼近物理内存已经有交换压力
si 与 so 在多个周期反复非零,同时 b、wa 或延迟升高活跃工作集在内存与交换设备之间来回搬运高度怀疑交换抖动

这里最重要的是“持续”和“影响”。NVMe、SATA SSD、云盘和机械盘承受同样交换速率时,延迟后果可能完全不同;数据库、Java 服务和批处理任务的可接受范围也不一样。因此,与其背一个“si 超过多少就危险”的数字,不如比较同一业务的正常基线,并观察用户请求延迟或吞吐是否同步恶化。

把 b、wa 和可用内存放进同一张判断图

b 表示等待 I/O 完成而阻塞的进程数,wa 表示 CPU 等待 I/O 的时间占比。它们并不专属于交换 I/O,普通磁盘读写同样会推高这些值,所以只能作为相关证据。实际排查时,我会同时打开另一个窗口查看可用内存:

# 查看可用内存与交换区存量
free -h

# 查看累计换入、换出页计数
grep -E '^(pswpin|pswpout) ' /proc/vmstat

如果 so 持续出现、可用内存处于低位、pswpout 在观察窗口内不断增长,而 b 或 wa 也同步抬升,交换正在对运行造成影响的证据就更完整。反过来,如果块设备本身繁忙但 si/so 为 0,应转向普通存储 I/O 排查,不要把所有 wa 都归因于 swap。

交换活动、内存余量、阻塞等待与业务影响之间的静态判断关系图
图2:结构图。交换活动必须和内存余量、阻塞等待及业务影响一起判断;连线表示证据关联,不表示执行时序。

用 memory PSI 确认任务是否真的被内存拖住

较新的 Linux 环境通常还能读取 /proc/pressure/memory。PSI 的 some 表示至少有部分任务因内存资源受阻,full 表示所有非空闲任务同时受阻;内核文档把持续处于 full 状态的工作负载视为抖动。这个指标比“交换了多少字节”更接近用户实际感受到的停顿。

# 查看最近 10、60、300 秒的内存压力占比
cat /proc/pressure/memory

若文件不存在,说明当前内核或配置没有提供可用的 PSI 接口,继续使用 vmstat、业务延迟和累计页计数即可。若 full avg10 明显上升,并且同一时间 si/so 来回出现,这比单看 swpd 更能支持“系统正在交换抖动”的判断。

确认抖动后先处理工作集,不急着改 swappiness

真正遇到抖动时,我会先找出是谁扩大了活跃工作集,以及最近是否发生了并发、缓存、批处理或容器限额变化:

# 按常驻内存从高到低列出进程,先确认主要使用者
ps -eo pid,comm,rss,vsz --sort=-rss | head -n 15

# 只读取当前 swappiness,先留证据再决定是否调整
sysctl vm.swappiness

短期处置通常是降低并发、暂停可重试批任务、限制缓存增长,或把部分负载迁走;长期处置则是修正内存泄漏、重新估算工作集、调整容器内存上限或增加物理内存。swappiness 描述内核在交换页与文件页回收之间的相对成本偏好,并不是“禁止抖动”的开关。直接把它改成 0,既不能弥补工作集超过内存,也可能把问题推向更剧烈的直接回收或 OOM。

同样,不要在未确认可用内存足够时直接 swapoff -a。该操作需要把仍在交换区的页重新装回内存,压力已经很高时可能让故障进一步扩大。更安全的顺序是先降低工作集,确认 si/so、PSI 和业务延迟回落,再评估是否需要改配置。

常见问题

si 很高但 so 为 0,一定是交换抖动吗?

不一定。应用重新访问之前换出的冷页时,可能出现一段换入而没有同步换出。只有该现象持续、反复,并伴随任务阻塞或业务性能下降,才更接近抖动。

swpd 很大但 si 和 so 都是 0,需要清理吗?

通常不需要仅为了数值好看而清理。它说明有页留在交换区,但当前没有明显搬运。应优先关注可用内存、业务表现和后续采样趋势。

只有 so 持续非零说明什么?

这说明系统正在持续把页换出,已经存在内存回收压力,但不一定已经形成来回换页。继续观察 si 是否随后升高,并结合 PSI、b、wa 和业务延迟判断影响。

vmstat 的 si、so 能直接和两台机器比较吗?

不能只比数字。先统一 -S 单位,再考虑物理内存规模、交换介质速度、采样间隔和工作负载。更可靠的是在同一主机上与正常时段基线比较。

声明:本文转载于:17golang原创 如有侵犯,请联系study_golang@163.com删除
相关阅读
更多>
最新阅读
更多>
课程推荐
更多>