今天在 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
后记:如有任何不当之处,敬请批评与指正,谢谢。