TT Lab
开始
学习 学习路径 课程

存储实务 — RAID、快照、iSCSI、fio

RAID 是可用性而不是备份 — 重建期间最危险

在 TT Lab 中继续学习

一句话总结

RAID 是让服务器在一块磁盘坏掉时也不会停机的机制。删除的文件、错误的变更、加密攻击都会被原样复制到所有磁盘上,所以 RAID 防不住。而且更换坏盘并重新对齐的重建时间,是整个阵列中最危险的时段。

为什么需要它

磁盘是消耗品。一台服务器上有多块磁盘时,其中一块损坏不是“会不会”的问题,而是“什么时候”的问题。每坏一块磁盘就重装操作系统、从备份里恢复,服务要停好几个小时。RAID(Redundant Array of Independent Disks)把多块磁盘绑成一个整体,以吸收一块磁盘的损坏。

Linux 通过内核的 md(multiple devices)驱动提供软件 RAID,由 mdadm(8) 创建和管理阵列。硬件 RAID 卡则由控制器完成同样的工作,操作系统只能看到一块磁盘。因此卡后面的磁盘状态通常要用厂商工具查看。原理相同,所以本课程用 md 来学习。

工作原理

md(4) 描述的级别(level)整理成表如下。

级别 方式 可承受的故障 可用容量
RAID0 条带化(stripe) 无——只要坏一块就全部丢失 全部 N 块
RAID1 镜像(mirror) N−1 块 一块
RAID5 1 份分布式奇偶校验 1 块 N−1 块
RAID6 2 份奇偶校验 2 块 N−2 块
RAID10 镜像之上做条带化 每个镜像对坏 1 块 一半

RAID5、6 容量便宜,但小写入很贵。因为要修改一个块,必须先读出旧数据和旧奇偶校验,计算新的奇偶校验,再把两者重新写入。写入密集的数据库卷选择 RAID10,原因就在这里。

阵列的状态全在 /proc/mdstat 的一行里。[2/2] [UU] 表示两块中两块都在线,[2/1] [U_] 表示缺了一块的 degraded 状态。故障设备的名称后面会加上 (F)。mdadm --detail 的 State : 行用 clean、degraded、recovering 之类的词表示同一件事。

更换磁盘有四个动作——用 --fail 标记故障,用 --remove 从阵列中移除,用 --add 加入新磁盘,内核就会开始 recovery,把存活一方的内容复制到新磁盘。复制完成后才会重新变回 clean。mdadm --wait 会一直等到这项工作结束。

重建之所以危险,是因为这段时间里存活的那一块是唯一的副本。重建会读取那块磁盘的所有块。如果平时没人读取的角落里藏着读不出来的扇区,就会在这时暴露出来,而那个块已经无处可恢复。所以 md 提供了平时预先全部读一遍的巡检(scrub)。根据内核的 md 文档,向 /sys/block/mdX/md/sync_action 写入 check,就会读取并比较所有副本,把不一致的块数记录到 mismatch_cnt,结束后 sync_action 变为 idle,last_sync_action 变为 check。Debian 系的 mdadm 软件包会预约定期运行这项巡检。

阵列必须在启动时重新组装。mdadm 通过配置文件中的 ARRAY 行得知哪些 UUID 的设备属于同一个阵列。在 Ubuntu、Debian 上是 /etc/mdadm/mdadm.conf,要让它在启动早期就组装,还要用 update-initramfs -u 写入 initramfs。mdadm --detail --brief 会生成这一行。如果把命令运行两次并用 >> 追加,同一行会堆叠两次;这个文件也是故障时人要重新阅读的文档,所以每个阵列只保留一行。

在现场相遇的样子

最常见的重大事故是拔出了正常的磁盘。告警说“一块磁盘故障”时,如果只相信槽位编号就拔,而拔掉的恰好是完好的那块,RAID1 就会整个下线。更换前先用 mdadm --detail 查看故障设备名称,再用 lsblk -o NAME,SERIAL 或 smartctl -i 确认序列号,与物理磁盘上的标签对上。很多团队会把这项确认写成作业计划书里的一行。

第二种是“有了 RAID 就不需要备份”的想法。rm -rf 会在两块磁盘上同时发生,错误的迁移也会像镜子一样精确地被复制。RAID 只能防住磁盘故障这一种事故。恢复原状要靠快照和备份,这些会在下一个模块和“容量规划与变更管理”课程中讲到。

第三种是重建拖慢服务。重建同样是磁盘 I/O,所以会与业务流量竞争。md(4) 允许通过 /proc/sys/dev/raid/speed_limit_min、speed_limit_max 调节重建速度的下限和上限。运维上会在业务时间降低上限、夜里调高,但代价是越慢,危险时段就越长。

下一项实验要做什么

创建三个 256MiB 的回环设备,用其中两个建立 RAID1 /dev/md/sto。格式化为 ext4,留下一个 20MiB 的文件及其校验和,并在 mdadm.conf 中用一行登记该阵列。然后让一块盘故障并移除,记录 degraded 状态,用第三块盘重建,再用校验和确认数据完好。最后运行巡检(check),记录 mismatch_cnt。