系统里挂着十二个 LUN,像十二块盘;核对串号后,它们只有六个真身。本文记录一次真实的 RAID 选型:从「数 LUN」到「数物理盘」的故障域重算,以及最终放弃 RAID6、改选 RAID10 的原因。
一、反直觉的发现:12 个盘不是 12 块物理盘
对存储节点来说,lsblk 的输出是最直观的盘清单。这台节点上,清单整齐:12 个 6.4T SAS LUN,型号均为 ST14000NM0001。若按 LUN 计数,这是一组 12 成员宽 RAID6,容量与冗余参数可观。
核对串号时,12 个 LUN 的序列号并非 12 个不同值,而是两两相同。按串号归组后,真实拓扑如下:
| 物理盘 | 系统里的两个 LUN |
|---|---|
| D1 | sda + sdf |
| D2 | sdb + sdd |
| D3 | sdc + sde |
| D4 | sdg + sdh |
| D5 | sdi + sdj |
| D6 | sdk + sdl |
这台机器没有 12 块物理盘,只有 6 块物理盘 × 2 LUN——双头/双致动器盘。每个 LUN 在操作系统内独立呈现,可单独组阵列、单独发 IO;同一个物理盘上的两个 LUN 生命周期绑定,故障时同时掉线。
这一事实改写后续 RAID 选型的前提:所有按「每盘」「每成员」的计算,都需先换算回物理盘。双头/双致动器允许两个 LUN 并行发 IO,读写并发是优势;该优势属拓扑红利,必须依靠正确配对兑现,配对错误即转化为故障域陷阱。
二、故障域重算:12-LUN RAID6 只扛得住一块物理盘
RAID6 的设计目标是「任意 2 个成员故障不丢数据」。12 个 LUN 组成 RAID6,成员数为 12,容错上限为任意 2 个成员同时故障。
故障域应按物理盘数计算,不按 LUN 数。RAID6 只有两条校验(P 与 Q),容错上限为「同时损坏 2 个成员」。一块物理盘故障时,其名下 2 个 LUN 同时掉线,两个成员在同一时刻消失。对 RAID6 而言,同时掉 2 个成员等于双校验耗尽,无第三条校验兜底。
12-LUN RAID6 的真实容错为:只承受 1 块物理盘故障。损坏 2 块物理盘即掉 4 个 LUN,阵列不可恢复;剩余 8 个 LUN 即使正常,数据也无法找回。
该结论由该盘拓扑直接得出:一块物理盘会带掉几个成员,故障域就是几。
三、三方案对比
三个候选方案的对比如下:
| 方案 | 可用容量 | 随机写 | 重建 | 真实容错 |
|---|---|---|---|---|
| RAID6(12 LUN) | 64T | 10-17MB/s(RMW) | 18-36h | 只承受 1 块物理盘故障;坏 2 块物理盘不可恢复 |
| RAID10(12 LUN,6 镜像对条带) | 约 38.2 TiB | 无 RMW | 纯拷贝,快 | 强;前提是镜像对必须跨物理盘 |
| RAID60(2×6 盘 RAID6) | 约 47T | 约 RAID6 的 1.5-2 倍 | 仍 RMW | LUN 跨组放置后,可承受 2 块物理盘故障 |
RAID6 容量最大,随机写为 10-17MB/s 的 RMW 水平,重建需 18-36h,真实容错仅 1 块物理盘。多租户环境下大量小随机写,RMW 写惩罚直接体现在延迟与吞吐上。
RAID10 无 RMW 惩罚,随机写路径干净;重建为纯拷贝,速度快。其隐含风险是镜像对必须显式跨物理盘。按默认相邻配对,sdg+sdh、sdi+sdj、sdk+sdl 三对来自同一块物理盘,坏一块物理盘即带走整条镜像的两条腿,等于没有冗余。RAID10 的安全性由配对方式决定,配对错误时风险高于 RAID6。镜像对显式跨物理盘后,坏任意一块物理盘只带走每条镜像的一条腿,阵列在另一条腿上继续运行。
RAID60 的可用容量与随机写居中,仍为 RMW;将同一物理盘的两个 LUN 分入不同 RAID6 组后,可承受 2 块物理盘故障。其代价为两层 RAID6 叠加,管理复杂度更高。
四、容量约束:先算承诺,再选型
选型不能只看百分比,还要看已经对客户承诺了多少容量。
该节点的业务数字:已分配 32.2TB 磁盘给客户(419 块盘),实际写入 4.1T;全面板 1297 块盘 / 59.3TB。关键数字是「已分配 32.2T」:客户侧配额按已分配计算,容量规划需兜住 32.2T 承诺值,而非当前 4.1T 用量。
用「可用容量兜住已分配的 32.2T」来算余量:
- RAID6(64T):余量 2 倍,最宽裕;
- RAID60(约 47T):余量约 46%;
- RAID10(约 38.2 TiB):余量只剩约 12%。
容量账面上 RAID6 最优,随机写与真实容错均不达标;RAID10 容量最紧,仍能兜住已分配量。容量可兜底后,问题归结为随机写与可靠性是否值得让出余量。在该节点上,答案明确:容量余量可以压缩,承诺必须兑现,可靠性是兑现承诺的前提。
五、决策:先试 journal,再认命
实施前先尝试保住 RAID6 的容量,未直接切换到 RAID10。
第一步为 RAID6 + 256G NVMe md journal,write-back 模式,目标是用 NVMe 先吸收随机写,再异步落到 HDD。实测结果:持续入写大于 HDD 落盘速度时,写性能仍回到 HDD 原水平。journal 只提供缓冲,不改变 HDD 侧 RMW 的物理能力;入写持续大于落盘,脏数据持续累积,延迟回升。该实验表明瓶颈位于 HDD 侧,不在缓冲侧。
第二步分层方案(热数据留 SSD)依赖一台借来的 SSD 机器,方案被否决;生产数据不能押在借来的硬件上。
三选一的结论为:RAID6 真实容错仅 1 块物理盘、随机写最差;RAID60 为折中;RAID10 以容量换可靠性与无 RMW。选择 RAID10,接受容量减半,换取真实冗余与干净的随机写路径。
六、实施细节
RAID10 的成败全在配对。我们按物理盘串号,将 12 个 LUN 排成 n2 布局下相邻两两成对、每对均跨物理盘的顺序:
sda sdb sdc sdg sdi sdk sdf sdd sde sdh sdj sdl相邻两两成对后是:(sda, sdb)、(sdc, sdg)、(sdi, sdk)、(sdf, sdd)、(sde, sdh)、(sdj, sdl)。逐一核对,每对的两个成员都来自不同物理盘。
创建命令:
mdadm --create /dev/md0 --level=10 --layout=n2 --raid-devices=12 --chunk=512K --bitmap=internal \
/dev/sda /dev/sdb /dev/sdc /dev/sdg /dev/sdi /dev/sdk \
/dev/sdf /dev/sdd /dev/sde /dev/sdh /dev/sdj /dev/sdl两条红线:
- 绝不
--assume-clean。历史事故中,--assume-clean创建的阵列 parity 从未计算,呈现为 RAID6,实际为伪 RAID0,坏盘重建得到垃圾数据。 - 初始同步默认被
/proc/sys/dev/raid/speed_limit_max=200000压到 200MB/s,ETA 55h;调高限速:
echo 800000 > /proc/sys/dev/raid/speed_limit_max之后同步跑到 543MB/s,ETA 缩短到 21h。
本次选型的难点不在命令执行,而在先纠正「12 个盘」的计数惯性。数对物理盘后,故障域、配对与容量账才成立。
复盘要点
- 数盘要数物理盘,不数 LUN;故障域按「一块物理盘故障会带掉几个成员」计算。
- RAID 选型先算容量承诺(已分配多少),再算性能。
- 双致动器盘的读写并发是优势,RAID 配对必须显式跨物理盘。
- journal 和缓存只能平滑波动,改变不了 HDD 侧 RMW 的落盘能力。
- 容量占优的方案,若真实容错只有一块物理盘,不值得采用。