转载请注明出处:小锋学长生活大爆炸xfxuezhagn.cn
如果本文帮助到了你,欢迎点赞、收藏、关注哦~
小内存设备救星:zram + lz4 让 4G 内存也能流畅跑 Docker
适用于:飞牛私有云 fnOS ARM 版 / 电视盒子 / 树莓派 / 各类小内存 ARM 设备
一、问题背景
在 ARM 盒子(如电视盒子、开发板)上运行 NAS 系统时,经常遇到这样的困境:
- • 物理内存只有 3-4GB
- • 运行 Docker 容器后内存迅速耗尽
- • 系统开始频繁使用磁盘 swap,导致卡顿甚至卡死
- • 磁盘 swap 放在 eMMC/SD 卡上,读写速度慢且消耗寿命
传统 swap 的痛点
| 痛点 | 说明 |
|---|---|
| 速度慢 | eMMC/SD 卡读写仅 50-100MB/s |
| 寿命短 | 频繁擦写加速存储芯片老化 |
| 空间占用 | swap 文件占用宝贵的磁盘空间 |
| 体验差 | 一旦触发磁盘 swap,系统明显卡顿 |
典型场景:4G 内存跑 3-4 个 Docker 容器,内存占满后开始 swap,NAS 管理界面都打不开。
二、zram 是什么?

