RAID

来自 ArchWiki
(重定向自 Mdadm

Redundant Array of Independent Disks(RAID)是一种存储技术,它将多个磁盘驱动器组件(通常是磁盘驱动器或其分区)组合成一个逻辑单元。根据 RAID 的实现方式,此逻辑单元可以是文件系统或可以容纳多个分区的附加透明层。数据以多种方式分布在驱动器上,称为 #RAID 级别,具体取决于所需的冗余和性能级别。因此,选择的 RAID 级别可以防止在硬盘驱动器发生故障时数据丢失,提高性能或两者兼而有之。

本文介绍如何使用 mdadm 创建/管理软件 RAID 阵列。

警告: 在继续操作之前,请务必备份所有数据。

RAID 级别

尽管大多数 RAID 级别都暗示了冗余,但 RAID 并不能保证数据安全。如果发生火灾、计算机被盗或多个硬盘驱动器同时发生故障,RAID 将无法保护数据。此外,使用 RAID 安装系统是一个复杂的过程,可能会破坏数据。

标准 RAID 级别

有许多不同的 RAID 级别;下面列出的是最常见的级别。

RAID 0
使用条带化来组合磁盘。即使它不提供冗余,它仍然被认为是 RAID。但是,它确实提供了很大的速度优势。如果速度的提高值得数据丢失的可能性(例如,对于交换分区),请选择此 RAID 级别。在服务器上,RAID 1 和 RAID 5 阵列更合适。RAID 0 阵列块设备的大小是最小组件分区的大小乘以组件分区的数量。
RAID 1
最直接的 RAID 级别:直接镜像。与其他 RAID 级别一样,只有当分区位于不同的物理磁盘驱动器上时,它才有意义。如果其中一个驱动器发生故障,RAID 阵列提供的块设备将继续正常运行。示例将对除交换和临时数据之外的所有内容使用 RAID 1。请注意,对于软件实现,RAID 1 级别是引导分区的唯一选择,因为读取引导分区的引导加载程序不理解 RAID,但是 RAID 1 组件分区可以作为普通分区读取。RAID 1 阵列块设备的大小是最小组件分区的大小。
RAID 5
需要 3 个或更多物理驱动器,并提供 RAID 1 的冗余以及 RAID 0 的速度和大小优势。RAID 5 使用条带化(如 RAID 0),但还存储分布在每个成员磁盘上的奇偶校验块。如果磁盘发生故障,这些奇偶校验块将用于重建替换磁盘上的数据。RAID 5 可以承受一个成员磁盘的丢失。
注意: RAID 5 是常见的选择,因为它结合了速度和数据冗余。需要注意的是,如果一个驱动器发生故障,并且在更换该驱动器之前另一个驱动器也发生故障,则所有数据都将丢失。此外,考虑到现代磁盘尺寸和消费级磁盘上预期的不可恢复读取错误 (URE) 率,重建 4TiB 阵列预计(即,高于 50% 的可能性)至少会发生一个 URE。因此,存储行业不再建议使用 RAID 5。
RAID 6
需要 4 个或更多物理驱动器,并提供 RAID 5 的优势,但具有针对两个驱动器故障的安全性。RAID 6 也使用条带化(如 RAID 5),但存储两个不同的奇偶校验块,分布在每个成员磁盘上。如果磁盘发生故障,这些奇偶校验块将用于重建替换磁盘上的数据。RAID 6 可以承受两个成员磁盘的丢失。针对不可恢复读取错误的鲁棒性稍好一些,因为在从单个故障驱动器重建时,阵列仍然具有奇偶校验块。但是,考虑到开销,RAID 6 成本很高,在大多数设置中,far2 布局的 RAID 10(见下文)提供了更好的速度优势和鲁棒性,因此是首选。

嵌套 RAID 级别

RAID 1+0
RAID1+0 是一种嵌套 RAID,它结合了两个标准 RAID 级别,以获得性能和额外的冗余。它通常被称为 RAID10,但是,Linux MD RAID10 与简单的 RAID 分层略有不同,请参见下文。
RAID 10
Linux 下的 RAID10 构建在 RAID1+0 的概念之上,但是,它将其实现为单层,具有多种可能的布局。
Y 个磁盘上的 near X 布局在 Y/2 条带上重复每个数据块 X 次,但不需要 X 均匀地除以 Y。数据块放置在它们镜像的每个磁盘上的几乎相同的位置,因此得名。它可以与任意数量的磁盘一起使用,从 2 个开始。2 个磁盘上的 Near 2 等同于 RAID1,4 个磁盘上的 near 2 等同于 RAID1+0。
Y 个磁盘上的 far X 布局旨在在镜像阵列上提供条带化读取性能。它通过将每个磁盘分成两个部分来实现此目的,例如正面和背面,并且写入磁盘 1 正面的内容镜像在磁盘 2 背面,反之亦然。这具有能够条带化顺序读取的效果,这正是 RAID0 和 RAID5 获得性能的原因。缺点是顺序写入具有非常轻微的性能损失,因为磁盘需要寻道到磁盘的另一部分以存储镜像。但是,当读取速度很重要且可用性/冗余至关重要时,far 2 布局的 RAID10 仍然优于分层 RAID1+0 RAID5。但是,它仍然不能替代备份。有关更多信息,请参见维基百科页面。
警告: mdadm 无法重塑 far X 布局的阵列,这意味着一旦创建阵列,您将无法使用 mdadm --grow 扩展它。例如,如果您有一个 4x1TB RAID10 阵列,并且您想切换到 2TB 磁盘,则您的可用容量将保持 2TB。对于此类用例,请坚持使用 near X 布局。

RAID 级别比较

RAID 级别 数据冗余 物理驱动器利用率 读取性能 写入性能 最少驱动器数
0 100% nX

最佳

nX

最佳

2
1 50% 如果多个进程正在读取,则高达 nX,否则为 1X 1X 2
5 67% - 94% (n−1)X

优越

(n−1)X

优越

3
6 50% - 88% (n−2)X (n−2)X 4
10,far2 50% nX

最佳;与 RAID0 相当,但具有冗余

(n/2)X 2
10,near2 50% 如果多个进程正在读取,则高达 nX,否则为 1X (n/2)X 2

* 其中 n 代表专用磁盘的数量。

已弃用的 RAID 级别

线性
线性 允许将两个或多个设备映射到单个设备中,而无需像 RAID0 那样的并行访问,但允许充分利用不同大小的磁盘。但是,它在 2021 年被弃用,并在 2023 年从 Linux 内核中删除(linear.ko 模块)(参见 commit 849d18e)。要使用此模式创建伪 RAID 而无需 mdadm,可以使用低级 dmsetup(8) 实用程序、高级 LVM 框架或 Btrfs 文件系统。

实现

RAID 设备可以通过不同的方式进行管理

软件 RAID
这是最简单的实现方式,因为它不依赖于晦涩的专有固件和软件才能使用。阵列由操作系统通过以下方式管理:
  • 抽象层(例如 mdadm);
    注意: 这是我们稍后将在本指南中使用的方法。
  • 逻辑卷管理器(例如 LVM);
  • 文件系统的组件(例如 ZFSBtrfs)。
硬件 RAID
阵列由安装在 PC 中的专用硬件卡直接管理,磁盘直接连接到该硬件卡。RAID 逻辑在板载处理器上独立于 主机处理器 (CPU) 运行。尽管此解决方案独立于任何操作系统,但后者需要驱动程序才能与硬件 RAID 控制器正常运行。RAID 阵列可以通过选项 ROM 接口进行配置,或者,根据制造商的不同,在安装操作系统后使用专用应用程序进行配置。配置对于 Linux 内核是透明的:它看不到单独的磁盘。
FakeRAID
这种类型的 RAID 正确地称为 BIOS 或板载 RAID,但被错误地宣传为硬件 RAID。阵列由伪 RAID 控制器管理,其中 RAID 逻辑在选项 ROM 或固件本身中实现 带有 EFI SataDriver(在 UEFI 的情况下),但不是所有 RAID 功能都已实现的完整硬件 RAID 控制器。因此,这种类型的 RAID 有时称为 FakeRAID。dmraid 将用于处理这些控制器。以下是一些 FakeRAID 控制器的示例:Intel 快速存储、JMicron JMB36x RAID ROM、AMD RAID、ASMedia 106x 和 NVIDIA MediaShield。

我拥有哪种类型的 RAID?

由于软件 RAID 由用户实现,因此用户很容易知道 RAID 的类型。

但是,区分 FakeRAID 和真正的硬件 RAID 可能更困难。如前所述,制造商经常错误地区分这两种类型的 RAID,并且始终可能存在虚假广告。在这种情况下,最好的解决方案是运行 lspci 命令并查看输出以查找 RAID 控制器。然后进行搜索以查看可以找到关于 RAID 控制器的哪些信息。硬件 RAID 控制器会出现在此列表中,但 FakeRAID 实现不会。此外,真正的硬件 RAID 控制器通常相当昂贵,因此,如果有人定制了系统,那么选择硬件 RAID 设置很可能使计算机的价格发生了非常明显的变化。

安装

安装 mdadmmdadm 用于管理使用普通块设备的纯软件 RAID:底层硬件不提供任何 RAID 逻辑,仅提供磁盘供应。mdadm 将与任何块设备集合一起工作。即使是不寻常的。例如,可以因此从拇指驱动器的集合中制作 RAID 阵列。

准备设备

警告: 这些步骤会擦除设备上的所有内容,因此请仔细键入!

如果设备正在被重用或从现有阵列中重新调整用途,请擦除任何旧的 RAID 配置信息

# mdadm --misc --zero-superblock /dev/drive

或者如果要删除驱动器上的特定分区

# mdadm --misc --zero-superblock /dev/partition
注意
  • 清除分区的超级块不应影响磁盘上的其他分区。
  • 由于 RAID 功能的性质,在运行中的阵列上安全擦除磁盘非常困难。考虑在创建之前这样做是否有用。
  • 您可以使用 GUI 通过 blivet-guiAUR 完成整个磁盘准备过程。

分区设备

强烈建议对将在阵列中使用的磁盘进行分区。由于大多数 RAID 用户选择大于 2 TiB 的磁盘驱动器,因此需要并推荐使用 GPT。有关分区和可用分区工具的更多信息,请参见分区

注意: 也可以直接在原始磁盘(没有分区)上创建 RAID,但不建议这样做,因为它可能会在更换故障磁盘时引起问题。
提示: 更换 RAID 的故障磁盘时,新磁盘的大小必须与故障磁盘完全相同或更大——否则,阵列重建过程将无法工作。即使是同一制造商和型号的硬盘驱动器也可能存在较小的尺寸差异。通过在磁盘末尾留出少量未分配空间,可以补偿驱动器之间的尺寸差异,这使得选择替换驱动器型号更容易。因此,最佳实践是在磁盘末尾留出约 100 MiB 的未分配空间。

GUID 分区表

  • 创建分区后,它们的分区类型 GUID 应为 A19D880F-05FC-4D3B-A006-743F0F84911E(可以通过在 fdisk 中选择分区类型 Linux RAID 或在 gdisk 中选择 FD00 来分配它)。
  • 如果使用较大的磁盘阵列,请考虑分配文件系统标签分区标签,以便稍后更容易识别单个磁盘。
  • 建议在每个设备上创建大小相同的分区。

主引导记录

对于那些在具有 MBR 分区表的 HDD 上创建分区的人,可用的分区类型 ID

  • 0xDA 用于非 FS 数据(fdisk 中的 Non-FS data)。这是 Arch Linux 上 RAID 阵列的推荐 mdadm 分区类型。
  • 0xFD 用于 RAID 自动检测阵列(fdisk 中的 Linux RAID autodetect)。只有在需要 RAID 自动检测时才应使用此分区类型(非 initramfs 系统,旧的 mdadm 元数据格式)。

有关更多信息,请参见 Linux Raid Wiki:Partition Types

构建阵列

使用 mdadm 构建阵列。有关支持的选项,请参见 mdadm(8)。下面给出几个示例。

警告: 不要简单地复制/粘贴下面的示例;请确保您替换了正确的选项和驱动器盘符。
注意
  • 如果这是一个旨在从 Syslinux 启动的 RAID1 阵列,则 syslinux v4.07 中的限制要求元数据值为 1.0 而不是默认值 1.2。
  • Arch 安装介质创建阵列时,请使用选项 --homehost=yourhostname(或 --homehost=any 以始终具有相同的名称,而与主机无关)来设置主机名,否则主机名 archiso 将写入阵列元数据中。
提示: 您可以使用选项 --name=MyRAIDName 或将 raid 设备路径设置为 /dev/md/MyRAIDName 来指定自定义 raid 设备名称。Udev 将使用该名称在 /dev/md/ 中创建指向 raid 阵列的符号链接。如果 homehost 与当前主机名匹配(或者如果 homehost 设置为 any),则链接将为 /dev/md/name,如果主机名不匹配,则链接将为 /dev/md/homehost:name

以下示例显示了构建 2 设备 RAID1 阵列

# mdadm --create --verbose --level=1 --metadata=1.2 --raid-devices=2 /dev/md/MyRAID1Array /dev/sdb1 /dev/sdc1

以下示例显示了构建具有 4 个活动设备和 1 个备用设备的 RAID5 阵列

# mdadm --create --verbose --level=5 --metadata=1.2 --chunk=256 --raid-devices=4 /dev/md/MyRAID5Array /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 --spare-devices=1 /dev/sdf1
提示: --chunk 用于更改数据块大小,使其与默认值不同。有关数据块大小优化的更多信息,请参见 Chunks: the hidden key to RAID performance

以下示例显示了构建具有 2 个设备的 RAID10,far2 阵列

# mdadm --create --verbose --level=10 --metadata=1.2 --chunk=512 --raid-devices=2 --layout=f2 /dev/md/MyRAID10Array /dev/sdb1 /dev/sdc1

阵列在虚拟设备 /dev/mdX 下创建、组装并准备好使用(处于降级模式)。可以直接开始使用它,而 mdadm 在后台重新同步阵列。恢复奇偶校验可能需要很长时间。使用以下命令检查进度:

$ cat /proc/mdstat

更新配置文件

默认情况下,大多数 mdadm.conf 都被注释掉,并且仅包含以下内容

/etc/mdadm.conf
...
DEVICE partitions
...

此指令告诉 mdadm 检查 /proc/partitions 引用的设备并尽可能多地组装阵列。如果您确实想要启动所有可用的阵列,并且确信不会找到意外的超级块(例如在安装新的存储设备之后),则这很好。更精确的方法是将阵列显式添加到 /etc/mdadm.conf

# mdadm --detail --scan >> /etc/mdadm.conf

这将产生如下内容

/etc/mdadm.conf
...
DEVICE partitions
...
ARRAY /dev/md/MyRAID1Array metadata=1.2 name=pine:MyRAID1Array UUID=27664f0d:111e493d:4d810213:9f291abe

这也导致 mdadm 检查 /proc/partitions 引用的设备。但是,只有具有 UUID 为 27664… 的超级块的设备才被组装到活动阵列中。

有关更多信息,请参见 mdadm.conf(5)

组装阵列

更新配置文件后,可以使用 mdadm 组装阵列

# mdadm --assemble --scan

格式化 RAID 文件系统

提示: 要在 RAID 阵列中创建多个卷,请按照软件 RAID 上的 LVM 文章进行操作。

现在可以使用文件系统格式化阵列,就像任何其他分区一样,只需记住

计算步幅和条带宽度

需要两个参数来优化文件系统结构,使其最佳地适应底层 RAID 结构:步幅条带宽度。这些参数从 RAID 数据块大小、文件系统块大小“数据磁盘”数量派生而来。

数据块大小是 RAID 阵列的属性,在创建时确定。mdadm 当前的默认值为 512 KiB。可以使用 mdadm 找到它

# mdadm --detail /dev/mdX | grep 'Chunk Size'

块大小是文件系统的属性,在其创建时确定。包括 ext4 在内的许多文件系统的默认值为 4 KiB。有关 ext4 的详细信息,请参见 /etc/mke2fs.conf

“数据磁盘”的数量是阵列中完全重建它而不会丢失数据所需的最少设备数量。例如,对于由 N 个设备组成的 raid0 阵列,此数量为 N;对于 raid5,此数量为 N-1。

获得这三个量后,可以使用以下公式计算步幅和条带宽度

stride = chunk size / block size
stripe width = number of data disks * stride
示例 1. RAID0

使用正确的条带宽度和步幅格式化为 ext4 的示例

  • 假设的 RAID0 阵列由 2 个物理磁盘组成。
  • 数据块大小为 512 KiB。
  • 块大小为 4 KiB。

步幅 = 数据块大小 / 块大小。在此示例中,数学计算为 512/4,因此步幅 = 128。

条带宽度 = 物理数据磁盘的数量 * 步幅。在此示例中,数学计算为 2*128,因此条带宽度 = 256。

# mkfs.ext4 -v -L myarray -b 4096 -E stride=128,stripe-width=256 /dev/md0
示例 2. RAID5

使用正确的条带宽度和步幅格式化为 ext4 的示例

  • 假设的 RAID5 阵列由 4 个物理磁盘组成;3 个数据磁盘和 1 个奇偶校验磁盘。
  • 数据块大小为 512 KiB。
  • 块大小为 4 KiB。

步幅 = 数据块大小 / 块大小。在此示例中,数学计算为 512/4,因此步幅 = 128。

条带宽度 = 物理数据磁盘的数量 * 步幅。在此示例中,数学计算为 3*128,因此条带宽度 = 384。

# mkfs.ext4 -v -L myarray -b 4096 -E stride=128,stripe-width=384 /dev/md0

有关步幅和条带宽度的更多信息,请参见:RAID Math

示例 3. RAID10,far2

使用正确的条带宽度和步幅格式化为 ext4 的示例

  • 假设的 RAID10 阵列由 2 个物理磁盘组成。由于 far2 布局中 RAID10 的属性,两者都算作数据磁盘。
  • 数据块大小为 512 KiB。
  • 块大小为 4 KiB。

步幅 = 数据块大小 / 块大小。在此示例中,数学计算为 512/4,因此步幅 = 128。

条带宽度 = 物理数据磁盘的数量 * 步幅。在此示例中,数学计算为 2*128,因此条带宽度 = 256。

# mkfs.ext4 -v -L myarray -b 4096 -E stride=128,stripe-width=256 /dev/md0

从 Live CD 挂载

想要从 Live CD 挂载 RAID 分区的用户,请使用

# mdadm --assemble /dev/mdnumber /dev/disk1 /dev/disk2 /dev/disk3 /dev/disk4

如果您的 RAID 1 丢失磁盘阵列被错误地自动检测为 RAID 1(根据 mdadm --detail /dev/mdnumber),并报告为非活动状态(根据 cat /proc/mdstat),请先停止阵列

# mdadm --stop /dev/mdnumber

在 RAID 上安装 Arch Linux

注意: 以下部分仅适用于根文件系统驻留在阵列上的情况。如果阵列包含数据分区,用户可以跳过本节。

您应该在安装过程的分区格式化步骤之间创建 RAID 阵列。不要直接格式化要用作根文件系统的分区,而是在 RAID 阵列上创建它。按照#安装部分创建 RAID 阵列。然后继续执行安装过程,直到 pacstrap 步骤完成。当使用UEFI 启动时,另请阅读EFI 系统分区#软件 RAID1 上的 ESP

更新配置文件

注意: 这应该在 chroot 之外完成,因此文件路径带有前缀 /mnt

安装基本系统后,必须像这样更新默认配置文件 mdadm.conf

# mdadm --detail --scan >> /mnt/etc/mdadm.conf

始终在使用文本编辑器运行此命令后检查 mdadm.conf 配置文件,以确保其内容看起来合理。

注意: 为了防止 mdmonitor.service 在启动时失败(由 udev 激活),您需要在 mdadm.conf 的底部取消注释 MAILADDR 并提供电子邮件地址和/或应用程序来处理有关阵列问题的通知。请参见#邮件通知

继续执行安装过程,直到到达步骤安装指南#Initramfs,然后按照下一节进行操作。

配置 mkinitcpio

注意: 这应该在 chroot 环境中完成。

安装 mdadm 并将 mdadm_udev 添加到 mkinitcpio.confHOOKS 数组,以将 mdadm 支持添加到 initramfs 映像中

/etc/mkinitcpio.conf
...
HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block mdadm_udev filesystems fsck)
...

