Linux zfs运维篇:scrub、扩容、换盘

玩 ZFS 存储、搭建 NAS 或服务器存储集群,日常运维核心无非三件事:定期巡检校验、存储空间扩容、故障硬盘替换。很多人只会基础的创建存储池命令,却不懂定期 scrub 的重要性,扩容、换盘也经常踩坑,比如乱加单盘导致数据风险、扩容不生效、换盘 resilver 出错等问题。我结合长期实操经验,把 ZFS 最核心的日常运维操作、底层原理、完整命令和避坑要点全部整理出来,覆盖家用 NAS 到企业存储场景,看完就能直接落地使用。
一、scrub:自愈的”心脏”
1.1 scrub 是什么?
scrub = 遍历 pool 中所有 block,校验 checksum,发现并修复不一致的 block。
scrub 过程中:
- 读取每个 block;
- 重新计算 checksum;
- 与存储的 checksum 对比;
- 不一致 → 用冗余副本修复。
scrub 是 ZFS “端到端校验和” 价值的最终体现。
1.2 scrub 的特性
- 只读为主(除修复不一致数据外);
- 后台运行,可以暂停/恢复;
- 不影响业务(性能会降 30~50%);
- 优先级可调(zfs scrub vs zpool scrub)。
1.3 scrub 命令
# 启动 scrub $ zpool scrub tank # 看 scrub 进度 $ zpool status pool: tank state: ONLINE scan: scrub in progress since Sun Jun 23 03:00:00 2024 9.50G scanned out of 100G at 100M/s, 14h30m to go 0B repaired, 0.13% done # 暂停 scrub(OpenZFS 2.1+) $ zpool scrub -p tank # 停止 scrub $ zpool scrub -s tank
1.4 scrub vs resilver
| 操作 | 触发条件 | 行为 |
|---|---|---|
| scrub | 手动 | 校验所有 block |
| resilver | 替换/添加盘后 | 把新盘数据补全 |
1.5 scrub 频率
| 场景 | 建议频率 |
|---|---|
| 家用 | 每月 1 次 |
| 企业关键 | 每周 1 次 |
| 大容量(>50TB) | 每月 1 次,限时窗口跑 |
| 冷存储 | 每月 1 次 |
1.6 自动化 scrub
# systemd timer $ cat /etc/systemd/system/zfs-scrub-monthly.timer [Unit] Description=Monthly ZFS scrub [Timer] OnCalendar=monthly RandomizedDelaySec=4h Persistent=true [Install] WantedBy=timers.target $ cat /etc/systemd/system/zfs-scrub-monthly.service [Unit] Description=Monthly ZFS scrub [Service] Type=oneshot ExecStart=/sbin/zpool scrub tank $ systemctl enable --now zfs-scrub-monthly.timer
或者 FreeBSD cron:
# /etc/cron.d/zfs-scrub 0 4 1 * * root /sbin/zpool scrub tank
1.7 scrub 性能
scrub 性能受限于最慢的盘。一个 vdev 内所有盘要全部扫完。
# 限制 scrub 速度(避免影响业务) # zfs 模块参数 options zfs zfs_scan_idle=0 # 0 = 高优先级;1 = 空闲时跑
二、扩容
2.1 加 vdev(最常见的扩容方式)
# 看当前 pool $ zpool list NAME SIZE ALLOC FREE CKPOINT EXPANDSZ FRAG CAP DEDUP HEALTH ALTROOT tank 9.50G 1.2G 8.30G - - 5% 12% 1.00x ONLINE - # 加新 vdev(raidz2) $ zpool add tank raidz2 /dev/sdh /dev/sdi /dev/sdj /dev/sdk # 加 mirror vdev $ zpool add tank mirror /dev/sdl /dev/sdm
注意:新加的 vdev 必须是冗余的(mirror/raidz),不要加单盘 stripe。
2.2 加 L2ARC / SLOG
# 加 L2ARC $ zpool add tank cache /dev/nvme0n1p1 # 加 SLOG(独立 ZIL) $ zpool add tank log /dev/nvme1n1p1 $ zpool add tank log mirror /dev/nvme1n1p1 /dev/nvme2n1p1
2.3 加 spare(热备盘)
# 加 spare(盘坏时自动顶替) $ zpool add tank spare /dev/sdx # 启用自动替换 $ zpool replace tank /dev/sdb /dev/sdx # 手动 # 或损坏时自动
2.4 替换更大的盘
# 步骤:1 块块替换,触发自动扩容 $ zpool replace tank /dev/sdb /dev/sdb_new # 全部替换后,启用 autoexpand $ zpool set autoexpand=on tank $ zpool online -e tank # 强制扩容 # 看进度 $ zpool list
2.5 容量与时间
替换更大盘后,pool 自动扩容到最小盘的容量(raidz 是按最小成员盘算)。
例:5 块 1TB + 1 块 2TB 的 raidz2,有效空间还是 3TB((5-2) × 1TB)。要全用 2TB,需要 5 块全换 2TB。
三、换盘
3.1 故障盘识别
# 看哪个盘故障 $ zpool status pool: tank state: DEGRADED status: One or more devices has experienced an unrecoverable error... action: ... config: NAME STATE READ WRITE CKSUM tank DEGRADED 0 0 0 raidz2-0 DEGRADED 0 0 0 sdb ONLINE 0 0 0 sdc FAULTED 5 2 0 ← 故障 sdd ONLINE 0 0 0 sde ONLINE 0 0 0 sdf ONLINE 0 0 0
3.2 替换故障盘(标准流程)
# 1. 物理换盘(关电?热插?) # 多数 SATA/SAS 盘支持热插拔 # 2. 用 zpool replace 替换 $ zpool replace tank /dev/sdc /dev/sdc_new # 或更详细(指定故障盘路径) $ zpool replace tank /dev/disk/by-id/ata-WDC_WD...-sdc /dev/disk/by-id/ata-WDC_WD...-sdc-new # 3. 看 resilver 进度 $ zpool status scan: resilver in progress since Sun Jun 23 03:00:00 2024 2.5G scanned out of 100G at 200M/s, 7m to go 2.5G resilvered, 2.5% done
3.3 mirror 单独替换
# mirror vdev 中替换单盘 $ zpool replace tank /dev/sdc /dev/sdc_new
3.4 离线盘
# 标记为离线(不立即换,先把业务保住) $ zpool offline tank /dev/sdc # 重新上线 $ zpool online tank /dev/sdc
3.5 强制 detach
# 强制把盘从 pool 中移除(危险!数据可能丢) $ zpool detach tank /dev/sdc
3.6 replace 失败处理
# 场景:resilver 中断 $ zpool status # 看具体错误 # 选项 1:重新 replace $ zpool replace tank /dev/sdc /dev/sdc_new # 选项 2:先 offline 再 replace $ zpool offline tank /dev/sdc $ zpool replace tank /dev/sdc /dev/sdc_new # 选项 3:从 backup 恢复(最坏情况)
四、实战案例
案例 1:家用 4 盘 NAS 升级
# 当前:4 × 4TB raidz2,可用 8TB # 想升级到 4 × 8TB raidz2,可用 16TB # 1. 一块块替换 $ zpool replace tank /dev/sdb /dev/sdb_8t $ zpool replace tank /dev/sdc /dev/sdc_8t $ zpool replace tank /dev/sdd /dev/sdd_8t $ zpool replace tank /dev/sde /dev/sde_8t # 2. 启用自动扩容 $ zpool set autoexpand=on tank $ zpool online -e tank # 3. 看结果 $ zpool list NAME SIZE ALLOC FREE ... CAP tank 32T 8T 24T ... 25% # 总容量 32T(4×8T),可用 16T(raidz2 损失 2 块)
案例 2:故障盘紧急处理
# 1. 收到 SMART 告警 $ smartctl -a /dev/sdc # ... critical warning ... # 2. 看 pool 状态 $ zpool status tank # sdc 有 CKSUM 错误,但还没 FAULTED # 3. 主动 replace(不等完全坏) $ zpool replace tank /dev/sdc /dev/sdc_new
案例 3:扩容(不破坏数据)
# 当前:raidz2 4 盘,可用 8TB # 想加 2 块盘(变成 2 个 vdev) # 1. 加 vdev $ zpool add tank raidz2 /dev/sdh /dev/sdi /dev/sdj /dev/sdk # 2. 看结果 $ zpool list # SIZE 翻倍 # 3. 数据会自动重新分布到所有 vdev # 期间性能会下降(migration I/O)
五、扩容期间的性能
扩容会触发数据迁移:
- 已有数据部分会重新分布到新 vdev;
- 性能下降 30~50%;
- 大量数据时耗时较长(几天)。
# 限制迁移速度 $ zpool set migration_limit=50M tank # 50 MB/s # 取消限速 $ zpool set migration_limit=none tank
经验:
- 在业务低峰扩容;
- 提前通知用户;
- 监控 zpool iostat 确认完成。
六、resilver 性能
resilver 速度受限于多个因素:
- 盘数(更多盘 = 更长);
- 盘速(最慢盘决定);
- CPU(校验计算);
- I/O 队列。
# 限速 $ zpool set resilver=bandwidth tank # 实际限速配置 # 50M = 50 MB/s # 100M = 100 MB/s
经验:
| 场景 | 建议 |
|---|---|
| 业务高峰 | 50~100 MB/s |
| 业务低峰 | 不限速 |
七、版本升级(Feature Flags)
OpenZFS 不断加新特性,但新 pool 默认关闭这些特性。要启用:
# 启用新特性 $ zpool upgrade tank # 启用所有新特性 $ zpool upgrade -a # 看当前版本 $ zpool get version tank
警告:升级
feature flags之后,旧版 ZFS 不能读这个 pool。确保所有机器的 ZFS 版本足够新。
八、命名规范
为了让运维更轻松,盘命名推荐用/dev/disk/by-id/:
# 看盘的稳定 ID $ ls /dev/disk/by-id/ ata-WDC_WD80EFZZ-68BTXN0_VCC5Y6XL ata-WDC_WD80EFZZ-68BTXN0_VCC5Y6YM ... # 用 ID 创建 pool(避免设备名变化) $ zpool create tank raidz2 \ /dev/disk/by-id/ata-WDC_WD80EFZZ-68BTXN0_VCC5Y6XL \ /dev/disk/by-id/ata-WDC_WD80EFZZ-68BTXN0_VCC5Y6YM \ /dev/disk/by-id/ata-WDC_WD80EFZZ-68BTXN0_VCC5Y6ZN \ /dev/disk/by-id/ata-WDC_WD80EFZZ-68BTXN0_VCC5Y6ZO
这样/dev/sdb → /dev/sdc不会影响 pool。
九、本篇小结
| 任务 | 命令 |
|---|---|
| 启动 scrub | zpool scrub tank |
| 看 scrub 进度 | zpool status |
| 加 vdev | zpool add tank raidz2 /dev/sdX /dev/sdY … |
| 加 L2ARC | zpool add tank cache /dev/nvme0n1 |
| 加 SLOG | zpool add tank log /dev/nvme0n1 |
| 替换盘 | zpool replace tank /dev/old /dev/new |
| 离线盘 | zpool offline tank /dev/sdX |
| 上线盘 | zpool online tank /dev/sdX |
关键提醒:
scrub必做——定期执行,发现并修复silent corruption;- 用
/dev/disk/by-id/——设备名稳定; - 新加的
vdev一定要冗余——不能加单盘; - 扩容会触发数据迁移——低峰期做;
resilver速度要限速——避免业务抖动。
总的来说,ZFS 存储的稳定运行,不靠侥幸,全靠规范运维。定期 scrub 巡检可以提前发现静默数据损坏,是保障数据安全的核心;扩容切忌随意加盘,优先冗余 vdev、遵守扩容规则,才能兼顾容量和安全性;硬盘故障及时处理,规范换盘、合理限速,能最大程度避免业务波动。同时坚持用磁盘唯一 ID 管理设备、按需升级特性、错开业务高峰期操作,就能规避绝大多数 ZFS 运维故障。掌握这套标准化流程,足以搞定 99%的 ZFS 日常维护场景,让存储系统长期稳定运行。
以上关于Linux zfs运维篇:scrub、扩容、换盘的文章就介绍到这了,更多相关内容请搜索码云笔记以前的文章或继续浏览下面的相关文章,希望大家以后多多支持码云笔记。
如若内容造成侵权/违法违规/事实不符,请将相关资料发送至 admin@mybj123.com 进行投诉反馈,一经查实,立即处理!
重要:如软件存在付费、会员、充值等,均属软件开发者或所属公司行为,与本站无关,网友需自行判断
码云笔记 » Linux zfs运维篇:scrub、扩容、换盘
微信
支付宝