2.1 核心概念
zram(以前叫 compcache)是 Linux 内核的一个模块,它:
-
- 在物理内存中划分一块区域
-
- 将准备 swap 出去的数据实时压缩后存储
-
- 用 CPU 算力换取内存空间
一句话总结:用内存的一部分假装成磁盘 swap,但数据是压缩存放的。
2.2 为什么比磁盘 swap 快?
| 对比项 | 磁盘 swap | zram |
|---|---|---|
| 存储介质 | eMMC/SSD/HDD | 内存(RAM) |
| 读写速度 | 50-500 MB/s | 数 GB/s(内存速度) |
| 延迟 | 毫秒级 | 微秒级 |
| 寿命影响 | 消耗磁盘寿命 | 无 |
| 额外开销 | 无 | CPU 压缩/解压 |
关键优势:内存访问速度是磁盘的 10-100 倍,即使加上压缩开销,zram 仍然比磁盘 swap 快得多。
2.3 压缩率如何?
zram 的压缩效果取决于数据类型:
| 数据类型 | 压缩率 | 说明 |
|---|---|---|
| 文本、代码、重复数据 | 2:1 ~ 3:1 | 省一半到三分之二内存 |
| 已压缩数据(图片、视频、加密流量) | 接近 1:1 | 省不了多少 |
| 混合场景(日常 NAS 使用) | 1.5:1 ~ 3:1 | 通常能节省 30-50% 的空间 |
举例:分配 2G zram,实际等效可能达到 3-4G 的 swap 容量。
2.4 实际效果
以学长的设备为例(3.6G 物理内存):
$ zramctl
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 lz4 1.8G 129.3M 37.6M 39.4M 6 [SWAP]
- • DATA 129.3M → 原始数据 129MB
- • COMPR 37.6M → 压缩后仅 37.6MB
- • 压缩率约 3.4:1,效果极佳
三、lz4 压缩算法
3.1 zram 支持哪些算法?
Linux 内核通常支持以下算法:
| 算法 | 压缩速度 | 压缩率 | CPU 占用 | 适用场景 |
|---|---|---|---|---|
| lz4 | 极快 | 一般 | 很低 | 小内存设备首选 |
| lzo / lzo-rle | 快 | 稍好 | 低 | 内核默认 |
| lz4hc | 快 | 较好 | 中 | 平衡选择 |
| zstd | 中等 | 很好 | 中高 | 大内存服务器 |
| deflate | 慢 | 好 | 高 | 兼容性需求 |
| 842 | 很快 | 一般 | 很低 | 特定硬件加速 |
3.2 为什么选 lz4?
对于 ARM 盒子 / 小内存设备:
-
- 压缩/解压速度最快 --- 减少 CPU 开销,系统更流畅
-
- CPU 占用最低 --- ARM 处理器性能有限,省 CPU 就是省性能
-
- 延迟最低 --- swap 操作本身已经够慢了,压缩不能成为瓶颈
-
- 实时性好 --- 适合交互式场景,不会因为压缩导致卡顿
牺牲:压缩率比 zstd 差 10-20%,但速度提升 3-5 倍,对小设备来说完全值得。
3.3 如何查看和切换算法
# 查看当前算法(方括号中为当前算法)
cat /sys/block/zram0/comp_algorithm
# 输出示例:[lzo-rle] lzo lz4 lz4hc zstd deflate 842
# 切换为 lz4(需先关闭 swap)
sudo swapoff /dev/zram0
echo lz4 | sudo tee /sys/block/zram0/comp_algorithm
sudo mkswap /dev/zram0
sudo swapon /dev/zram0
四、完整配置流程
4.1 环境准备
以 FnNAS / fnOS(飞牛私有云 ARM 版) 为例,通过 SSH 登录:
bash
ssh root@你的设备IP
4.2 检查当前状态
# 查看内存和 swap 使用情况
free -h
# 查看当前 swap 详情
swapon --show
# 查看 zram 状态(如果有)
zramctl
4.3 清理旧的 zram 配置(如有)
如果系统之前配置过 zram 但失败了,先清理:
# 停止可能冲突的服务
sudo systemctl stop systemd-zram-setup@zram0.service 2>/dev/null
sudo systemctl stop zramswap.service 2>/dev/null
# 关闭所有 swap
sudo swapoff -a
# 重置所有 zram 设备
sudo zramctl --reset /dev/zram0 2>/dev/null
sudo zramctl --reset /dev/zram1 2>/dev/null
4.4 创建 zram 设备
# 加载 zram 模块
sudo modprobe zram num_devices=1
# 创建 zram0 设备,大小 2GB,算法 lz4
sudo zramctl /dev/zram0 --size 2G --algorithm lz4
# 如果 zramctl 不支持 --algorithm 参数,用 sysfs:
# echo lz4 | sudo tee /sys/block/zram0/comp_algorithm
# echo 2G | sudo tee /sys/block/zram0/disksize
大小建议:zram 大小通常设为物理内存的 50%-100%。4G 内存设 2G,8G 内存设 4G。
4.5 启用 zram swap
# 格式化为 swap
sudo mkswap /dev/zram0
# 启用,并设置高优先级(-p 100)
# 优先级越高,系统越优先使用
sudo swapon /dev/zram0 -p 100
# 重新启用磁盘 swap(作为兜底,优先级低)
sudo swapon /mnt/.swap/swapfile
4.6 验证配置
# 查看内存状态
free -h
# 查看 swap 优先级
swapon --show
# 查看 zram 详情
zramctl --output-all
预期输出:
$ free -h
total used free shared buff/cache available
Mem: 3.6Gi 2.7Gi 100Mi 280Mi 1.2Gi 901Mi
Swap: 3.0Gi 591Mi 2.4Gi
$ swapon --show
NAME TYPE SIZE USED PRIO
/mnt/.swap/swapfile file 1024M 256.2M -2 # 磁盘 swap,兜底
/dev/zram0 partition 2G 335.3M 100 # zram,优先使用
$ zramctl
NAME ALGORITHM DISKSIZE DATA COMPR TOTAL STREAMS MOUNTPOINT
/dev/zram0 lz4 2G 23.3M 8.5M 8.5M 6 [SWAP]
4.7 设置开机自动生效
创建 systemd 服务:
sudo tee /etc/systemd/system/zram-swap.service > /dev/null << 'EOF'
[Unit]
Description=Zram Swap with lz4
After=local-fs.target
[Service]
Type=oneshot
ExecStartPre=-/sbin/modprobe zram
ExecStartPre=-/sbin/zramctl --reset /dev/zram0
ExecStart=/sbin/zramctl /dev/zram0 --size 2G --algorithm lz4
ExecStart=/sbin/mkswap /dev/zram0
ExecStart=/sbin/swapon /dev/zram0 -p 100
ExecStart=/sbin/swapon /mnt/.swap/swapfile
ExecStop=/sbin/swapoff /dev/zram0
ExecStop=/sbin/swapoff /mnt/.swap/swapfile
ExecStop=/sbin/zramctl --reset /dev/zram0
RemainAfterExit=yes
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
sudo systemctl enable zram-swap
sudo systemctl start zram-swap
五、进阶调优
5.1 调整 swappiness
控制系统使用 swap 的倾向:
# 查看当前值(默认通常 60)
cat /proc/sys/vm/swappiness
# 临时设为 10(减少不必要的 swap,保留给真正需要时)
echo 10 | sudo tee /proc/sys/vm/swappiness
# 永久生效
echo 'vm.swappiness=10' | sudo tee -a /etc/sysctl.conf
| 值 | 含义 |
|---|---|
| 0 | 尽量不用 swap |
| 10-30 | 保守使用,适合小内存设备 |
| 60 | 默认,平衡 |
| 100 | 积极使用 swap |
5.2 监控 zram 效率
# 查看压缩统计
cat /sys/block/zram0/mm_stat
# 查看压缩率
cat /sys/block/zram0/comp_data_size
cat /sys/block/zram0/orig_data_size
# 实时查看
cat /proc/swaps
5.3 多 zram 设备(多核优化)
如果 CPU 核心多,可以创建多个 zram 设备,每个绑定一个核心:
# 创建 4 个 zram 设备(假设 4 核)
sudo modprobe zram num_devices=4
# 每个 512M,总共 2G
for i in 0 1 2 3; do
sudo zramctl /dev/zram$i --size 512M --algorithm lz4
sudo mkswap /dev/zram$i
sudo swapon /dev/zram$i -p 100
done
现代内核通常会自动处理多线程,单设备也足够好。
六、常见问题
Q1: zram 和磁盘 swap 可以同时用吗?
可以,而且推荐。zram 优先级设高(如 100),磁盘 swap 优先级设低(如 -2)。系统会先用 zram,满了才用磁盘 swap。
Q2: zram 会消耗很多 CPU 吗?
lz4 算法下几乎无感。压缩/解压速度达到数 GB/s,对小数据量的 swap 操作来说,CPU 开销可以忽略。
Q3: 为什么 swapon 报 "Invalid argument"?
常见原因:
- • 文件系统不支持 swap(如 Btrfs、ZFS)
- • zram 设备未正确初始化
- • 设备正被占用
Q4: 重启后 zram 消失?
需要创建 systemd 服务或加入 /etc/rc.local 实现开机自动配置。
Q5: 4G 内存设多大 zram?
建议 2G。zram 太大可能挤压正常内存使用,太小则效果不明显。
Q6: 为什么 Btrfs 上不能放 swap 文件?
Btrfs 不支持传统的 swap file(或支持但条件苛刻且有风险)。解决方案:
- • 使用 zram(推荐)
- • 创建独立的 swap 分区
- • 使用 zram 替代磁盘 swap
七、总结
| 方案 | 速度 | 寿命 | 空间 | 适用场景 |
|---|---|---|---|---|
| 无 swap | --- | --- | --- | 内存极大时 |
| 磁盘 swap | 慢 | 消耗磁盘 | 占用磁盘 | 大内存服务器 |
| zram + lz4 | 快 | 无影响 | 内存内压缩 | 小内存设备首选 |
对于 ARM 盒子、NAS、树莓派等小内存设备,zram + lz4 是最优解:
- • ✅ 速度接近内存,比磁盘 swap 快 10 倍以上
- • ✅ 不消耗磁盘寿命
- • ✅ 不占用磁盘空间
- • ✅ CPU 开销极低(lz4 算法)
- • ✅ 配置简单,效果立竿见影
附录:一条命令速配
sudo bash -c 'modprobe zram; zramctl --reset /dev/zram0 2>/dev/null; zramctl /dev/zram0 --size 2G --algorithm lz4; mkswap /dev/zram0; swapon /dev/zram0 -p 100; swapon /mnt/.swap/swapfile 2>/dev/null; echo "zram OK"'
执行后运行
free -h和zramctl验证即可。
本文基于 fnOS / FnNAS ARM 版实测整理,适用于各类小内存 Linux 设备。