然后重新生成 initramfs

注意: 每次更改 /etc/mdadm.conf 时,都需要重新生成 initramfs。

配置引导加载程序

根设备

root 参数指向映射的设备。例如

root=/dev/md/MyRAIDArray

如果使用上述内核设备节点方法从软件 raid 分区启动失败,则另一种方法是使用持久块设备命名中的方法之一,例如

root=LABEL=Root_Label

另请参见 GRUB#RAID

RAID0 布局

注意: 这也影响从旧版本 Linux 内核升级到 5.3.4 或更高版本的现有 mdraid RAID0 用户。

自 Linux 内核 5.3.4 版本起,您需要显式告诉内核应使用哪个 RAID0 布局:RAID0_ORIG_LAYOUT (1) 或 RAID0_ALT_MULTIZONE_LAYOUT (2)。[1] 您可以通过提供内核参数来执行此操作,如下所示

raid0.default_layout=2

正确的值取决于用于创建 raid 阵列的内核版本:如果使用内核 3.14 或更早版本创建,则使用 1;如果使用更新版本的内核,则使用 2。检查此项的一种方法是查看 raid 阵列的创建时间

mdadm --detail /dev/md1
/dev/md1:
           Version : 1.2
     Creation Time : Thu Sep 24 10:17:41 2015
        Raid Level : raid0
        Array Size : 975859712 (930.65 GiB 999.28 GB)
      Raid Devices : 3
     Total Devices : 3
       Persistence : Superblock is persistent

       Update Time : Thu Sep 24 10:17:41 2015
             State : clean
    Active Devices : 3
   Working Devices : 3
    Failed Devices : 0
     Spare Devices : 0

        Chunk Size : 512K

