字数 1212,阅读大约需 7 分钟
Btrfs 在文件系统层实现 RAID(无需 mdadm)。本篇讲清 raid0/1/5/6/10 的选择、配置、scrub、和 write hole 的问题。
一、Btrfs RAID 概览
Btrfs 的 RAID 比传统硬件 RAID 和 mdadm 灵活:
| | | | |
|---|
single | | | | |
DUP | | | | |
raid0 | | | | |
raid1 | | | | |
raid5 | | | | |
raid6 | | | | |
raid10 | | | | |
重要警告:Btrfs RAID5/6 历史上多次出现 write hole bug。Linux 5.5 起部分修复,但生产仍建议 RAID10。
二、创建 RAID
2.1 RAID0(条带化,无冗余)
$ mkfs.btrfs -d raid0 -m raid1 /dev/sdb /dev/sdc
# ^^^^^^^^^ data 用 raid0
# ^^^^^^^ metadata 用 raid1
2.2 RAID1(镜像)
# 2 块盘 RAID1
$ mkfs.btrfs -d raid1 -m raid1 /dev/sdb /dev/sdc
# 3 块盘 RAID1(3 份镜像)
$ mkfs.btrfs -d raid1 -m raid1 /dev/sdb /dev/sdc /dev/sdd
- • 性能:读 ≈ 2×(多源读),写 ≈ 1×(写多份)
2.3 RAID5(推荐 3+ 盘)
$ mkfs.btrfs -d raid5 -m raid1 /dev/sdb /dev/sdc /dev/sdd
- • 性能:读 ≈ (N-1)×,写 ≈ 1×(算校验)
- • 风险:write hole 历史 bug(部分已修)
2.4 RAID6(推荐 4+ 盘)
$ mkfs.btrfs -d raid6 -m raid1 /dev/sdb /dev/sdc /dev/sdd /dev/sde
- • 性能:读 ≈ (N-2)×,写 ≈ 1×(算校验)
2.5 RAID10(条带+镜像)
# 4 块盘:2 个 mirror,再 stripe
$ mkfs.btrfs -d raid10 -m raid10 /dev/sdb /dev/sdc /dev/sdd /dev/sde
三、修改 RAID 级别(balance)
3.1 用 balance 转换
# 把数据从 single 转为 raid1
$ btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
| |
|---|
| -dconvert=raid1 |
| -mconvert=raid1 |
| -sconvert=raid1 |
3.2 实战:单盘转 RAID1
# 1. 加盘
$ btrfs device add /dev/sdc /mnt
# 2. balance 转 RAID1
$ btrfs balance start -dconvert=raid1 -mconvert=raid1 /mnt
# 3. 看进度
$ btrfs balance status /mnt
四、scrub(校验和修复)
# 启动 scrub
$ btrfs scrub start /mnt
# 状态
$ btrfs scrub status /mnt
scrub 在 RAID1/5/6 中自动用副本修复不一致的 extent。
五、Write Hole:核心争议
5.1 什么是 write hole?
传统 RAID5(mdadm):
写数据:① 写数据 ② 写校验
断电时可能 ① 完成 ② 没完成
→ 校验和数据不一致(write hole)
→ 必须 mdadm --assemble --force 修复
→ 数据可能丢
Btrfs RAID5/6:
COW + transaction 模型理论上能避免
但实际实现有过 bug(Linux 5.5 之前的 early hole)
→ 部分场景下数据可能仍丢
5.2 Btrfs RAID5/6 修复时间线
5.3 现状
2024 年现状:Btrfs RAID5/6 仍在改进中,生产关键数据用 RAID10。
六、RAID 选型决策树
你的场景是什么?
│
├── 临时数据 / 高性能
│ └── raid0(必须接受盘坏数据全丢)
│
├── 关键数据 / 性能 + 冗余
│ └── raid10(4 盘起步)
│
├── 大量存储 / 容量利用率高
│ ├── 大盘(>4TB)→ raid6
│ ├── 中盘(1~4TB)→ raid5(5.10+ 内核)
│ └── 商业环境 → raid10(保守)
│
└── 单盘
└── DUP metadata(默认)+ 重要数据定期备份
七、实战配置
案例 1:家用 4 盘 NAS
# 4 块 4TB HDD
# 推荐 raid5(家用性价比高)或 raid6(更安全)
# raid5
$ mkfs.btrfs -d raid5 -m raid1 -L nasdata /dev/sdb /dev/sdc /dev/sdd
# 容量:3 × 4TB = 12TB(损 1 块冗余)
# raid6(更保守)
$ mkfs.btrfs -d raid6 -m raid1 -L nasdata /dev/sdb /dev/sdc /dev/sdd /dev/sde
# 容量:4 × 4TB = 16TB(但盘数要到 4)
案例 2:性能优先(数据库)
# 4 块 SSD
$ mkfs.btrfs -d raid10 -m raid10 -L dbdata /dev/sdb /dev/sdc /dev/sdd /dev/sde
# 容量:2 × 单盘
# 性能:4 块盘的读 + 2 块盘的写
案例 3:混合(SSD cache + HDD)
# HDD 主数据
# SSD 做缓存
# 先建 pool
$ mkfs.btrfs -d raid1 -m raid1 -L tank /dev/sdb /dev/sdc
# 加 SSD 做 cache(btrfs 自身不直接做 cache,但可以放热数据)
# 用 bcache / lvmcache / dm-cache 在更底层
八、RAID 内 spare
Btrfs 暂时不支持 hot spare(与 mdadm 不同)。需要手动替换。
替代方案:
九、本篇小结
重要警告:
- • raid5/6 在 Linux 5.10+ 内核才稳定