RAID
Redundant Array of Independent Disks (RAID) 是一种存储技术,它将多个磁盘驱动器组件——通常是磁盘驱动器或其分区——组合成一个逻辑单元。根据 RAID 实现的不同,这个逻辑单元可以是一个文件系统,也可以是一个可以容纳多个分区的额外的透明层。
数据以几种称为 #RAID 级别的方式分布在驱动器上,具体取决于所需的冗余和性能级别。因此,所选的 RAID 级别可以在硬盘驱动器发生故障时防止数据丢失、提高性能或两者兼而有之。
本文介绍如何使用 mdadm(8) 创建和管理软件 RAID 阵列。
RAID 级别
尽管大多数 RAID 级别都意味着冗余,但 RAID 并不保证数据是安全的。RAID 无法在发生火灾、计算机被盗或多个硬盘驱动器同时发生故障时保护数据。此外,安装带有 RAID 的系统是一个可能销毁数据的复杂过程。
标准 RAID 级别
有许多不同的 RAID 级别;下面列出的是最常见的。
- RAID 0
- 使用条带化来组合磁盘。尽管它*不提供冗余*(实际上降低了可靠性),但它仍然被认为是 RAID。然而,它*确实提供了巨大的速度提升*。如果速度提升值得数据丢失的可能性(例如,用于 swap 分区),请选择此 RAID 级别。在服务器上,RAID 1 和 RAID 5 阵列更合适。RAID 0 阵列块设备的大小是最小组件分区的大小乘以组件分区的数量。
- RAID 1
- 最直接的 RAID 级别:直接镜像。与其他 RAID 级别一样,只有当分区位于不同的物理磁盘驱动器上时才有意义。如果其中一个驱动器发生故障,RAID 阵列提供的块设备将继续正常运行。示例将除 swap 和临时数据外,所有内容都用于 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 成本高昂,在大多数情况下,RAID 10 在 far2 布局(见下文)中提供更好的速度优势和健壮性,因此更受青睐。
嵌套 RAID 级别
- RAID 1+0
- RAID1+0 是一种嵌套 RAID,它结合了两种标准的 RAID 级别以获得性能和额外的冗余。它通常被称为*RAID10*,但 Linux MD RAID10 与简单的 RAID 分层略有不同,见下文。
- RAID 10
- Linux 下的 RAID10 是在 RAID1+0 的概念基础上构建的,然而,它实现为一个单一层,具有多种可能的布局。
- Y 磁盘上的*near X* 布局将每个块重复 X 次在 Y/2 条带上,但不需要 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 --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 代表专用磁盘的数量。
LINEAR
LINEAR 允许将两个或多个设备映射成一个设备,没有像 RAID0 那样的并行访问,但允许完全使用不同大小的磁盘。要使用此模式创建伪 RAID 而不使用*mdadm*,可以使用低级 dmsetup(8) 工具,高级 LVM 框架或 Btrfs 文件系统。
实现
RAID 设备可以通过不同方式管理
- 软件 RAID
- 这是最简单的实现方式,因为它不依赖于晦涩的专有固件和软件。该阵列由操作系统管理,通过
- 硬件 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 Rapid Storage,JMicron JMB36x RAID ROM,AMD RAID,ASMedia 106x 和 NVIDIA MediaShield。
我拥有哪种 RAID 类型?
由于软件 RAID 是由用户实现的,因此用户很容易知道 RAID 的类型。
然而,区分 FakeRAID 和真正的硬件 RAID 可能更困难。如前所述,制造商经常错误地区分这两种 RAID 类型,并且可能存在虚假广告。在这种情况下,最佳解决方案是运行lspci命令并查看输出以找到 RAID 控制器。然后进行搜索以了解有关 RAID 控制器的信息。硬件 RAID 控制器会出现在此列表中,但 FakeRAID 实现不会。此外,真正的硬件 RAID 控制器通常相当昂贵,因此如果有人定制了系统,那么选择硬件 RAID 设置很可能会显著改变计算机的价格。
安装
安装 mdadm。mdadm 用于管理纯软件 RAID,使用普通块设备:底层硬件不提供任何 RAID 逻辑,仅提供磁盘。mdadm 可以与任何块设备集合一起工作。例如,可以从一组 U 盘创建 RAID 阵列。
准备设备
如果设备正在被重新使用或从现有阵列重新配置,请擦除任何旧的 RAID 配置信息
# mdadm --misc --zero-superblock /dev/drive
或者,如果要删除驱动器上的特定分区
# mdadm --misc --zero-superblock /dev/partition
- 擦除分区的超级块不应影响磁盘上的其他分区。
- 由于 RAID 功能的性质,在运行的阵列上安全擦除磁盘非常困难。在创建之前考虑是否需要这样做。
- 您可以使用 GUI 和 blivet-guiAUR 来完成整个磁盘准备过程。
分区设备
强烈建议对将在阵列中使用的磁盘进行分区。由于大多数 RAID 用户选择大于 2 TiB 的磁盘驱动器,因此需要并建议使用 GPT。有关分区和可用分区工具的更多信息,请参阅分区。
GUID 分区表
- 创建分区后,其分区类型 GUID应为
A19D880F-05FC-4D3B-A006-743F0F84911E(可以通过在*fdisk*中选择分区类型Linux RAID或在*gdisk*中选择FD00来分配)。 - 如果使用了较大的磁盘阵列,请考虑分配文件系统标签或分区标签,以便以后更容易识别单个磁盘。
- 建议在每个设备上创建相同大小的分区。
主引导记录
对于在具有 MBR 分区表的 HDD 上创建分区的用户,可用的分区类型 ID为
0xDA用于非文件系统数据(*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)。下面给出了几个示例。
--name=MyRAIDName 指定自定义 RAID 设备名称,或将 RAID 设备路径设置为 /dev/md/MyRAIDName。Udev 将使用该名称在 /dev/md/ 中创建指向 RAID 阵列的符号链接。如果 homehost 与当前主机名匹配(或如果 homehost 设置为 any),链接将是 /dev/md/name,如果主机名不匹配,链接将是 /dev/md/homehost:name。以下示例显示了构建一个 2 设备的 RAID1 阵列
# mdadm --create --verbose --level=1 --raid-devices=2 /dev/md/MyRAID1Array /dev/sdb1 /dev/sdc1
以下示例显示了构建一个具有 4 个活动设备和 1 个备用设备的 RAID5 阵列
# mdadm --create --verbose --level=5 --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 --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 文件系统
阵列现在可以像任何其他分区一样使用 文件系统进行格式化,只需记住
- 由于卷大小较大,并非所有文件系统都适用(参见:Wikipedia:Comparison of file systems#Limits)。
- 文件系统应支持在线增长和缩小(参见:Wikipedia:Comparison of file systems#Features)。
- 应计算正确的跨距和条带宽度以获得最佳性能。
计算跨距和条带宽度
需要两个参数来优化文件系统结构,使其能够最好地适应底层 RAID 结构:*跨距*(stride)和*条带宽度*(stripe width)。这些参数由 RAID *块大小*(chunk size)、文件系统*块大小*(block size)和*数据磁盘*数量得出。
块大小是 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。
stride = chunk size / block size。在此示例中,计算为 512/4,因此 stride = 128。
stripe width = # of physical *data* disks * stride。在此示例中,计算为 2*128,因此 stripe width = 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。
stride = chunk size / block size。在此示例中,计算为 512/4,因此 stride = 128。
stripe width = # of physical *data* disks * stride。在此示例中,计算为 3*128,因此 stripe width = 384。
# mkfs.ext4 -v -L myarray -b 4096 -E stride=128,stripe-width=384 /dev/md0
有关 stride 和 stripe width 的更多信息,请参阅:RAID Math。
示例 3. RAID10,far2
格式化为 ext4 的示例,具有正确的条带宽度和跨距
- 假设的 RAID10 阵列由 2 个物理磁盘组成。由于 far2 布局的 RAID10 的特性,两者都算作数据磁盘。
- 块大小为 512 KiB。
- 块大小为 4 KiB。
stride = chunk size / block size。在此示例中,计算为 512/4,因此 stride = 128。
stripe width = # of physical *data* disks * stride。在此示例中,计算为 2*128,因此 stripe width = 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 阵列上。请按照#Installation部分创建 RAID 阵列。然后继续安装过程,直到完成 pacstrap 步骤。使用UEFI 引导时,也请阅读EFI system partition#ESP on software RAID1。
更新配置文件
/mnt 前缀。在安装完基本系统后,必须像这样更新默认配置文件 mdadm.conf
# mdadm --detail --scan >> /mnt/etc/mdadm.conf
运行此命令后,请始终使用文本编辑器检查 mdadm.conf 配置文件,以确保其内容看起来合理。
mdmonitor.service 在启动时失败(由 udev 激活),您需要取消注释 MAILADDR 并提供电子邮件地址和/或应用程序来处理阵列问题的通知,位于 mdadm.conf 的底部。请参阅#Email notifications。继续安装过程,直到您到达 Installation guide#Initramfs 步骤,然后按照下一节进行。
配置 mkinitcpio
安装 mdadm 并将 mdadm_udev 添加到 mkinitcpio.conf 的 HOOKS 数组中,以便将 mdadm 支持添加到 initramfs 映像中
/etc/mkinitcpio.conf
... HOOKS=(base udev autodetect microcode modconf kms keyboard keymap consolefont block mdadm_udev filesystems fsck) ...
/etc/mdadm.conf 后,都需要重新生成 initramfs。配置引导加载程序
根设备
将 root 参数指向映射的设备。例如
root=/dev/md/MyRAIDArray
如果使用上述内核设备节点方法从软件 RAID 分区引导失败,另一种方法是使用 Persistent block device naming 中的方法之一,例如
root=LABEL=Root_Label
另请参阅 GRUB#RAID。
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 Kernel 3.14 的发布日期是 2014 年 3 月 30 日,因此这个 RAID 阵列很可能使用了多区域布局(2)。
RAID 维护
擦除 (Scrubbing)
定期运行数据 数据校验以检查和修复错误是一个好习惯。根据阵列的大小/配置,校验可能需要数小时才能完成。
启动数据擦除:
# echo check > /sys/block/mdX/md/sync_action
或者,您可以启用包含的 mdcheck_start.timer,该定时器每周执行一次扫描。
检查操作会扫描驱动器是否存在坏扇区并自动修复它们。如果找到包含坏数据的良好扇区(即不匹配,一个扇区中的数据与另一个驱动器中的数据指示的不一致,例如奇偶校验块+其他数据块会导致我们认为该数据块不正确),则不会采取任何行动,但事件会被记录(见下文)。这种“无操作”允许管理员检查扇区中的数据以及通过重建扇区从冗余信息中获得的数据,并选择正确的数据进行保留。
与 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
关于数据校验的一般说明
/sys/block/md0/md/sync_action,但这不建议,因为如果遇到数据不匹配,它将被自动更新以保持一致。危险在于我们真的不知道是奇偶校验还是数据块是正确的(或者 RAID1 的情况下是哪个数据块)。它是否能获取到正确的数据而不是坏数据,纯粹是运气。最好设置一个 root 的 cron 作业来安排定期的校验。请参阅 raid-checkAUR,它可以提供帮助。要使用 systemd 定时器而不是 cron 执行定期校验,请参阅 raid-check-systemdAUR,它包含相同的脚本以及相关的 systemd 定时器单元文件。
RAID1 和 RAID10 的数据校验说明
由于 RAID1 和 RAID10 在内核中的写入是无缓冲的,即使阵列健康,阵列也可能出现非零的失配计数。这些非零计数只会存在于瞬时数据区域,不会造成问题。然而,我们无法区分仅仅存在于瞬时数据中的非零计数,还是预示着真实问题的非零计数。这一事实是 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 阵列的一部分之后)。
停止使用阵列
- 卸载目标阵列
- 使用以下命令停止阵列:
mdadm --stop /dev/md0 - 在每个设备上重复本节开头描述的三个命令。
- 从
/etc/mdadm.conf中删除相应的行。
向阵列添加新设备
可以使用 mdadm 在运行的系统上添加新设备,并且设备可以挂载。使用与数组中已有的设备相同的布局来分区新设备,如上所述。
组装 RAID 阵列(如果尚未组装)
# mdadm --assemble /dev/md0 /dev/sda1 /dev/sdb1
将新设备添加到阵列
# mdadm --add /dev/md0 /dev/sdc1
mdadm 完成此操作应该不会花费太长时间。
根据 RAID 的类型(例如,对于 RAID1),mdadm 可能会将设备添加为备用驱动器而不进行数据同步。您可以使用带有 --raid-devices 选项的 --grow 来增加 RAID 使用的磁盘数量。例如,将阵列扩展到四个磁盘
# mdadm --grow /dev/md0 --raid-devices=4
您可以使用以下命令检查进度
# cat /proc/mdstat
使用以下命令检查设备是否已添加
# mdadm --misc --detail /dev/md0
mdadm: add new device failed for /dev/sdc1 as 2: Invalid argument
这是因为上述命令会将新磁盘添加为“备用”,但 RAID0 没有备用驱动器。如果您想向 RAID0 阵列添加设备,您需要在一个命令中同时“扩展”和“添加”,如下所示
# mdadm --grow /dev/md0 --raid-devices=3 --add /dev/sdc1
增大 RAID 卷的大小
如果在 RAID 阵列中安装了更大的磁盘或增加了分区大小,则可能需要增加 RAID 卷的大小以填满更大的可用空间。此过程可能首先需要遵循上述关于更换磁盘的部分。一旦 RAID 卷已重建到更大的磁盘上,就必须“扩展”它以填满空间。
# mdadm --grow /dev/md0 --size=max
接下来,可能需要调整 RAID 卷 /dev/md0 上的分区大小。有关详细信息,请参阅 Partitioning。最后,需要调整上述分区上的文件系统大小。如果使用 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
在上面的例子中,似乎最大速度被限制在每秒约 238MB。
检查当前速度限制(以每秒千字节为单位,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 性能
为了提高 RAID5 对快速存储(例如 NVMe)的性能,请将 /sys/block/mdx/md/group_thread_cnt 增加到更多线程。例如,为操作 RAID5 设备使用 8 个线程
# 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 提供了 mdmonitor.service systemd 服务,该服务可用于监控 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,适用于家庭用户。
像电子邮件通知一样进行测试。
故障排除
如果您在重启时遇到关于“无效的 RAID 超级块魔数”的错误,并且除了您安装的硬盘之外还有其他硬盘,请检查您的硬盘顺序是否正确。在安装期间,您的 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 和/或 APIC 应该会有帮助。
以只读方式启动阵列
当 md 阵列启动时,将写入超级块,并且可能开始同步。要以只读方式启动,请设置内核模块 md_mod 参数 start_ro。当此参数设置时,新阵列将获得“auto-ro”模式,该模式禁用所有内部 IO(超级块更新、同步、恢复),并在第一个写入请求到达时自动切换到“rw”模式。
mdadm --readonly 将阵列设置为真正的“ro”模式,或者在没有写入的情况下使用 mdadm --readwrite 启动同步。要在启动时设置参数,请将 md_mod.start_ro=1 添加到您的内核行。
或者通过 Kernel module#Using modprobe.d 或直接从 /sys/ 加载模块时设置它
# echo 1 > /sys/module/md_mod/parameters/start_ro
从损坏或丢失的 RAID 驱动器中恢复
当驱动器因任何原因损坏时,您也可能收到上述错误。在这种情况下,您将不得不强制 RAID 即使缺少一个磁盘也能启动。输入此命令(根据需要进行更改)
# mdadm --manage /dev/md0 --run
现在您应该能够像这样(如果将其添加到 fstab 中)重新挂载它
# mount /dev/md0
现在 RAID 应该可以再次工作并可用,但缺少一个磁盘。因此,要添加那个磁盘,请按照上面 #Prepare the devices 中描述的方式进行分区。完成后,您可以通过执行以下操作将新磁盘添加到 RAID:
# mdadm --manage --add /dev/md0 /dev/sdd1
如果您输入
# cat /proc/mdstat
您可能会看到 RAID 现在已激活并且正在重建。
您还可能需要更新您的配置(请参阅:#Update configuration file)。
基准测试
有几种工具用于基准测试 RAID。最显著的改进是当多个线程从同一个 RAID 卷读取时的速度提升。
bonnie++ 测试对一个或多个文件的数据库类型访问,以及创建、读取和删除小文件,这些操作可以模拟 Squid、INN 或 Maildir 格式电子邮件等程序的用法。附带的 ZCAV 程序可以在不写入数据到磁盘的情况下测试硬盘不同区域的性能。
hdparm不应用于 RAID 的基准测试,因为它会提供非常不一致的结果。
参见
- Linux 内核 RAID 文档
- Linux Software RAID (thomas-krenn.com)
- Linux RAID wiki 条目,位于 The Linux kernel archives:Linux RAID wiki entry
- 位图如何工作
- Red Hat Enterprise Linux 9 文档的 第 19 章。管理 RAID。
- Linux 文档项目上的 Linux-RAID FAQ
- (Archive.org) BAARF,包括 Art S. Kagel 撰写的 《为什么我不能使用 RAID 5?》(Archive.org)
- Linux Magazine 上的《RAID 简介》、《嵌套 RAID:基于 RAID-5 和 RAID-6 的配置》、《嵌套 RAID 简介:RAID-01 和 RAID-10》以及《嵌套 RAID:三连击》:Introduction to RAID, Nested-RAID: RAID-5 and RAID-6 Based Configurations, Intro to Nested-RAID: RAID-01 and RAID-10, and Nested-RAID: The Triple Lindy
- 如何:加快 Linux 软件 RAID 的构建和重新同步速度
- Wikipedia:非 RAID 驱动器架构
邮件列表
mdadm
- mdadm 源代码
- Linux Magazine 上的《使用 mdadm 在 Linux 上进行软件 RAID》:Software RAID on Linux with mdadm
- Wikipedia - mdadm
论坛帖子