Consistency Policy : none

              Name : archiso:root
              UUID : 028de718:20a81234:4db79a2c:e94fd560
            Events : 0

    Number   Major   Minor   RaidDevice State
       0     259        2        0      active sync   /dev/nvme0n1p1
       1     259        6        1      active sync   /dev/nvme2n1p1
       2     259        5        2      active sync   /dev/nvme1n1p2

在这里我们可以看到,此 raid 阵列创建于 2015 年 9 月 24 日。Linux 内核 3.14 的发布日期是 2014 年 3 月 30 日,因此此 raid 阵列很可能使用多区域布局 (2) 创建。

RAID 维护

擦洗

定期运行数据清理以检查和修复错误,这是一个良好的实践。根据阵列的大小/配置,清理可能需要数小时才能完成。

要启动数据清理

# echo check > /sys/block/mdX/md/sync_action

检查操作会扫描驱动器上的坏扇区并自动修复它们。如果它发现好的扇区包含坏数据(即不匹配,扇区中的数据与来自另一个磁盘的数据指示应该是什么数据不一致,例如,奇偶校验块 + 其他数据块会让我们认为此数据块不正确),则不会采取任何操作,但该事件会被记录下来(见下文)。这种“不作为”允许管理员检查扇区中的数据以及通过从冗余信息重建扇区而产生的数据,并选择正确的数据来保留。

