之前在《1核1.9G的小鸡上到底跑了多少服务》那篇的结尾我挖了个坑——说下一步要搞 zram 压缩交换。今天终于填上了,顺便把过程记录下来,给同样在破 VPS 上挣扎的朋友参考。
zram 到底是什么
简单说,zram 就是把一块内存虚拟成压缩过的块设备,然后拿来做 swap。听起来有点绕,但实际上就是:
- 传统 swap:内存不够了 → 把数据写到硬盘上 → 慢了但能保命
- zram swap:内存不够了 → 把数据压缩后留在内存里 → 省了 IO 但挤占实际内存
关键区别在哪?硬盘 swap 慢是因为 IO 速度瓶颈(我那 20G 的 Contabo 虚拟盘,随机读写大概就几十 MB/s),而 zram 压缩/解压全靠 CPU。现代 CPU(我那台 E5-2660 v2 算老的了)压 LZO 或者 zstd 也就几微秒的事。用 CPU 时间换 IO 时间,在小内存机器上很划算。
怎么装的
Ubuntu 24.04 默认没装 zram-tools,需要手动来:
| |
装完配置就在 /etc/default/zramswap。默认配置保守得一匹,只给总内存的 25%,我改了一下:
| |
这里我不推荐用 lz4(虽然更快但压缩率低),也不推荐用 zstd 的极端压缩级别。默认的 zstd 快又好,对小内存机器刚刚好。
然后重启服务:
| |
zramctl 能看到实际压缩比。我跑了几天观察了一下,压缩比大概在 2.5x 到 3x 之间——也就是说用了 100M 的 zram swap,实际在内存里只占了 35-40M 左右。
效果到底怎么样
装之前我观察过最差情况:Hermes gateway 加上 Hugo 构建同时跑,内存干到 1.7G,剩下 200M 还撑着一堆服务。那个时候一卡一卡的,top 看 wa 指标飘到 10%+。
装完之后,同样的负载下,系统开始把不常用的内存页压缩到 zram 里,多腾出了大概 200-300M 的可用内存给缓存和活跃进程。wa 基本稳定在 0-2%,不再吃磁盘 swap 了。
这是用 vmstat 1 观察的对比:
- 旧方案(磁盘 swap):si/so(swap in/out)偶尔跳到几百 KB/s,然后系统开始卡
- 新方案(zram swap):si/so 几乎为 0,si 偶有几十 KB,几乎不调磁盘
注意事项
别关磁盘 swap。zram 适合放热数据(经常被 swap 进出的内存页),磁盘 swap 放冷数据(很久才访问一次的)。两个一起用效果最好。配置 zram 的优先级比磁盘高就行。
CPU 消耗。我测了一下,E5-2660 v2 这种太监 U 压 zstd 大概 0.5%-1% 的单核,基本可以忽略。要是你用的树莓派那种级别的 CPU,建议用 lzo 算法,压缩率低一点但 CPU 开销更低。
oomd / earlyoom 仍然要装。zram 不是银弹,内存真的爆的时候它该 OOM 还是 OOM。zram 只是让系统在内存压力下的响应更平滑,不是让系统变出更多内存。
swapiness 建议调低。我之前设了 10,装了 zram 之后可以稍微调到 20-30。因为 zram 的代价比磁盘 swap 小得多,系统可以稍微积极一点搞压缩换页。
整体感受
花五分钟配置,效果立竿见影。虽然不是说装完就能起飞,但最卡的时候明显比之前顺畅了一截。说到底小内存机器的优化就是各种小技巧的组合——关服务 + 换工具 + 压缩 + 合理配置,每项省几十 M,加起来就多出一两百 M 的富裕空间了。
下一步可能会搞下 earlyoom,彻底杜绝 OOM 把 SSH 给杀了的尴尬场景。不过那个下篇文章再说。
行了,这个坑填完了,下一坑是啥来着?我看看 todo list……先不看了,回头再说。