skip to content
Logo I like chickens.
they're persistent.
Faust
you better try google.com...

zram压缩内存

/

服务器内存只有 422MB,跑着 sing-box、fail2ban、nezha 之类的东西,剩下能用的不到 20MB。说实话能撑着不崩已经挺不容易的了。

磁盘 swap 是有的,但那东西慢得像在泥里爬,写进去再读出来,延迟高得离谱。看到一个叫 zram 的东西,装上之后顺手记一下。


zram 是什么

简单说就是:在内存里划一块地方,压缩存数据,当 swap 用。

比起写到磁盘,速度快几十倍,压缩率还不错,zstd 算法大概能压到原来的 1/3 到 1/8。代价是要消耗一点 CPU,不过现代 CPU 这点开销基本可以忽略。

传统磁盘 swap 和 zram 的区别大概是这样:

磁盘 swapzram
位置磁盘内存(压缩)
速度很快
压缩没有有(zstd/lz4 等)
适合大内存溢出兜底小内存日常使用

两个可以共存,我现在就是磁盘 swap 和 zram 叠在一起用的。


Terminal window
sudo apt install zram-tools -y

配置文件在 /etc/default/zramswap,写两行就够了:

Terminal window
sudo bash -c 'echo "ALGO=zstd
PERCENT=40" > /etc/default/zramswap'

PERCENT=40 就是用物理内存的 40% 做 zram。422MB × 40% ≈ 168MB,差不多。内存越小这个比例可以稍微调高,内存够大其实没必要装 zram。

然后启动:

Terminal window
sudo systemctl enable zramswap
sudo systemctl start zramswap

验证一下:

Terminal window
zramctl
free -h

看到 ALGORITHM 那列显示 zstdMOUNTPOINT 显示 [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 在内存里,速度完全不一样,可以大胆一点:

/etc/sysctl.conf
vm.swappiness = 80
vm.min_free_kbytes = 16384
vm.vfs_cache_pressure = 150

vfs_cache_pressure 调高是让内核更积极地回收文件缓存,把内存还给进程用。

改完 sudo sysctl -p 让它生效。


装完的效果

可用内存从将近耗尽(available < 20MB)变成了 65MB 左右,OOM 的概率小了很多。

不是什么大优化,但对小内存机器来说够用了。毕竟才花了五分钟。


常用命令

Terminal window
# 看状态和压缩率
zramctl
# 看内存
free -h
# 重启(改配置后用)
sudo systemctl restart zramswap