与许多与 mdadm 相关的任务/项目一样,可以通过读取 /proc/mdstat 来查询清理的状态。

示例

$ cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4] [raid1]
md0 : active raid1 sdb1[0] sdc1[1]
      3906778112 blocks super 1.2 [2/2] [UU]
      [>....................]  check =  4.0% (158288320/3906778112) finish=386.5min speed=161604K/sec
      bitmap: 0/30 pages [0KB], 65536KB chunk

要安全地停止当前正在运行的数据清理

# echo idle > /sys/block/md0/md/sync_action
注意: 如果系统在部分清理暂停后重启,清理将重新开始。

清理完成后,管理员可以检查有多少块(如果有)被标记为坏块

# cat /sys/block/md0/md/mismatch_cnt

关于清理的一般说明

注意: 用户也可以选择将 repair 回显到 /sys/block/md0/md/sync_action,但这不明智,因为如果遇到数据不匹配,它将自动更新以保持一致。危险在于我们真的不知道奇偶校验块或数据块哪个是正确的(或者在 RAID1 的情况下哪个数据块是正确的)。操作是否获得正确的数据而不是错误的数据,这完全是碰运气。

最好设置一个 root 用户的 cron 任务来安排定期清理。请参阅 raid-checkAUR,它可以帮助完成这项工作。要使用 systemd 计时器而不是 cron 执行定期清理,请参阅 raid-check-systemdAUR,其中包含相同的脚本以及相关的 systemd 计时器单元文件。

