1. 单块硬盘靠不住:RAID 到底在赌什么、防什么
很多人第一次接触 RAID,是因为一块盘突然不认了:系统盘还在转,数据目录却挂不上,dmesg里全是 I/O error。那一刻你才意识到,单块硬盘并不是"会不会坏"的问题,而是"什么时候坏"的问题。RAID(Redundant Array of Independent Disks,独立磁盘冗余阵列)就是在这个背景下诞生的工程手段——它把多块物理盘组合成一个逻辑卷,用条带化换吞吐,用镜像或校验换容错。说白了,RAID 不提升单块盘的质量,它提升的是"坏一块盘之后你还能不能继续干活"这件事的概率。
我在实际运维里见过太多把 RAID 当"备份"的误区。先说结论:RAID 不是备份,它只解决硬盘级硬件故障导致的可用性问题,解决不了误删、勒索、机房泡水、整机被盗这些上层灾难。这也是为什么后文会反复强调快照和异地副本——RAID 负责让你在坏盘时不至于业务中断,备份负责让你在逻辑灾难后还能回到昨天。两者职责完全不同,混为一谈是新手最容易踩的第一个认知坑。
理解 RAID 前要先理解三块"积木":**条带(stripe)**把数据切块分散写到多块盘上,目的是并行读写提升带宽;**镜像(mirror)**把同一份数据写到两块盘上,目的是容错;**校验(parity)**用异或运算算出冗余信息,目的是用较小的冗余成本换来容错能力。所有 RAID 级别无非是这三种积木的排列组合。搞懂这一点,后面 RAID 0/1/5/6/10 的差异就都是推论而非死记。
1.1 三种基础积木决定了所有 RAID 级别的性格
条带化最直观的价值是带宽叠加。假设单盘顺序读 150 MB/s,4 块盘做条带,理论顺序读能到 600 MB/s 左右(实测会打折,后文会讲原因)。但它有个副作用:条带越小,随机小 IO 越容易跨盘拆分,反而增加开销;条带越大,单盘内的连续访问越多,顺序性能越好,但并行度下降。这就是为什么数据库场景常把条带设成 64KB~256KB,而大文件归档可以设到 512KB 甚至 1MB。
镜像的逻辑更简单:一份数据写两份,读的时候可以两块盘交替读来提升读带宽,写的时候必须两份都写成功才算成功。它的代价是容量利用率只有 50%(两盘镜像),换来的是"坏一块盘数据零丢失、重建只需拷一份"的最强容错。
校验则是走"用计算换空间"的路线。以 RAID 5 为例,N 块盘里有一块盘的容量用于存校验,实际可用是 (N-1) 块。写数据时要先读旧数据、读旧校验、算出新校验、再写新数据和新校验,这就是著名的写惩罚(write penalty)。读的时候如果某块盘坏了,可以用剩下的数据块加校验块异或还原出来。校验的代价是写性能下降和重建期间的风险,后文会重点讲。
个人经验:判断一个 RAID 方案合不合适,先问三件事——你要的是容量、读带宽、写带宽还是容错?能接受坏几块盘?重建窗口有多长?这三个问题答不上来,选 RAID 级别就是拍脑袋。
1.2 RAID 的"硬盘级容错"边界在哪
RAID 能防的:单块或多块(取决于级别)物理盘故障、部分坏道导致的读错误(在校验可修复范围内)、盘突然掉线。RAID 防不了的:控制器故障(除非双控)、整机断电导致缓存数据丢失(除非带电池/超级电容)、文件系统损坏、误删、病毒加密、机房级灾害。
这里有个容易被忽略的点:RAID 卡的缓存策略。开启 Write-Back 且带电池保护时,写入先落缓存再落盘,性能好且断电不丢;但如果电池老化失效,很多卡会自动降级为 Write-Through,性能骤降。我遇到过一台老服务器突然写入慢到离谱,排查半天发现是阵列卡电池到期,卡自己把写策略切了。这种"没报错但性能崩了"的情况,比直接坏盘更难查。
2. RAID 0/1/5/6/10 逐个拆:容量、性能与容错的三角权衡
选 RAID 级别本质是在容量利用率、读写性能、容错能力这三个角上做取舍,没有全能选手。下面逐个拆,重点讲每个级别的"隐性成本",这些是文档里通常不写、但实际会咬人的地方。
2.1 RAID 0 与 RAID 1:两个极端
RAID 0是纯条带,无任何冗余。N 块盘容量全用上,读写带宽接近线性叠加。代价是:坏任意一块盘,整个阵列数据全丢。它的适用场景其实很窄——临时缓存、渲染中间产物、可随时重算的数据。我见过有人把数据库放在 RAID 0 上追求性能,结果一块盘坏掉整个库没了,这种教训一次就够记一辈子。
RAID 1是纯镜像,两盘互为副本。容量利用率 50%,读带宽可叠加(两块盘并行读),写带宽基本等于单盘(要写两份)。它的容错最干脆:坏一块盘照常跑,重建只需从另一块盘拷一份,重建窗口短、风险低。系统盘、小容量高价值数据、对重建风险敏感的场景,RAID 1 往往比 RAID 5 更稳。
两者的共同点是"简单":没有校验计算,没有写惩罚的复杂放大。RAID 10 就是在这两个简单积木上叠加出来的。
2.2 RAID 5 的写惩罚与重建窗口:最容易被低估的两个坑
RAID 5 是"性价比之选"的代名词:(N-1)/N 的容量利用率,读性能不错,能容忍一块盘故障。但它有两个致命隐性成本。
第一是写惩罚。一次小随机写,RAID 5 实际要做:读旧数据、读旧校验、算新校验、写新数据、写新校验——放大成 4 次 IO。这意味着随机写密集的场景(比如 OLTP 数据库),RAID 5 的写性能可能只有单盘的几分之一。很多人在测试环境用顺序写测出漂亮数字,上线后随机写直接跪,就是这个原因。缓解手段是阵列卡带大缓存 + 电池保护,把多次小写合并成大条带写,但这依赖缓存策略正确配置。
第二是重建窗口。RAID 5 坏一块盘后进入降级模式,此时如果再坏一块,数据全丢。重建一块大盘要多久?以 8TB 盘、重建速度 100 MB/s 估算,约 22 小时;实际受阵列卡、盘的健康度、业务 IO 抢占影响,往往更久。而重建期间阵列处于无冗余状态,任何一块盘出问题就是灾难。更麻烦的是重建时的 URE(不可恢复读错误):消费级盘 URE 率约 10^14,意味着读 12.5TB 左右可能遇到一个读不出的扇区;企业级盘约 10^15,好一个数量级。大容量盘 + RAID 5 的组合,重建时撞上 URE 导致重建失败的概率并不低,这是业界讨论多年的老问题,结论是:大容量盘(单盘 8TB 以上)慎用 RAID 5,优先 RAID 6 或 RAID 10。
2.3 RAID 6 与 RAID 10:用更多冗余换更稳的重建
RAID 6用两块盘的容量存双校验,可用容量 (N-2)/N,能同时容忍两块盘故障。它的写惩罚更高(一次小写放大成 6 次 IO),写性能比 RAID 5 更差,但换来了"重建期间再坏一块也不丢数据"的底气。大容量盘、冷数据、归档存储,RAID 6 是更稳妥的选择。
RAID 10是先镜像再条带,容量利用率 50%,能容忍"每组镜像各坏一块"(具体能坏几块取决于布局,最坏情况是每组坏一块仍可用)。它的读写性能都好,重建只需拷一份、窗口短,是数据库这类随机写密集 + 高可用要求场景的常见选择。代价是容量成本高——50% 的利用率意味着你为容错付了双倍硬盘钱。
2.4 一张表把容量和容错算清楚
假设有 N 块同容量 C 的盘,下表是各级别的可用容量与容错能力(重建期间可再坏盘数按最坏情况保守估计):
| 级别 | 可用容量 | 最少盘数 | 容错(正常运行) | 容错(重建期间) | 典型场景 |
|---|---|---|---|---|---|
| RAID 0 | N × C | 2 | 0 块 | 0 块 | 临时缓存、可重算数据 |
| RAID 1 | C | 2 | 1 块 | 0 块 | 系统盘、小容量高价值数据 |
| RAID 5 | (N-1) × C | 3 | 1 块 | 0 块 | 读多写少、中等容量 |
| RAID 6 | (N-2) × C | 4 | 2 块 | 1 块 | 大容量盘、归档、冷数据 |
| RAID 10 | N × C / 2 | 4 | 每组 1 块 | 视布局而定 | 数据库、高 IOPS 场景 |
容量计算还有个常被忽略的细节:盘的实际可用容量不等于标称容量。厂商标称 8TB 用的是十进制(8×10^12 字节),操作系统按二进制显示约 7.27 TiB;再加上文件系统元数据开销(ext4 默认约 1%~2%,XFS 类似),实际可用还要再打折。做容量规划时按标称的 90% 估算比较稳妥。
3. 软 RAID 还是硬 RAID:选型时真正该看的变量
"用阵列卡还是用操作系统软 RAID"是绕不开的选型题。网上常见答案是"生产用硬 RAID,测试用软 RAID",这个说法对但不完整。真正该看的是四个变量:性能要求、缓存与断电保护、跨平台需求、运维复杂度。
3.1 硬件阵列卡的价值与它的隐性依赖
硬件 RAID 的核心优势是带缓存的独立处理器。阵列卡上有 DRAM 缓存和电池/超级电容,写操作先落缓存并立即向主机返回成功,再由卡后台刷盘。这带来两个好处:一是写延迟大幅降低,二是可以把多个小写合并成整条带写,显著缓解 RAID 5/6 的写惩罚。没有缓存保护的 RAID 5,随机写性能会难看到让你怀疑人生。
但硬件 RAID 有个隐性依赖:电池/超级电容的状态。电池老化后,卡会自动把 Write-Back 降级为 Write-Through,性能断崖式下跌却不报硬故障。我建议把阵列卡的管理工具接进监控,定期读电池健康度和写策略状态,别等业务方投诉慢才去查。另外,阵列卡故障时,盘上的数据往往依赖同型号卡才能读取,备一块同型号卡是低成本高回报的保险。
硬件 RAID 还有个坑:缓存数据丢失。如果卡没电保护又开了 Write-Back,突然断电会导致缓存里未落盘的数据丢失,严重时阵列元数据损坏。所以"开 Write-Back 必须有电池/超级电容"是铁律,不是建议。
3.2 Linux 软 RAID(mdadm)适合谁
软件 RAID 由操作系统用 CPU 做校验计算和条带管理,优点是:不依赖特定硬件、盘可以直接挂到任意机器上读、成本低、配置透明可脚本化。缺点是吃 CPU(现代 CPU 做异或很快,通常不是瓶颈)、没有独立缓存(写惩罚缓解有限)、部分场景下重建速度受系统调度影响。
mdadm 软 RAID 特别适合这几类场景:单机文件服务器、备份存储、开发测试环境、以及"我就是要能随时把盘拔下来插到另一台机器上读"的可移植性需求。它的元数据写在盘上,换机器、换系统版本通常都能识别,这一点比硬件 RAID 的"锁卡"友好得多。
一个实操细节:软 RAID 的chunk size(对应硬件 RAID 的条带大小)默认 512KB,对大多数场景够用;数据库类可以调到 64KB~128KB 提升小 IO 并行度,大文件顺序写可以调到 1MB。改 chunk 只能在创建时指定,建好之后没法改,所以创建前想清楚用途。
3.3 一张决策表帮你快速定型
| 维度 | 硬件 RAID | 软件 RAID(mdadm) |
|---|---|---|
| 写性能(随机) | 强(有缓存合并) | 一般(无独立缓存) |
| CPU 开销 | 低 | 中(异或计算) |
| 断电保护 | 依赖电池/超级电容 | 无缓存,反而简单 |
| 可移植性 | 差(常锁卡) | 好(元数据在盘上) |
| 成本 | 高(卡+电池) | 低 |
| 运维透明度 | 依赖厂商工具 | 命令透明、可脚本化 |
| 适合场景 | 生产数据库、高 IOPS | 文件服务、备份、测试 |
我的实际选择习惯是:核心数据库上硬 RAID + 电池保护 + 备卡;文件服务、备份、测试环境用 mdadm 软 RAID。这个分法在多数中小规模场景里比较省心,也不是什么金科玉律,关键是把上表的变量对着自己的需求过一遍。
4. 用 mdadm 从零搭一套 RAID 5 并做故障演练
光讲原理不够,下面走一遍完整实操。用 4 块盘搭 RAID 5,留一块做热备,然后模拟坏盘、替换、重建,把整个链路跑通。这套流程在测试环境练熟,真出事时才不会手忙脚乱。
4.1 环境准备与磁盘识别
先确认盘符。最容易出事的环节就是盘符认错,把系统盘加进阵列直接毁数据。我的习惯是先看lsblk的树状结构和容量,再用smartctl确认型号,双保险。
# 查看块设备树,确认哪些盘是空的、没挂载 lsblk -o NAME,SIZE,TYPE,MOUNTPOINT # 逐块确认型号和序列号,避免认错盘 for d in /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf; do echo "== $d ==" smartctl -i "$d" | grep -E "Device Model|Serial Number" done确认无误后,把要用的盘的分区表清干净(如果盘上有旧分区表或旧 RAID 元数据,会导致创建失败):
# 清除旧 RAID 元数据,注意确认盘符! for d in /dev/sdb /dev/sdc /dev/sdd /dev/sde /dev/sdf; do mdadm --zero-superblock "$d" 2>/dev/null wipefs -a "$d" done提示:
wipefs -a和mdadm --zero-superblock都是破坏性操作,执行前务必用lsblk确认目标盘没有被挂载、不是系统盘。在脚本里跑这组命令时,建议加一个"盘符白名单"校验,防止手滑。
4.2 创建 RAID 5 阵列与文件系统
用 4 块盘(sdb/sdc/sdd/sde)建 RAID 5,sdf 先不加,留作热备:
# 创建 RAID 5,chunk 用 256KB(文件服务折中值) mdadm --create /dev/md0 \ --level=5 \ --raid-devices=4 \ --chunk=256 \ /dev/sdb /dev/sdc /dev/sdd /dev/sde # 查看构建进度(初次同步会跑一阵) cat /proc/mdstat/proc/mdstat里会显示[>....................] resync = x.x%,4 块盘、几 TB 的数据,初次同步可能要几十分钟到几小时,期间可以正常使用但性能打折。同步完成后,创建文件系统并挂载:
# 建 ext4,保留 1% 给 root 应急(默认 5%,可按需调整) mkfs.ext4 -m 1 -L data /dev/md0 mkdir -p /data mount /dev/md0 /data接着写入/etc/mdadm/mdadm.conf(或/etc/mdadm.conf,视发行版而定),让系统开机自动组装阵列。用mdadm --detail --scan生成配置行追加进去:
mdadm --detail --scan >> /etc/mdadm/mdadm.conf # Debian/Ubuntu 系还需要更新 initramfs,否则重启可能不自动组装 update-initramfs -u最后把挂载写进/etc/fstab,建议用 UUID 或 LABEL 而不是 /dev/md0,防止设备名变化导致挂不上:
blkid /dev/md0 # 拿到 UUID # 在 /etc/fstab 中追加: # UUID=xxxx-xxxx /data ext4 defaults,nofail 0 2nofail这个选项值得加:某块盘没就绪时,不至于让系统卡在启动阶段进不去。
4.3 模拟一块盘故障,走完替换与重建全流程
演练的目的是把命令肌肉记忆化。先标记 sdb 故障并移除:
# 标记故障(模拟坏盘) mdadm --manage /dev/md0 --fail /dev/sdb # 从阵列中移除 mdadm --manage /dev/md0 --remove /dev/sdb # 把热备盘 sdf 加进去,自动开始重建 mdadm --manage /dev/md0 --add /dev/sdf # 观察重建进度 watch -n 5 cat /proc/mdstat重建期间重点看两个指标:重建速度和预计剩余时间。如果重建速度异常慢(比如低于 30 MB/s),常见原因是业务 IO 抢占太狠,可以临时调高重建速率上限:
# 查看当前重建速度限制(单位 KB/s) cat /proc/sys/dev/raid/speed_limit_max cat /proc/sys/dev/raid/speed_limit_min # 临时调高上限,加快重建(生产环境慎用,会抢业务 IO) echo 200000 > /proc/sys/dev/raid/speed_limit_max重建完成后,把坏盘 sdb 换掉,清元数据后作为新的热备盘加回去:
mdadm --zero-superblock /dev/sdb mdadm --manage /dev/md0 --add /dev/sdb这套流程走一遍,你对"故障—降级—替换—重建"的时序就有体感了。真出事时,最大的风险往往不是不会敲命令,而是慌乱中拔错盘——后文会专门讲这个坑。
5. 重建期间才是真考场:几个亲历过的坑与排查链路
RAID 配好只是开始,真正考验人的是故障处理和重建阶段。下面几个坑我都真实遇到过或见别人踩过,按"现象—排查—根因—处置"的顺序讲,方便你复现排查思路。
5.1 重建跑到一半失败:URE 与坏道叠加
现象:RAID 5 坏一块盘后开始重建,进度到 60%~80% 时卡住,/proc/mdstat不再前进,dmesg出现md/raid:md0: read error或UNC字样。
排查链路:先看dmesg -T | grep -iE "error|unc|medium"定位是哪块盘、哪个扇区读失败;再用smartctl -a看剩余盘的 Reallocated_Sector_Ct、Pending_Sector_Ct 是否在涨。根因通常是剩余盘里有坏道或 URE,重建时读到读不出的扇区,校验也无法恢复(因为坏的是数据盘且校验盘也读不出对应位置)。
处置:这种情况没有银弹。可行的做法是先把能读的数据尽量备份出来(用ddrescue对可读部分做镜像),再评估是否放弃重建、从备份恢复。预防手段才是重点:定期做 RAID 巡检(scrub/check),提前发现坏道;大容量盘避免 RAID 5,改 RAID 6 或 RAID 10;剩余盘选企业级(URE 更低)。
定期巡检的命令:
# 触发一次 RAID 一致性检查(会读全盘,慢,建议低峰期跑) echo check > /sys/block/md0/md/sync_action # 查看进度 cat /proc/mdstat建议每月跑一次 check,把坏道问题在"还没坏盘"的时候就暴露出来。
5.2 拔错盘:热插拔时代的经典事故
现象:以为坏的是 sdc,拔出来发现是 sdd;或者服务器盘位编号和系统盘符对不上,拔了正在用的好盘,阵列直接崩。
根因:盘位物理编号和 Linux 盘符没有稳定映射。重启、换卡、加盘都可能让 sdb 变成 sdc。纯粹靠lsblk认盘,在多盘机器上非常危险。
处置与预防:给每块盘做物理位置标签,用smartctl读序列号,在盘架上贴对应的序列号后四位;操作前用mdadm --detail /dev/md0看阵列里每块盘的槽位(/dev/sdX对应的Faulty状态)。更稳的做法是用/dev/disk/by-id/下的持久化路径来建阵列和操作,避免盘符漂移。比如:
ls -l /dev/disk/by-id/ | grep -E "ata|wwn" # 建阵列时用 by-id 路径 mdadm --create /dev/md0 --level=5 --raid-devices=4 \ /dev/disk/by-id/ata-XXXX1 /dev/disk/by-id/ata-XXXX2 \ /dev/disk/by-id/ata-XXXX3 /dev/disk/by-id/ata-XXXX4这样即使盘符变了,by-id 路径也不变,大幅降低拔错盘的概率。
5.3 监控缺位:坏盘一周没人知道
现象:某天业务突然全挂,登录一看 RAID 5 早就坏了两块盘,第一块坏了没人发现,第二块坏的时候直接全丢。
根因:没有对 RAID 状态做主动监控。/proc/mdstat不会主动告警,阵列降级时系统该跑还跑,直到第二块盘坏掉才暴露。这是最隐蔽也最致命的一类问题。
处置:把 RAID 状态接进监控系统,最简方案是用mdadm --monitor配合邮件/告警脚本:
# 以守护进程方式监控,事件触发时执行指定脚本 mdadm --monitor --scan --daemonise \ --program /usr/local/bin/raid-alert.sh \ --delay 300raid-alert.sh里根据事件类型(Fail、DegradedArray、RebuildStarted、RebuildFinished)发不同级别的告警。DegradedArray 必须当天处理,不能拖。
另外,文件系统层面也可以加监控:/proc/mdstat的[U_]这种标记表示有一块盘不在线,定期抓取解析即可。我习惯写一个轻量脚本,每分钟读一次mdstat,出现_或F就告警,实现成本极低但能救大命。
5.4 扩容的坑:在线扩容不是想扩就扩
mdadm 支持在线扩容,但流程有严格的顺序,顺序错了会丢数据。典型扩容(RAID 5 加一块盘,4 盘扩到 5 盘):
# 1. 确认阵列当前状态健康、已同步 cat /proc/mdstat # 2. 加入新盘 mdadm --manage /dev/md0 --add /dev/sdg # 3. 扩容阵列设备数(4→5) mdadm --grow /dev/md0 --raid-devices=5 # 4. 等 reshape 完成(watch cat /proc/mdstat) # 5. reshape 完成后,扩容文件系统(ext4 示例) resize2fs /dev/md0关键点:第 3 步的 grow 和第 5 步的文件系统扩容之间必须等 reshape 完成,中间不能跳过;另外--backup-file在部分版本里对大阵列是必须的,否则 grow 可能失败或损坏数据。我建议扩容前先做完整备份,在线扩容虽然支持,但中途断电、盘故障都可能让阵列进入不可恢复状态。
6. 选型落地:把需求翻译成 RAID 配置的几步
讲完原理和坑,最后回到"我到底该怎么选"这个最实际的问题。我的做法是把需求拆成四个问题,逐个回答,答案组合起来基本就锁定了配置。
第一个问题:数据丢了能不能重算/重下?能,就 RAID 0 或 RAID 5(看容量);不能,就 RAID 1/6/10。第二个问题:写是随机多还是顺序多?随机写密集(数据库、虚拟化)优先 RAID 10,RAID 5/6 的写惩罚会很痛;顺序写为主(文件、备份、视频归档)RAID 5/6 可以接受。第三个问题:单盘容量多大?单盘 8TB 以上且用 RAID 5,重建窗口长、URE 风险高,建议 RAID 6;2TB 以下 RAID 5 压力小很多。第四个问题:能接受多长的降级运行时间?业务对降级敏感、要求快速恢复的,RAID 10 重建快是巨大优势。
把答案填进下面这张速查表:
| 你的主要诉求 | 推荐级别 | 理由 |
|---|---|---|
| 极致读带宽、数据可重算 | RAID 0 | 无冗余开销,带宽叠加 |
| 系统盘、小容量高价值 | RAID 1 | 容错干脆,重建简单 |
| 读多写少、中等容量、单盘 ≤4TB | RAID 5 | 容量利用率与容错平衡 |
| 大容量盘、归档、冷数据 | RAID 6 | 重建期间可再坏一块 |
| 数据库、虚拟化、随机写密集 | RAID 10 | 写性能好,重建窗口短 |
| 既要容量又要一定容错、预算有限 | RAID 5 + 热备 | 热备缩短降级窗口 |
最后一个常被忽略的配置细节:热备盘(spare)要不要配。热备盘的价值是"盘一坏自动顶上开始重建",把降级窗口从"等人来换盘"压缩到"立刻重建"。代价是占用一块盘的容量。我的建议是 RAID 5/6 尽量配一块热备,尤其是无人值守的机房——人可能几小时后才到现场,热备能把这几个小时省掉,而 RAID 5 降级期间多坏一块就是全丢。
容量规划还要留余量。经验值是实际使用不超过阵列可用容量的 80%,原因有两个:一是文件系统在接近满时会碎片化严重、性能下降;二是留出空间给快照、临时文件、重建时的元数据操作。一个塞满 95% 的阵列,做 snapper 快照或者 resize 时很容易出问题。
关于条带大小(chunk size)的最后一句提醒:大多数场景 256KB 是安全牌,不需要过度优化。除非你有明确的基准测试数据支撑,否则不必为了"可能提升 5%"去折腾 64KB 或 1MB——改 chunk 要重建阵列,成本远大于收益。我自己的习惯是文件服务 256KB、数据库所在阵列 128KB、纯归档 512KB,这个组合在多数机器上跑下来比较稳,也谈不上最优,够用而已。
真正把 RAID 用好的关键,从来不是记住哪个级别"最好",而是清楚每个级别的失效模型:它防什么、不防什么、重建时最坏会发生什么。把这三个问题想透,再配上巡检、监控、热备和备份这四件套,硬盘故障对你来说就只是一个操作流程,而不是一场事故。