ZFS 的两个杀手特性:
- 快照即时 + 几乎零成本:copy-on-write,秒级、不占额外空间
- zfs send / receive:增量传输到另一台机器,做异地备份
下面在 Ubuntu 上装 ZFS、建池、配快照轮转、做远程增量备份。
1. 装 ZFS(Ubuntu 已带)
sudo apt install -y zfsutils-linux
zfs version
CentOS / RHEL:用 zfs-fuse 不行,要装 native(zfsonlinux 仓库)。
2. 建池
假设有两块裸盘 /dev/sdb /dev/sdc:
# 镜像(mirror = RAID1)
sudo zpool create tank mirror /dev/sdb /dev/sdc
# 单盘
# sudo zpool create tank /dev/sdb
# RAIDZ1 (RAID5 类似,需 ≥ 3 盘)
# sudo zpool create tank raidz /dev/sdb /dev/sdc /dev/sdd
sudo zpool status tank
sudo zpool list
sudo zfs list
tank 是池名。建议用块设备的 /dev/disk/by-id/... 而不是 /dev/sdb(重启后顺序变)。
3. 创建文件系统(dataset)
sudo zfs create tank/data
sudo zfs create tank/data/users
sudo zfs create tank/data/projects
sudo zfs list
# tank/data 96K 3.5T ...
# tank/data/users 96K 3.5T ...
# tank/data/projects 96K 3.5T ...
dataset 像目录但每个都是独立挂载 + 独立 properties。
4. 重要 properties
sudo zfs set compression=lz4 tank # 透明压缩,几乎免费
sudo zfs set atime=off tank # 关 atime,性能 +
sudo zfs set xattr=sa tank # 高效 xattr 存储
sudo zfs set recordsize=1M tank/data # 大文件场景调大
sudo zfs set quota=500G tank/data/users # 限制使用空间
sudo zfs set reservation=100G tank/data/projects # 保留 100G
compression=lz4 是 ZFS 最值得开的:CPU 开销几乎为零,能压缩出 30-50%
的额外空间。
5. 快照
sudo zfs snapshot tank/data@$(date +%F-%H%M%S)
sudo zfs list -t snapshot
# tank/data@2026-05-23-090000 0B ...
@ 后面是快照名。
恢复某个文件:
ls /tank/data/.zfs/snapshot/2026-05-23-090000/
# 像普通目录,cp 出来即可
整个 dataset 回滚到某快照:
sudo zfs rollback tank/data@2026-05-23-090000
# 注意:会丢掉快照之后的所有改动!
删快照:
sudo zfs destroy tank/data@2026-05-23-090000
6. 自动快照轮转:zfs-auto-snapshot
sudo apt install -y zfs-auto-snapshot
自动每 15 分钟 / 小时 / 天 / 周 / 月做快照并轮转:
ls /etc/cron.*/zfs-auto-snapshot
# /etc/cron.d/zfs-auto-snapshot (15min)
# /etc/cron.hourly/zfs-auto-snapshot
# /etc/cron.daily/...
# ...
# 给特定 dataset 关掉某频率
sudo zfs set com.sun:auto-snapshot:frequent=false tank/data/projects
sudo zfs set com.sun:auto-snapshot:hourly=true tank/data/projects
默认保留:96 frequent / 24 hourly / 31 daily / 8 weekly / 12 monthly。
7. zfs send:远程增量备份
第一次全量:
# 源机
sudo zfs snapshot tank/data@base
sudo zfs send tank/data@base | ssh backup@remote 'zfs receive -F tank-backup/data'
# 远端
zfs list
# tank-backup/data
之后增量:
# 源机:在前一个快照基础上做新快照
sudo zfs snapshot tank/data@2026-05-23
# 增量 send:只传 base → 2026-05-23 的差异
sudo zfs send -i tank/data@base tank/data@2026-05-23 \
| ssh backup@remote 'zfs receive tank-backup/data'
# 完成后 base 可以删掉(远端也跟着删),用新快照做下一次的 base
实际生产用 syncoid 或
zrepl 包装,自动管 base 和 retention:
sudo apt install -y sanoid
# /etc/sanoid/sanoid.conf 配置 dataset + retention
# /etc/sanoid/syncoid.conf 配置 replication
syncoid tank/data backup@remote:tank-backup/data
8. 加密
# 建 dataset 时启用加密
sudo zfs create -o encryption=on -o keyformat=passphrase \
tank/data/sensitive
# 之后挂载要解锁
sudo zfs load-key tank/data/sensitive # 输入密码
sudo zfs mount tank/data/sensitive
zfs send / receive 加 -w 直接发加密 stream(远端不需要密码,
压缩 + dedup 在加密状态下做)。
9. 校验 + scrub
sudo zpool scrub tank
sudo zpool status tank
# scan: scrub in progress since ...
# 100M scanned out of 50G at 200M/s
scrub 读全部数据 + 校验 checksum,发现损坏自动从镜像 / parity 修复。
推荐每月跑一次:
0 3 1 * * /sbin/zpool scrub tank
10. 容量监控
sudo zpool list -v tank
# NAME SIZE ALLOC FREE ...
# tank 4T 1.2T 2.8T ...
# mirror 4T 1.2T 2.8T
# sdb - - -
# sdc - - -
sudo zfs list -o name,used,avail,refer,mountpoint
ZFS 超过 80% 使用率性能急剧下降;保持在 80% 以下。
踩过的坑
- 用
/dev/sdb直接建池,机器重启 sdb 变成 sdc → 池找不到。永远用
/dev/disk/by-id/路径。 - ZFS 内存吃得多:1GB / 1TB 数据是经验值。8GB 机器跑 32TB 池可能要
调zfs_arc_max限制 ARC 缓存。 zfs destroy没确认就执行,整个 dataset + 所有快照消失。养成
-n模拟先看的习惯。- snapshot 是 read-only,但占空间 = 这个快照后所有被修改的数据。
长期保留快照 + 高频改动 = 池快速胀满。retention 不要太长。
登录后参与评论。