为什么要在 VPS 上做软 RAID
很多站长以为 RAID 是机房高端硬件才有的东西,其实 Linux 内核自带 md(Multiple Device)驱动,用 mdadm 工具就能把多块云硬盘组成软阵列。对于数据量大、又不想依赖商家快照的 VPS,软 RAID 是性价比最高的冗余方案:两块盘做 RAID1,坏一块不影响服务;三块盘做 RAID5,容量只损失一块盘。软阵列不依赖特定硬件,换机器后只要把盘挂回去用 mdadm 重新组装即可。
本文全程基于 Ubuntu 22.04 / Debian 12 演示,CentOS/RHEL 系命令几乎一致,仅有安装和 initramfs 更新命令不同,文中会单独标注。
RAID 级别怎么选:0 / 1 / 5 / 10
先明确各级别的容量与冗余特性,再动手,避免建错阵列浪费磁盘:
级别 最少盘数 可用容量 冗余能力 典型用途 RAID0 2 N 块之和 无,坏一块全丢 纯性能需求,不建议存数据 RAID1 2 总容量的一半 镜像,坏一块可读 系统盘、数据库数据目录 RAID5 3 (N-1) 块之和 允许坏一块 性价比最高的容量+冗余 RAID10 4 总容量的一半 允许每组坏一块 性能与冗余兼顾,盘多时首选
VPS 上的通用建议:
数据盘数量=2 -> RAID1 数据盘数量=3 -> RAID5 数据盘数量=4+ -> RAID10 或 RAID5 加一块热备盘
需要说明的是,云服务商的"数据盘"通常是虚拟磁盘,单盘 IOPS 有限,RAID 主要解决的是可用性而非性能叠加,写入性能甚至略降,这是正常现象。
环境准备:安装 mdadm 与磁盘规划
先安装工具,Debian/Ubuntu 与 CentOS 命令如下:
# Debian / Ubuntu apt update && apt install -y mdadm # CentOS / Rocky / AlmaLinux dnf install -y mdadm
然后用 lsblk 看清盘符,确认要组阵列的磁盘上没有数据(组阵列会抹掉盘上内容):
lsblk fdisk -l | grep -E '^Disk /dev' # 示例输出 # NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT # sda 8:0 0 40G 0 disk # sdb 8:16 0 20G 0 disk # sdc 8:32 0 20G 0 disk
如果磁盘是二手盘或曾经加入过其他阵列,先清掉残留的 superblock 与分区表,否则 mdadm 会报错拒绝创建:
mdadm --zero-superblock /dev/sdb /dev/sdc wipefs -a /dev/sdb /dev/sdc
创建 RAID1 镜像阵列
以两块 20G 盘 sdb、sdc 组建 RAID1,元数据版本用 1.2(内核可自动识别):
mdadm --create /dev/md0 --level=1 --raid-devices=2 --metadata=1.2 /dev/sdb /dev/sdc
创建完成后立即查看状态,resync 正在后台同步,此时阵列可用但未完成镜像:
cat /proc/mdstat # Personalities : [raid1] # md0 : active raid1 sdc[1] sdb[0] # 20948992 blocks super 1.2 [2/2] [UU] # [=>...................] resync = 7.3% (1540608/20948992) finish=2.1min speed=163000K/sec
[UU] 表示两块盘都正常,resync 完成后即可建文件系统挂载:
mkfs.ext4 /dev/md0 mkdir -p /data mount /dev/md0 /data df -h /data
查看阵列详细信息,后面排错经常用到:
mdadm --detail /dev/md0
创建 RAID5 与 RAID10 阵列
三块盘建 RAID5,-c 指定 chunk 大小(典型值 128K,适合大文件与数据库):
mdadm --create /dev/md1 --level=5 --raid-devices=3 --chunk=128 --metadata=1.2 /dev/sdd /dev/sde /dev/sdf
四块盘建 RAID10,外镜像内条带,兼顾性能与容错:
mdadm --create /dev/md2 --level=10 --raid-devices=4 --metadata=1.2 /dev/sdg /dev/sdh /dev/sdi /dev/sdj
建议在创建时顺便指定一个名字并预留热备盘,热备盘平时空转,阵列坏盘时自动顶上:
mdadm --create /dev/md1 --name=raid5_data --level=5 --raid-devices=3 --spare-devices=1 \ --chunk=128 /dev/sdd /dev/sde /dev/sdf /dev/sdg # 查看热备盘状态 cat /proc/mdstat
让阵列开机自动组装
软阵列是"按需组装"的,重启后必须告诉内核哪些盘组成哪个阵列。先生成配置:
mdadm --detail --scan # ARRAY /dev/md0 metadata=1.2 name=xxx:0 UUID=xxxxxxxx:xxxx:xxxx:xxxx mdadm --detail --scan | tee /etc/mdadm/mdadm.conf
注意 Debian/Ubuntu 配置文件路径是 /etc/mdadm/mdadm.conf,CentOS 是 /etc/mdadm.conf。生成后用 --examine 兜底补充:
mdadm --examine --scan >> /etc/mdadm/mdadm.conf
关键一步:把配置打进 initramfs,否则重启时引导阶段无法识别阵列:
# Debian / Ubuntu update-initramfs -u # CentOS / Rocky dracut --force
最后写 /etc/fstab 开机自动挂载。强烈建议用 UUID 而不是 /dev/mdX,因为 mdX 编号重启后可能变化:
blkid /dev/md0 # /dev/md0: UUID="a1b2c3d4-...." TYPE="ext4" # /etc/fstab 追加一行 UUID=a1b2c3d4-.... /data ext4 defaults,noatime 0 2
改完 fstab 后建议用 mount -a 验证语法无误再重启。
模拟磁盘故障:fail / remove / add 热替换
RAID 的价值在故障时体现。模拟 sdc 盘损坏(实际生产中是磁盘硬件告警或 I/O 错误):
# 手动把盘标记为故障 mdadm /dev/md0 --fail /dev/sdc # 查看状态,出现 [U_] 表示降级运行 cat /proc/mdstat # md0 : active raid1 sdc[2](F) sdb[0] # 20948992 blocks super 1.2 [2/1] [U_] # 从阵列中摘除故障盘 mdadm /dev/md0 --remove /dev/sdc
降级期间阵列只靠 sdb 一块盘撑着,数据读写正常,但任何一块再坏就全丢,应尽快更换。更换新盘后重新加入,自动开始重建:
# 新盘先清理再添加 wipefs -a /dev/sdc mdadm /dev/md0 --add /dev/sdc # 观察重建进度 cat /proc/mdstat # [=>...................] resync = 15.2% ...
如果创建时配置了热备盘(spare),故障盘被摘除后热备盘会自动接管重建,无需人工干预,这是生产环境的标准姿势。
重建监控与速度调优
重建会占用大量 IO,默认限速可能让重建跑几个小时。可动态调整:
# 调高重建限速(单位 KB/s) echo 100000 > /proc/sys/dev/raid/speed_limit_min echo 200000 > /proc/sys/dev/raid/speed_limit_max
实时盯着进度:
watch -n 5 cat /proc/mdstat
也可以一次性查看,等 [UU] 恢复即可:
mdadm --detail /dev/md0 | grep -E 'State|resync'
想要故障第一时间邮件/脚本通知,可用 mdadm 的监控模式常驻:
mdadm --monitor --daemonize --mail=admin@example.com /dev/md0
在线扩容:新增成员盘与 grow
RAID5 扩容非常常用:云控制台加一块新盘后,先加入阵列再扩展成员数,最后扩大文件系统,全程在线:
# 1. 加入新盘 mdadm /dev/md1 --add /dev/sdg # 2. 把阵列从 3 块盘扩展为 4 块盘(RAID5 自动触发 reshaping) mdadm --grow /dev/md1 --raid-devices=4 # 3. 扩展文件系统,ext4 在线即可 resize2fs /dev/md1 df -h /dev/md1
RAID1 也可以扩容,方法是先 --grow --raid-devices 增加镜像份数再转换级别(如 RAID1 转 RAID5),操作复杂且耗时,新手建议直接规划好盘数。扩容期间阵列 IO 性能明显下降,业务高峰期别做。
排错手册:常见错误与处理方法
下面是实践中最高频的几个坑,按症状给出处理方案:
1. mdadm: /dev/sdc is busy 或 contains a filesystem - 该盘被分区表或旧数据占用:wipefs -a /dev/sdc 后重试 - 若已被系统挂载:先 umount 2. 创建时报 superblock 残留 - 旧盘残留 RAID 元数据:mdadm --zero-superblock /dev/sdb /dev/sdc 3. 重启后阵列不自动组装 - mdadm.conf 未生成或 initramfs 未更新 - 手动验证:mdadm --detail --scan 与 /etc/mdadm.conf 内容一致 - Debian 系务必 update-initramfs -u 4. 阵列编号变成 md127 - 重启后编号漂移属正常,mdadm.conf 里用 name/UUID 固定 - 手动装配:mdadm --assemble --scan 5. 降级阵列无法启动,提示 not enough devices - 少一块盘时用手动装配并指定盘:mdadm --assemble --run /dev/md0 /dev/sdb 6. 重建速度极慢 - 按上文调高 /proc/sys/dev/raid/speed_limit_min 7. 挂载报 unknown filesystem - 先看 cat /proc/mdstat 确认阵列处于 active 而非 degraded 太狠 - RAID5/RAID10 连续坏盘数超过容错上限时阵列会停止,先换盘重建
最后提醒:RAID 不是备份。阵列冗余只防"盘坏了",不防"手滑删了/商家跑路/机房烧了",重要数据务必配合 mdadm 阵列之上的快照或异地备份,三层防护才睡得着觉。



