zram 内存压缩 Swap 完整指南:10 分钟吃透指标与调优动作
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
凌晨三点,服务器内存被吃满,磁盘 swap 开始狂转,页面故障排队几毫秒起步。内核里的 zram 可以改变这件事:它是个"压缩块设备"——把冷数据压缩后塞回内存里存着,换页不再等磁盘。本文从 Linux 内核的 zram 驱动讲起,覆盖工作原理、指标读法与生产调优动作。
zram 是怎么把冷页压回内存的
zram 在/dev/zram0这类设备上实现了块设备接口,数据却只存在内存里。一次完整的换页过程按下面几步走:
- 内存紧张时,回收路径挑出长时间不活跃的匿名页;
- 该页被写入 zram 设备,驱动调用
zcomp框架里的压缩后端(lz4、zstd 等)压缩; - 压缩后的字节存进 zsmalloc 内存池,原页面物理内存归还系统;
- 进程再次访问时触发读请求,zram 原地解压返回;全零页干脆不存,直接记一笔。
因为读写全程在 RAM 里完成,延迟比磁盘 swap 低一到两个数量级,代价是压缩和解压消耗 CPU。
指标怎么读:一张表看懂 /sys/block/zram0
所有状态都挂在 sysfs 下,字段权威定义见Documentation/ABI/testing/sysfs-block-zram:
| 文件 | 含义 | 什么时候看 |
|---|---|---|
disksize | 容量上限,单位是"未压缩数据量" | 初始化前设置 |
comp_algorithm | 当前压缩算法(初始化后不可再改) | 初始化前选择 |
mm_stat | 9 列核心数据:原始大小 / 压缩后大小 / 实际占用 / mem_limit / 峰值占用 / 相同页计数等 | 日常监控主力 |
io_stat | 失败读、失败写、notify_free 次数 | 排查异常 |
mem_used_max | 历史峰值内存占用,写 0 复位 | 观察增长趋势 |
idle/writeback | 把冷页回写到 backing 磁盘(需编译开关) | 高级用法 |
压缩率就是mm_stat前两列相除:
DEV=/sys/block/zram0 cat $DEV/mm_stat # 前两列依次为:原始数据大小、压缩后大小 awk '{printf "压缩率: %.2f 节省: %sMB\n", $1/$2, ($1-$2)/1048576}' $DEV/mm_stat经验区间:压缩率 1.5~3 属健康;低于 1.3 说明数据可压缩性差或算法没选对。
三步上手:用 zramctl 启用内存 swap
大多数发行版装了 util-linux 后就有zramctl:
zramctl /dev/zram0 -s 1G -a lz4 # 建 1G 设备,选 lz4 算法 mkswap /dev/zram0 && swapon -p 10 /dev/zram0 zramctl -v # 查看状态容量怎么定:一般取物理内存的 25%~50%。它限制的是"未压缩数据总量",实际占用的 RAM 通常只有标称的几分之一。想更省事,也可以直接写 sysfs 按官方文档Documentation/admin-guide/blockdev/zram.rst里的步骤走。
常见坑与三个调优动作
| 现象 | 可能原因 | 动作 |
|---|---|---|
| CPU 偏高 | 高压缩比算法 + 换页频繁 | 换 lz4;调小 disksize |
| 压缩率 <1.3 | 算法与数据不匹配 | 换 zstd;查业务内存画像 |
| 占用接近上限 | 碎片或容量不够 | 写compact触发整理;调大 disksize |
算法选型对照:lz4 最快但省得少,zstd 省得最多但更耗 CPU,lz4hc/lzo 居中。算法只能在初始化前选,切换必须先 reset:
cat /sys/block/zram0/comp_algorithm # 看可选列表,括号内为当前 echo 1 > /sys/block/zram0/reset echo zstd > /sys/block/zram0/comp_algorithm echo $((2*1024**3)) > /sys/block/zram0/mem_limit # 限内存,0=不限💡mem_limit容易被忽略:默认 zram 可以无限占用 RAM,给压缩池设个上限,避免极端场景把应用内存挤没。
源码地图:内核里 zram 代码在哪读
drivers/block/zram/zram_drv.c:主驱动,sysfs 属性、读写路径、mm_stat_show都在这里drivers/block/zram/zcomp.c与backend_*.c:压缩抽象层和各算法适配器Documentation/admin-guide/blockdev/zram.rst:官方使用说明与错误码表Documentation/ABI/testing/sysfs-block-zram:每个 sysfs 字段的行为定义
读代码时从mm_stat_show的 9 列格式入手,对照上表,半小时就能把指标和内核字段一一对上。
今晚就能做
modinfo zram确认内核带驱动,没有就modprobe zram- 建一个 1G 的 zram0 挂成 swap,跑半天业务
- 读一次
mm_stat,把压缩率算出来留底 - 给
mem_limit设个上限(如物理内存 20%) - 把
mm_stat前两列纳入你的监控采集,占用逼近mem_limit时告警
【免费下载链接】linuxLinux kernel source tree项目地址: https://gitcode.com/GitHub_Trending/li/linux
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考