Linux 下使用 RAID10 软陈列

今天在 VirtualBox Deepin 20.2.4 Linux 虚拟机里演示一下 Linux 下用 mdadm 创建了 RAID10 软陈列。RAID10 陈列兼顾了速度与数据冗余保障。其中介绍一下我在创建过程中的一些心得。包括:选择 RAID10 布局类型并创建阵列、模拟阵列成员损坏及恢复、测试创建阵列的命令中设备顺序对阵列的影响、删除阵列、阵列不能取代数据备份、参考资料。视频演示地址:https://www.bilibili.com/video/BV1zT4y1v7Va?share_source=copy_web

一、选择 RAID10 布局类型并创建阵列

测试的环境是 VirtualBox 里面的 Deepin 20.2.4 Linux,内核版本 5.10.60,mdadm - V4.1 - 2018-10-01。

RAID10 软阵列在 Linux 下用 mdadm 创建,虽然理论上两块就行,但没有意义。所以一般最少4块,这里仅用4块硬盘创建,不使用备份盘。这个 RAID10 坏 1 块硬盘没事,运气好的话坏 2 块硬盘恰好是不同的数据也没事。但在实际使用中如果是这种情况,出现了1块坏盘就必须及时替换。因为,你不能保证下 1 块坏的恰巧是不同数据的那块。下面分别用 4 块 8G 的虚拟硬盘创建陈列,在系统中分别是 sdb、sdc、sdd 和 sde。Linux 下 mdadm 创建 RAID10 有 3 种布局,分别是 near(默认)、far、offset。从网上的一篇机械硬盘 RAID 10 测试文章最后的结论来看(参见:Linux software RAID 10 layouts performance: near, far and offset benchmark analysis https://www.ilsistemista.net/index.php/linux-a-unix/35-linux-software-raid-10-layouts-performance-near-far-and-offset-benchmark-analysis.html ),“near” 布局有非常好的随机存取速度和过得去的顺序存取速度,“offset”布局有好的随机和顺序存取速度,“far”布局有非常好的顺序存取速度但是随机存取速度较慢。这里就以默认的 near 布局创建 RAID10 阵列。为了测试 RAID10 阵列创建时组件设备的顺序的影响,每块磁盘分为两个分区,如:sdb1、sdb2。创建阵列的步骤如下:

1、用 fdisk 命令分别创建4个磁盘的分区,并修改分区类型为阵列成员。 如:

sudo fdisk /dev/sdb

创建好后的 /dev/sdb 如下:

littlebat@learndiary:~$ sudo fdisk -l /dev/sdb
Disk /dev/sdb: 8 GiB, 8589934592 bytes, 16777216 sectors
Disk model: VBOX HARDDISK
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0xa653d59f
Device     Boot   Start      End Sectors Size Id Type
/dev/sdb1          2048  8390655 8388608   4G fd Linux raid autodetect
/dev/sdb2       8390656 16777215 8386560   4G fd Linux raid autodetect
littlebat@learndiary:~$

/dev/sdc、/dev/sdd、/dev/sde 同样如此分区。

2、正式创建 RAID10 阵列

sudo mdadm --create --verbose --level=10 --raid-devices=4 /dev/md/r10a1 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1

3、查看阵列信息

sudo mdadm --detail /dev/md/r10a1
littlebat@learndiary:~$ sudo mdadm --detail /dev/md/r10a1
/dev/md/r10a1:
Version : 1.2
Creation Time : Sun Mar 27 16:29:45 2022
Raid Level : raid10
Array Size : 8378368 (7.99 GiB 8.58 GB)
Used Dev Size : 4189184 (4.00 GiB 4.29 GB)
Raid Devices : 4
Total Devices : 4
Persistence : Superblock is persistent
Update Time : Sun Mar 27 16:30:27 2022
State : clean
Active Devices : 4
Working Devices : 4
Failed Devices : 0
Spare Devices : 0
Layout : near=2
Chunk Size : 512K
Consistency Policy : resync
Name : learndiary:r10a1  (local to host learndiary)
UUID : 716cefb2:264f1d90:c97c674d:d90d2dd1
Events : 17
Number   Major   Minor   RaidDevice State
0       8       17        0      active sync set-A   /dev/sdb1
1       8       33        1      active sync set-B   /dev/sdc1
2       8       49        2      active sync set-A   /dev/sdd1
3       8       65        3      active sync set-B   /dev/sde1

然后更新 /etc/mdadm/mdadm.conf 文件:

sudo mdadm --detail --scan | sudo tee -a /etc/mdadm/mdadm.conf

更新 initramfs 文件:

sudo update-initramfs -u

4、在阵列上创建文件系统,以 ext4 为例

sudo mkfs.ext4 -L R10P /dev/md/r10a1
sudo mkdir /mnt/tmp -v
sudo mount /dev/md/r10a1 /mnt/tmp -v
sudo touch /mnt/tmp/test.txt
ls /mnt/tmp/test.txt

二、模拟阵列成员损坏及恢复

从上面 sudo mdadm --detail 显示的信息可以看到 /dev/sdb1 和 /dev/sdd1 是 set-A,而 /dev/sdc1 和 /dev/sde1 是 set-B,每个 set 就是一份完整的数据。所以,在这个例子中,如果 4 个阵列成员的任 1 个坏掉数据都不会丢。坏掉 2 个的话,如果这 2 个是同一个 set 的话,数据也不会丢。但如果坏掉的 1 个位于 set-A 中,1个位于 set-B 中,而 set-B 坏掉的成员恰好是 set-A 坏掉成员的镜像,那么数据就丢了。总的来说,在 RAID10 阵列中坏掉 1 个阵列成员就必须替换掉,因为你不知道下 1 个坏掉会不会恰好是前 1 个成员的数据镜像。下面模拟一下阵列成员损坏及恢复:

1、 标记 /dev/sdb1 损坏并移除:

sudo mdadm /dev/md/r10a1 --fail /dev/sdb1
sudo mdadm --detail /dev/md/r10a1
sudo mdadm /dev/md/r10a1 --remove /dev/sdb1
sudo mdadm --detail /dev/md/r10a1

2、尝试标记 dev/sdc1 损坏并移除:

sudo mdadm /dev/md/r10a1 --fail /dev/sdc1
显示:mdadm: set device faulty failed for /dev/sdc1:  Device or resource busy
sudo mdadm /dev/md/r10a1 --remove /dev/sdc1
显示:mdadm: hot remove failed for /dev/sdc1: Device or resource busy

这是因为 /dev/sdc1 损坏了,阵列就被破坏,所以无法正常标记损坏和移除。

3、尝试标记 dev/sde1 损坏并移除:

sudo mdadm /dev/md/r10a1 --fail /dev/sde1
sudo mdadm --detail /dev/md/r10a1
sudo mdadm /dev/md/r10a1 --remove /dev/sde1
sudo mdadm --detail /dev/md/r10a1

是可以正常标记损坏并移除的。

4、尝试标记 dev/sdd1 损坏并移除:

sudo mdadm /dev/md/r10a1 --fail /dev/sdd1
显示:mdadm: set device faulty failed for /dev/sdd1:  Device or resource busy
sudo mdadm /dev/md/r10a1 --remove /dev/sdd1
显示:mdadm: hot remove failed for /dev/sdd1: Device or resource busy

无法正常标记损坏和移除。

5、清除被移除阵列成员的超级块(superblock)并加入阵列:

先查看一下 /dev/sdb 和 /dev/sde 的文件系统信息:

sudo lsblk --fs /dev/sdb /dev/sde

显示 /dev/sdb1 /dev/sde1 仍是阵列的成员。

sudo mdadm --zero-superblock /dev/sdb1 /dev/sde1

再看就没有了阵列成员的信息了。

sudo fdisk -l /dev/sdb /dev/sde

可以看到分区信息没有变的。

这里是原来 /dev/sdb1 和 /dev/sde1,因此可以直接加入。如果是另外新的阵列成员,那么它的大小必须跟移除的成员相同或大于。

sudo mdadm /dev/md/r10a1 --add /dev/sdb1
sudo mdadm /dev/md/r10a1 --add /dev/sde1
sudo mdadm --detail /dev/md/r10a1

三、测试创建阵列的命令中设备顺序对阵列的影响

创建第 1 个阵列时,我们用的命令是:

sudo mdadm --create --verbose --level=10 --raid-devices=4 /dev/md/r10a1 /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1

现在,我们创建第 2 个阵列 r10a2,改变一下后面 4 个设备的顺序,看看创建出来的阵列跟第 1 个阵列有什么区别。作为对比测试,不把第 2 个阵列加入 mdadm.conf 配置文件并更新 initramfs 文件。

sudo mdadm --create --verbose --level=10 --raid-devices=4 /dev/md/r10a2 /dev/sdb2 /dev/sdd2 /dev/sdc2 /dev/sde2
sudo mdadm --detail /dev/md/r10a2

然后,我们测试标记损坏并移除阵列 /dev/md/r10a1 的 set-A,即 /dev/sdb1 和 /dev/sdd1

sudo mdadm /dev/md/r10a1 --fail set-A
sudo mdadm /dev/md/r10a1 --remove /dev/sdb1 /dev/sdd1

然后,我们尝试标记损坏并移除第 2 个阵列 /dev/md/r10a2 中同样磁盘的第 2 个分区,即 /dev/sdb2 和 /dev/sdd2

sudo mdadm /dev/md/r10a2 --fail /dev/sdb2 /dev/sdd2
显示:
mdadm: set /dev/sdb2 faulty in /dev/md/r10a2
mdadm: set device faulty failed for /dev/sdd2:  Device or resource busy
sudo mdadm /dev/md/r10a2 --remove /dev/sdb2 /dev/sdd2
显示:
mdadm: hot removed /dev/sdb2 from /dev/md/r10a2
mdadm: hot remove failed for /dev/sdd2: Device or resource busy
sudo mdadm --detail /dev/md/r10a2

显示只有 /dev/sdb2 被正常标记损坏并移除,而 /dev/sdd2 不能被正常标记损坏并移除。

然后,我们尝试标记损坏并移除 /dev/sdc2

sudo mdadm /dev/md/r10a2 --fail /dev/sdc2
sudo mdadm /dev/md/r10a2 --remove /dev/sdc2

成功。

再继续尝试标记损坏并移除 /dev/sde2

sudo mdadm /dev/md/r10a2 --fail /dev/sde2
sudo mdadm /dev/md/r10a2 --remove /dev/sde2

失败。

sudo mdadm --detail /dev/md/r10a2

从上面可以看出,第 1 个阵列 sdb1 和 sdd1 属于 set-A 就肯定不是互为镜像的成员了。 第 2 个阵列的 sdb2 和 sdd2 因为不能同时标记损坏并移除,那么就应该是互为镜像的成员(不过我没有看到这方面的权威文档,如果有问题的话希望告诉我一下)。这样,如果磁盘 sdb 和 sdd 同时损坏,第 1 个阵列数据没事,而第 2 个阵列数据就丢掉了。所以,RAID10 创建命令中阵列设备的顺序也是有意义的。

四、删除陈列:

这里以删除第 1 个阵列为例。

1、卸载其上的文件系统

sudo umount /mnt/tmp -v

2、删除阵列

先停止并删除阵列,然后把阵列包含设备的存储阵列信息的 superblock 擦除掉,命令如下:

sudo lsblk --fs /dev/sdb /dev/sdc /dev/sdd /dev/sde # 查看阵列组件信息
sudo mdadm --stop /dev/md/r10a1
sudo mdadm --zero-superblock /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1
sudo lsblk --fs /dev/sdb /dev/sdc /dev/sdd /dev/sde # 再次查看阵列组件信息

3、删除 /etc/mdadm/mdadm.conf 中相应的配置信息并更新 initramfs 映像文件

sudo vim /etc/mdadm/mdadm.conf 删除相应的配置信息,即把包含阵列的 ARRAY 开头行注释掉就行。

sudo update-initramfs -u

五、阵列不能取代数据备份

阵列只能预防磁盘故障导致数据丢失,但不能保证数据是否一定完备正确。比如,由于操作系统或软件故障,导致产生了损坏的数据,而这种损坏的数据会被镜像到相应的磁盘中。数据备份不一样,它可以在时间上和空间上与原存储数据隔离,使备份的数据保证完备正确。除非你有意或无意备份了错误的数据。

六、参考资料

1、How To Configure RAID Arrays on Ubuntu 16.04 https://www.digitalocean.com/community/tutorial_series/how-to-configure-raid-arrays-on-ubuntu-16-04

2、Linux software RAID 10 layouts performance: near, far and offset benchmark analysis https://www.ilsistemista.net/index.php/linux-a-unix/35-linux-software-raid-10-layouts-performance-near-far-and-offset-benchmark-analysis.html

3、RAID 10 & Why Should I Use It? https://www.acronis.com/en-us/articles/whats-raid10-and-why-should-i-use-it

后记:如有任何不当之处,敬请批评与指正,谢谢。

发表评论

电子邮件地址不会被公开。 必填项已用*标注