注意: 对于典型的机械硬盘,清理大约需要每千兆字节六秒(即每太字节一小时四十五分钟),因此请适当计划您的 cron 任务或计时器的开始时间。

关于 RAID1 和 RAID10 清理的说明

由于 RAID1 和 RAID10 在内核中的写入是无缓冲的,即使阵列是健康的,也可能存在非 0 的不匹配计数。这些非 0 计数只会存在于瞬态数据区域,在这些区域它们不会造成问题。但是,我们无法区分仅仅在瞬态数据中的非 0 计数,还是表示真正问题的非 0 计数。这一事实是 RAID1 和 RAID10 阵列误报的来源。然而,仍然建议定期清理,以便捕获和纠正设备中可能存在的任何坏扇区。

从阵列中移除设备

可以在将 块设备 标记为故障后,将其从阵列中移除

# mdadm --fail /dev/md0 /dev/failing_array_member

现在将其从阵列中移除

# mdadm --remove /dev/md0 /dev/failing_array_member

如果设备没有完全故障,但您想更换它,例如因为它看起来快要坏了,您可以更优雅地处理更换,首先添加一个新驱动器,然后告诉 mdadm 更换它。

例如,以 /dev/sdc1 作为新驱动器,/dev/sdb1 作为故障驱动器

# mdadm /dev/md0 --add /dev/sdc1
# mdadm /dev/md0 --replace /dev/sdb1 --with /dev/sdc1

