服务器内存只有 422MB,跑着 sing-box、fail2ban、nezha 之类的东西,剩下能用的不到 20MB。说实话能撑着不崩已经挺不容易的了。
磁盘 swap 是有的,但那东西慢得像在泥里爬,写进去再读出来,延迟高得离谱。看到一个叫 zram 的东西,装上之后顺手记一下。
zram 是什么
简单说就是:在内存里划一块地方,压缩存数据,当 swap 用。
比起写到磁盘,速度快几十倍,压缩率还不错,zstd 算法大概能压到原来的 1/3 到 1/8。代价是要消耗一点 CPU,不过现代 CPU 这点开销基本可以忽略。
传统磁盘 swap 和 zram 的区别大概是这样:
| 磁盘 swap | zram | |
|---|---|---|
| 位置 | 磁盘 | 内存(压缩) |
| 速度 | 慢 | 很快 |
| 压缩 | 没有 | 有(zstd/lz4 等) |
| 适合 | 大内存溢出兜底 | 小内存日常使用 |
两个可以共存,我现在就是磁盘 swap 和 zram 叠在一起用的。
装
sudo apt install zram-tools -y配置文件在 /etc/default/zramswap,写两行就够了:
sudo bash -c 'echo "ALGO=zstdPERCENT=40" > /etc/default/zramswap'PERCENT=40 就是用物理内存的 40% 做 zram。422MB × 40% ≈ 168MB,差不多。内存越小这个比例可以稍微调高,内存够大其实没必要装 zram。
然后启动:
sudo systemctl enable zramswapsudo systemctl start zramswap验证一下:
zramctlfree -h看到 ALGORITHM 那列显示 zstd,MOUNTPOINT 显示 [SWAP] 就对了。
我这边装完的输出是这样的:
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT/dev/zram0 zstd 168.8M 40K 4.9K 60K 1 [SWAP]40KB 的数据压完只有 4.9KB,压缩比将近 8:1,说明当时塞进去的东西挺好压的。
配合 sysctl 用
装完 zram 之后,vm.swappiness 可以调高一些。这个参数控制内核有多积极地把内存页换出到 swap,默认是 60。
磁盘 swap 的时候大家一般调低,因为磁盘 IO 太慢了,能不换就不换。但 zram 在内存里,速度完全不一样,可以大胆一点:
vm.swappiness = 80vm.min_free_kbytes = 16384vm.vfs_cache_pressure = 150vfs_cache_pressure 调高是让内核更积极地回收文件缓存,把内存还给进程用。
改完 sudo sysctl -p 让它生效。
装完的效果
可用内存从将近耗尽(available < 20MB)变成了 65MB 左右,OOM 的概率小了很多。
不是什么大优化,但对小内存机器来说够用了。毕竟才花了五分钟。
常用命令
# 看状态和压缩率zramctl
# 看内存free -h
# 重启(改配置后用)sudo systemctl restart zramswap