--with /dev/sdc1 部分是可选的,但更明确。有关更多详细信息,请参阅 [2]

要永久移除设备(例如,从现在开始单独使用它),请按照上述步骤(故障/移除或添加/更换),然后运行

# mdadm --zero-superblock /dev/failing_array_member
警告
  • 不要在线性或 RAID0 阵列上执行此命令,否则将发生数据丢失!
  • 在没有清零超级块的情况下重用已移除的磁盘将导致下次启动时丢失所有数据。(在 mdadm 尝试将其用作 raid 阵列的一部分之后)。

停止使用阵列

  1. 卸载目标阵列
  2. 使用以下命令停止阵列:mdadm --stop /dev/md0
  3. 在每个设备上重复本节开头描述的三个命令。
  4. /etc/mdadm.conf 中删除相应的行。

向阵列添加新设备

可以使用 mdadm 在正在运行的系统上添加新设备,设备可以已挂载。按照上面讨论的方式,使用与阵列中已有的设备相同的布局对新设备进行分区。

如果 RAID 阵列尚未组装,则组装它

# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1

将新设备添加到阵列

# mdadm --add /dev/md0 /dev/sdc1

mdadm 执行此操作应该不需要很长时间。

本文或章节需要扩充。

原因: 应该在 grow 之前创建 --backup-file(在 Talk:RAID#Add a drive (RAID5, RAID6) 中讨论)

根据 RAID 的类型(例如,对于 RAID1),mdadm 可能会将设备添加为备用盘,而不会将数据同步到其中。您可以使用带有 --raid-devices 选项的 --grow 来增加 RAID 使用的磁盘数量。例如,要将阵列增加到四个磁盘

# mdadm --grow /dev/md0 --raid-devices=4

您可以使用以下命令检查进度

# cat /proc/mdstat

使用以下命令检查设备是否已添加

# mdadm --misc --detail /dev/md0
注意: 对于 RAID0 阵列,您可能会收到以下错误消息
mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument

这是因为上面的命令会将新磁盘添加为“备用盘”,但 RAID0 没有备用盘。如果要向 RAID0 阵列添加设备,则需要在同一命令中“grow”和“add”,如下所示

# mdadm --grow /dev/md0 --raid-devices=3 --add /dev/sdc1

增加 RAID 卷的大小

如果在 RAID 阵列中安装了更大的磁盘,或者分区大小已增加,则可能需要增加 RAID 卷的大小以填充更大的可用空间。此过程可以首先按照上面有关更换磁盘的部分进行。一旦 RAID 卷已重建到更大的磁盘上,就必须“grow”以填充空间。

# mdadm --grow /dev/md0 --size=max

接下来,可能需要调整 RAID 卷 /dev/md0 上的分区大小。有关详细信息,请参阅 分区。最后,需要调整上述分区上的文件系统大小。如果使用 gparted 执行分区,则将自动完成此操作。如果使用了其他工具,请卸载然后手动调整文件系统大小。

# umount /storage
# fsck.ext4 -f /dev/md0p1
# resize2fs /dev/md0p1

更改同步速度限制

同步可能需要一段时间。如果机器不需要用于其他任务,则可以提高速度限制。

# cat /proc/mdstat
 Personalities : [raid10]
 md127 : active raid10 sdd1[3] sdc1[2] sdb1[1] sda1[0]
     31251490816 blocks super 1.2 512K chunks 2 far-copies [4/4] [UUUU]
     [=>...................]  resync =  5.2% (1629533760/31251490816) finish=2071.7min speed=238293K/sec
     bitmap: 221/233 pages [884KB], 65536KB chunk

在上面的示例中,最大速度似乎限制在约 238 M/秒。

检查当前速度限制(以千字节每秒,KiB/s 为单位)

# sysctl dev.raid.speed_limit_min
dev.raid.speed_limit_min = 1000
# sysctl dev.raid.speed_limit_max
dev.raid.speed_limit_max = 200000

使用 sysctl 设置新的 raid 重新同步操作的最大速度

# sysctl -w dev.raid.speed_limit_min=600000
# sysctl -w dev.raid.speed_limit_max=600000

然后查看同步速度和预计完成时间。

# cat /proc/mdstat
 Personalities : [raid10]
 md127 : active raid10 sdd1[3] sdc1[2] sdb1[1] sda1[0]
     31251490816 blocks super 1.2 512K chunks 2 far-copies [4/4] [UUUU]
     [=>...................]  resync =  5.3% (1657016448/31251490816) finish=1234.9min speed=399407K/sec
     bitmap: 221/233 pages [884KB], 65536KB chunk

RAID5 性能

为了提高快速存储(例如 NVMe)的 RAID5 性能,请将 /sys/block/mdx/md/group_thread_cnt 增加到更多线程。例如,要使用 8 个线程来操作 RAID5 设备

# echo 8 > /sys/block/md0/md/group_thread_cnt

请参阅 git kernel commit 851c30c9badf

更新 RAID 超级块

要更新 RAID 超级块,您需要首先卸载阵列,然后使用以下命令停止阵列

# mdadm --stop /dev/md0

然后,您可以通过重新组装阵列来更新某些参数。例如,要更新 homehost

# mdadm --assemble --update=homehost --homehost=NAS /dev/md0 /dev/sda1 /dev/sdb1

有关详细信息,请参阅 --update 的参数。

监控

一个简单的单行命令,用于输出 RAID 设备的状态

# awk '/^md/ {printf "%s: ", $1}; /blocks/ {print $NF}' </proc/mdstat
md1: [UU]
md0: [UU]

监视 mdstat

# watch -t 'cat /proc/mdstat'

或者最好使用 tmux

# tmux split-window -l 12 "watch -t 'cat /proc/mdstat'"

使用 iotop 跟踪 IO

iotop 软件包显示进程的输入/输出统计信息。使用此命令查看 raid 线程的 IO。

# iotop -a $(sed 's/^/-p /g' <<<`pgrep "_raid|_resync|jbd2"`)

使用 iostat 跟踪 IO

来自 sysstat 软件包的 iostat 实用程序显示设备和分区的输入/输出统计信息。

# iostat -dmy 1 /dev/md0
# iostat -dmy 1 # all

通过 systemd 使用 mdadm

mdadm 提供了 systemd 服务 mdmonitor.service,它可以用于监视您的 raid 阵列的健康状况,并在出现任何问题时通知您。

此服务很特殊,因为它不能像常规服务那样手动激活;mdadm 将在系统启动时通过 udev 在组装您的阵列时负责激活它,但只有在为其通知配置了电子邮件地址和/或程序时才会这样做(见下文)。

电子邮件通知

警告: 未能配置电子邮件地址将导致监视服务静默失败而无法启动。
注意: 为了发送电子邮件,需要正确配置的 邮件传输代理

要启用此功能,请编辑 /etc/mdadm.conf 并定义电子邮件地址

MAILADDR user@domain

然后,要验证一切是否正常工作,请运行以下命令

# mdadm --monitor --scan --oneshot --test

如果测试成功并且电子邮件已送达,则您已完成;下次重新组装阵列时,mdmonitor.service 将开始监视它们是否有错误。

程序通知

与上面的电子邮件通知类似,编辑 /etc/mdadm.conf 并编辑行

PROGRAM /usr/sbin/handle-mdadm-events

PROGRAM 的参数是您想要为任何事件运行的脚本。然后与适当的网络监控代理进行交互。甚至 IM 客户端或推送通知服务,如家庭用户的 ntfy.sh。

以与上面的电子邮件通知相同的方式进行测试。

故障排除

如果您在重启时收到关于“invalid raid superblock magic”的错误,并且您有安装到的驱动器以外的其他硬盘驱动器,请检查您的硬盘驱动器顺序是否正确。在安装期间,您的 RAID 设备可能是 hdd、hde 和 hdf,但在启动期间它们可能是 hda、hdb 和 hdc。相应地调整您的内核行。无论如何,这就是我遇到的情况。

错误:“kernel: ataX.00: revalidation failed”

如果您突然(在重启后,更改了 BIOS 设置)遇到类似以下的错误消息

Feb  9 08:15:46 hostserver kernel: ata8.00: revalidation failed (errno=-5)

这不一定意味着驱动器已损坏。您经常会在网上找到恐慌链接,这些链接都会往最坏的情况去想。总而言之,不要惊慌。也许您只是以某种方式更改了 BIOS 或内核参数中的 APIC 或 ACPI 设置。将它们改回去,您应该就没事了。通常,关闭和/或开启 ACPI 应该会有所帮助。

以只读方式启动阵列

当 md 阵列启动时,将写入超级块,并且可能开始重新同步。要以只读方式启动,请设置内核模块 md_mod 参数 start_ro。当设置此参数时,新阵列获得“auto-ro”模式,该模式禁用所有内部 io(超级块更新、重新同步、恢复),并在第一个写入请求到达时自动切换到“rw”。

注意: 可以使用 mdadm --readonly 在第一个写入请求之前将阵列设置为真正的“ro”模式,或者可以使用 mdadm --readwrite 在没有写入的情况下启动重新同步。

要在启动时设置参数,请将 md_mod.start_ro=1 添加到您的内核行。

或者在模块加载时通过 内核模块#使用 modprobe.d 或直接从 /sys/ 设置它

# echo 1 > /sys/module/md_mod/parameters/start_ro

从 raid 中损坏或丢失的驱动器恢复

当其中一个驱动器因任何原因损坏时,您也可能会遇到上述错误。在这种情况下,您将不得不强制 raid 即使在一个磁盘短缺的情况下仍然开启。输入此命令(根据需要更改)

# mdadm --manage /dev/md0 --run

现在您应该能够再次挂载它,例如这样(如果它在 fstab 中)

# mount /dev/md0

现在 raid 应该再次工作并可用,但是少了一个磁盘。因此,要添加该磁盘分区,请按照上面 #准备设备 中的描述进行操作。完成后,您可以通过执行以下操作将新磁盘添加到 raid

# mdadm --manage --add /dev/md0 /dev/sdd1

如果您输入

# cat /proc/mdstat

您可能会看到 raid 现在处于活动状态并正在重建。

您可能还想更新您的配置(请参阅:#更新配置文件)。

基准测试

有几种工具可以用于基准测试 RAID。最显着的改进是当多个线程从同一个 RAID 卷读取时速度的提高。

bonnie++ 测试对一个或多个文件的数据库类型访问,以及小文件的创建、读取和删除,这些可以模拟诸如 Squid、INN 或 Maildir 格式电子邮件等程序的使用。随附的 ZCAV 程序测试硬盘驱动器不同区域的性能,而无需向磁盘写入任何数据。

hdparm 不应 用于基准测试 RAID,因为它提供的结果非常不一致。

另请参阅

邮件列表

mdadm

论坛帖子