Raid——软件磁盘阵列
1. 软件磁盘阵列(Software RAID)
Q:
什么是RAID?
RAID机制的功能是什么?
有哪些等级?
什么是硬件、软件磁盘阵列?
Linux支持什么样的软件磁盘阵列?
1.1 什么是RAID
磁盘阵列全名是[ Redundant Arrays of Inexpensive Disks, RAID],英翻的意思是:容错式廉价磁盘阵列。RAID可以透过一个技术(软件或硬件),将多个较小的磁盘整合成为一个较大的磁盘装置;而这个较大的磁盘功能不止是存储,他还具有数据保护的功能。整个RAID由于选择的等级(level)不同,而使得整合后的磁盘具有不同的功能,基本常见的level有以下几种:
-
RAID-0(等量模式,stripe):效能最佳
这种模式如果使用相同型号与容量的磁盘来组成时,效果较佳。这种模式的RAID会将磁盘先切出等量的区块(名为chumk,一般可设定4K~1M之间),然后当一个文件要写入RAID时,该文件会依据chunk的大小切割好,之后再依序放到各个磁盘里面去。由于每个磁盘会交错的存放数据,因此当数据要写入RAID时,数据会被等量的放置在各个磁盘上面。举例来说,有两个磁盘组成RAID-0,当有100MB的数据要写入时,每个磁盘会被分配到50MB的储存量。RAID-0的示意图如下:
上图的意思是,在组成RAID-0时,每个磁盘(Disk A 与 Disk B)都会先被区隔成为小区块(chunk).
当有数据要写入RAID时,资料会先被切割成符合小区块的大小,然后再依序一个一个的放置到不同的磁盘去。由于数据已经先被切割并且依次放置到不同的磁盘上面,因此每个磁盘所复制的数据量都降低了,这种情况来看,越多磁盘组成的RAID-0效能会越好,因为每颗负责的资料量都降低了,资料可以分散让多颗磁盘来储存,效能会更好,磁盘的总容量也会变大,每个磁盘的容量加起来是RAID-0的总容量。
缺点:使用RAID-0,要自行负担数据毁坏的风险,文件是被切割成为适合每颗磁盘分区区块的大小,再依序放置到各个磁盘中,如果某一个磁盘损坏了,文件数据就少了一部分,这个文件就损毁了。由于每个文件都是这样存放的,因此RAID-0 只要有任何一颗磁盘损坏,在RAID上面的所有数据都会遗失而无法读取。
另外,如果使用不同容量的磁盘来组成 RAID-0 时,由于数据是一直等量的依序放置到不同磁盘中,当小容量磁盘的区块被用完了,那么所有的数据都将被写入到最大的那颗磁盘去。举例说明:使用200G与500G组成 RAID-0 ,那么最初的400GB数据可同时写入两颗磁盘(各消耗 200G 的容量),后来再加入的数据就只能写入500G的磁盘中。此时的效能就变差了。
-
RAID-1(映像模式,mirror):完整备份
这种模式也是需要相同的磁盘容量,最好是一模一样的磁盘。如果是不同容量的磁盘组成RAID-1时,那么总容量将以最小的那一颗磁盘为主!这种模式主要是让同一份数据,完整的保存在两个磁盘上。举例说,如果有一个100MB的文件,有一个两个磁盘组成的 RAID-1 时,那么这两个磁盘将会同步写入100MB到储存空间去。因此,整体的RAID的同类几乎少了 50%。 由于两个磁盘的内容一样,也成RAID-1 为 mirror 模式。
如上图所示,一份数据传送到 RAID-1 之后会分别写入到各个磁盘里去。由于同一份数据会被分别写入到其他不同磁盘,因此如果要写入100MB时,数据传送到I/O总线后会被复制多份到各个磁盘,结果就是数据量感觉变大了,因此在大量写入 RAID-1 的情况下,写入的效能可能会变得非常差。如果使用的是硬件RAID(磁盘阵列卡)时,磁盘阵列卡会主动的复制一份而不使用系统的 I/O 总线,效能方面则还可以。如果使用软件磁盘阵列,可能效能就不好了。
由于两个磁盘内的数据一模一样,所以任何一颗磁盘损坏时,资料还是可以完整保留下来的。RAID-1 最大的优点大概在于数据的备份,不过由于磁盘容量有一半用在备份,因此总容量会是全部磁盘容量的一半而已。RAID-1的写入效能不佳,读取的效能还可以,因为数据有两份在不同的磁盘商量,多个processes 在读取同一笔数据时,RAID会自行取得最佳的读取平衡。
-
RAID 1+0,RAID 0+1
RAID-0 效能佳但是数据不安全,RAID-1 数据安全但是效能不佳,能不能将两者整合起来设定 RAID 呢? 由此引出 RAID-0 、RAID-1。
所谓RAID 1+0 就是:
(1)先让两个磁盘组成RAID-1,并且这样的设定有两组
(2)将这两组RAID-1,再组成一组RAID-0.
以上就是 RAID 1+0,反过来就是 RAID 0+1
如上图所示,Disk A + Disk B组成第一组 RAID 1,Disk C + Disk D组成第二组RAID 1,然后这两组再整合成为一组 RAID 0。如果我有 100MB 的数据要写入,由于RAID 0的关系,两组RAID 1都会写入50MB,又由于 RAID 1的关系,每个磁盘都会写入50MB,如此一来,不论哪一组 RAID 1的磁盘损毁,由于是RAID1的影响数据,因此不会有任何问题发送,这也是目前储存设备厂商最推荐的方法。
-
RAID-5
RAID-5 至少需要三颗以上的磁盘才能够组成这种类型的磁盘阵列。这种磁盘阵列的数据写入有点类似 RAID-0 ,不过每个循环的写入过程中(striping),在每个磁盘还加入一个同位检查数据(Parity),这个数据会记录其他磁盘的备份数据,用于当有磁盘损坏时的救援。图示如下
如上图所示,每个循环写入时,都会有部分的同位检查码(Parity)被记录起来,并且记录的同位检查码都记录在不同的磁盘,因此,任何一个磁盘损毁时都能够藉由其他磁盘的健康码来重建原本磁盘内的数据。需要注意的是,由于有同位检查码,因此RAID5的总容量会是整体磁盘数量减一颗。RAID-5 仅能支持一个磁盘损毁的情况。RAID-6用两个磁盘做为 Parity 的存储,整体允许两个磁盘损毁,也可以保证数据没问题。
-
Spare Disk: 预备磁盘的功能:
当磁盘阵列的磁盘损毁时们就要将坏掉的磁盘拔除,然后换一个新的磁盘。换成新磁盘并且顺利启动磁盘阵列后,磁盘阵列就会开始主动的重建(rebuild)原本坏掉的那颗磁盘数据到新的磁盘上,然后磁盘阵列上面的数据就复原了,这是磁盘阵列的有点。不过还是需要动手拔插硬盘,除非系统支持拔插,否则通常得要关机才能这么做。
为了让系统可以实时的在坏掉硬盘时主动的重建,因此就需要预备磁盘(spare disk) 的辅助。所谓的spare disk 就是一个或多个没有包含在原本磁盘阵列等级中的磁盘,这个磁盘平时并不会被磁盘阵列所使用。当磁盘阵列有任何磁盘损坏时,则这个spare disk 会被主动的拉进磁盘阵列中,若磁盘阵列支持热拔插,直接将坏掉的那个磁盘换一个新的,再将那个新的设定为spare disk ,就完成了
-
磁盘阵列的优点
- 数据安全与可靠性:磁盘损毁时,数据是否还能够安全的救援或使用
- 读写效能:例如RAID 0 可以加强读写效能,让系统I/O部分得以改善
- 容量:可以让多颗磁盘组合起来,故单一文件系统可以有相当大的容量
1.2 software,hardware RAID
硬件磁盘阵列是透过磁盘阵列卡来达成数组的目的。磁盘阵列卡上有一块专门的芯片在处理RAID的任务,因此在效能方面会比较好,在很多任务磁盘阵列不会消耗本系统的 I/O 总线,理论上效能会较佳。此外目前一般的高阶磁盘阵列卡都支持热拔插,不关机的情况下抽换损坏的磁盘,对于系统的复原与数据的可靠性方面非常的好用。
软件磁盘阵列主要是透过软件来仿真数组的任务,因此会损耗较多的系统资源,比如说CPU的运算与 I/O总线的资源等
CentOS 提供的软件磁盘阵列为 mdadm 这套软件,这套软件会以 partition 或 disk 为磁盘的单位,也就是说,不需要两个以上的磁盘,只要有两个以上的分区槽(partition)就能够设计磁盘阵列。mdadm 支持前面提到的 RAID0/1/5/spare disk等。而且提供的管理机制可以达到类似热拔插的功能,可以在线进行分区槽的抽换。
硬件磁盘阵列在Linux底下看起来是一个实际的大磁盘,硬件磁盘阵列的装置文件名为 /dev/sd[a-p] ,因为使用到SCSI的模块。
软件磁盘阵列是系统仿真的,使用的装置文件名是系统的装置文件,文件名为/dev/md0,/dev/md1 两者的装置文件名不相同
1.3 软件磁盘阵列的设定
演示环境:kylin:release V10 (SP1) /(Tercel)-x86_64-Build19/20210319
软件磁盘阵列的设定需要使用指令mdadm,raid的语法大概如下
[root@localhost ~]# mdadm --detail /dev/md0
[root@localhost ~]# mdadm --create /dev/md[0-9] --auto=yes --level=[015] --chunk=NK --raid-devices=N --spare-devices=N /dev/sdx /dev/sdx
选项与参数:
--create : 建立RAID选项
--auto=yes : 决定建立后面接的软件磁盘阵列装置
--chunk=NK : 决定这个装置的chunk大小,一般是64K 或512K
--raid-devices=N: 使用几个磁盘(partition) 作为磁盘阵列的装置
--spare-devices=N: 使用几个磁盘作为备用(spare)装置
--level=[015] : 设定这组磁盘阵列的等级。支持很多,建议使用 0 1 5 即可
--detail : 后面所接的磁盘装置的详细信息
以上语法中,最后面会接许多的装置文件名,这些装置文件名可以是整个磁盘,例如/dev/sdb,也可以使分区槽,例如 /dev/sdb1之类的。不过,这些装置文件名的总数必须要等于 --raid-devices 与 --spare-devices 的个数总和才行。
1.3.1 建立 RAID5 :
RAID5环境:
- 4个partition 组成RAID 5;
- 每个 partition 约为 1G
- 利用一个partition 设定为spare disk
- chunk 设定为256k
- spare disk 大小与其他 RAID 所需的 partition 一样
- 此 RAID 5 挂载到 /srv/raid目录下
首先先建好分区:
sdb13567 为五个partition
以mdadm 建立 RAID
[root@localhost ~]# mdadm --create /dev/md0 --auto=yes --level=5 --chunk=256K --raid-devices=4 --spare-devices=1 /dev/sdb1 /dev/sdb3 /dev/sdb5 /dev/sdb6 /dev/sdb7
mdadm: Defaulting to version 1.2 metadata
mdadm: array /dev/md0 started.
[root@localhost ~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Wed Sep 8 18:25:42 2021
Raid Level : raid5
Array Size : 3139584 (2.99 GiB 3.21 GB)
Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
Raid Devices : 4
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Wed Sep 8 18:25:50 2021
State : clean
Active Devices : 4
Working Devices : 5
Failed Devices : 0
Spare Devices : 1
Layout : left-symmetric
Chunk Size : 256K
Consistency Policy : resync
Name : localhost.localdomain:0 (local to host localhost.localdomain)
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
Events : 18
Number Major Minor RaidDevice State
0 8 17 0 active sync /dev/sdb1
1 8 19 1 active sync /dev/sdb3
2 8 21 2 active sync /dev/sdb5
5 8 22 3 active sync /dev/sdb6
4 8 23 - spare /dev/sdb7
也可以用以下命令查看系统软件磁盘阵列的情况:
[root@localhost ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
md0 : active raid5 sdb6[5] sdb7[4](S) sdb5[2] sdb3[1] sdb1[0]
3139584 blocks super 1.2 level 5, 256k chunk, algorithm 2 [4/4] [UUUU]
unused devices: <none>
1.3.2 格式化与挂载使用RAID
参数情况
-
stripe(chunk)容量为256K,所以 su = 256k
-
共有 4 个part组成 RAID5,因此容量少一个,sw=3
-
由上面两项计算出数据宽度为: 256K*3=768K
整体来讲,优化这个XFS 文件系统如下:
[root@localhost ~]# mkfs.xfs -f -d su=256k,sw=3 -r extsize=768k /dev/md0 meta-data=/dev/md0 isize=512 agcount=8, agsize=98048 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=1, sparse=1, rmapbt=0 = reflink=1 data = bsize=4096 blocks=784384, imaxpct=25 = sunit=64 swidth=192 blks naming =version 2 bsize=4096 ascii-ci=0, ftype=1 log =internal log bsize=4096 blocks=5184, version=2 = sectsz=512 sunit=64 blks, lazy-count=1 realtime =none extsz=786432 blocks=0, rtextents=0 [root@localhost ~]# mkdir /srv/raid [root@localhost ~]# mount /dev/md0 /srv/raid [root@localhost ~]# df -Th /srv/raid/ 文件系统 类型 容量 已用 可用 已用% 挂载点 /dev/md0 xfs 3.0G 54M 3.0G 2% /srv/raid
1.4 仿真RAID错误的救援模式
相关语法:
[root@localhost ~]# mdadm --manage /dev/md0[0-9] [--add 装置] [--remove 装置] [--fail 装置]
--add: 会将后面的装置加入到这个md中
--remove: 会将后面的装置从这个md中移除
--fail: 会将后面的装置设定成为出错的状态
1.4.1 设定磁盘为错误 (fault)
首先,先处理一下,该如何让一个磁盘变成错误,然后让 spare disk 自动开始重建系统
# 0.复制一些文件到/srv/raid 中,模拟RAID已经在使用
[root@localhost ~]# cp -a /etc /var/log /srv/raid
[root@localhost ~]# df -Th /srv/raid/; du -sm /srv/raid/*
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/md0 xfs 3.0G 96M 2.9G 4% /srv/raid
28 /srv/raid/etc
7 /srv/raid/log
# 1.设定/sdb/sdb3装置出错
[root@localhost ~]# mdadm --manage /dev/md0 --fail /dev/sdb3
mdadm: set /dev/sdb3 faulty in /dev/md0
[root@localhost ~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Wed Sep 8 18:25:42 2021
Raid Level : raid5
Array Size : 3139584 (2.99 GiB 3.21 GB)
Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
Raid Devices : 4
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Wed Sep 8 18:49:43 2021
State : clean
Active Devices : 4
Working Devices : 4
Failed Devices : 1
Spare Devices : 0
Layout : left-symmetric
Chunk Size : 256K
Consistency Policy : resync
Name : localhost.localdomain:0 (local to host localhost.localdomain)
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
Events : 37
Number Major Minor RaidDevice State
0 8 17 0 active sync /dev/sdb1
4 8 23 1 active sync /dev/sdb7
2 8 21 2 active sync /dev/sdb5
5 8 22 3 active sync /dev/sdb6
1 8 19 - faulty /dev/sdb3
可以看到 /dev/sdb3 出错了,spare disk 已经在使用中了
1.4.2 将出错的磁盘移除并加入新磁盘
- 先从/dev/md0 数组中移除 /dev/sdb3 这个(磁盘)
- 整个Linux 系统关机,拔除 /dev/sdb3 这个(磁盘),并安装上新的 /dev/sdb3(磁盘),之后开机
- 将新的 /dev/sdb3 放入到 /dev/md0 数组中
# 3. 拔除旧的 /dev/sdb3 磁盘
[root@localhost ~]# mdadm --manage /dev/md0 --remove /dev/sdb3
mdadm: hot removed /dev/sdb3 from /dev/md0
# 4. 安装新的 /dev/sdb3 磁盘
[root@localhost ~]# mdadm --manage /dev/md0 --add /dev/sdb3
mdadm: added /dev/sdb3
[root@localhost ~]# mdadm --detail /dev/md0
/dev/md0:
Version : 1.2
Creation Time : Wed Sep 8 18:25:42 2021
Raid Level : raid5
Array Size : 3139584 (2.99 GiB 3.21 GB)
Used Dev Size : 1046528 (1022.00 MiB 1071.64 MB)
Raid Devices : 4
Total Devices : 5
Persistence : Superblock is persistent
Update Time : Wed Sep 8 18:58:08 2021
State : clean
Active Devices : 4
Working Devices : 5
Failed Devices : 0
Spare Devices : 1
Layout : left-symmetric
Chunk Size : 256K
Consistency Policy : resync
Name : localhost.localdomain:0 (local to host localhost.localdomain)
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
Events : 39
Number Major Minor RaidDevice State
0 8 17 0 active sync /dev/sdb1
4 8 23 1 active sync /dev/sdb7
2 8 21 2 active sync /dev/sdb5
5 8 22 3 active sync /dev/sdb6
6 8 19 - spare /dev/sdb3
可以看到/dev/sdb3 的状态编程了 spare
1.5 开机自启动 RAID 并自动挂载
新的distribution 大多会自己搜寻 /dev/md[0-9] 然后在开机的时候给予设定好所需要的功能,不过建议还是修改一下配置文件。software RAID的配置文件在/etc/mdadm.conf
,只需要知道 /dev/md0的UUID就能够设定这个文件。
# 查看UUID
[root@localhost ~]# mdadm --detail /dev/md0 | grep -i uuid
UUID : 4e7b3d01:2e6ff0f6:9743a623:0f7fa446
# 设定mdadm.conf
[root@localhost ~]# vim /etc/mdadm.conf
ARRAY /dev/md0 UUID=4e7b3d01:2e6ff0f6:9743a623:0f7fa446
# 开始设定开机自动挂载并测试
[root@localhost ~]# blkid /dev/md0
/dev/md0: UUID="7c3c9a5e-2e3f-4b3a-91e9-b3031600b2d5" BLOCK_SIZE="512" TYPE="xfs"
[root@localhost ~]# echo "UUID=7c3c9a5e-2e3f-4b3a-91e9-b3031600b2d5 /srv/raid xfs defaults 0 0" >> /etc/fstab
[root@localhost ~]# umount /dev/md0 ; mount -a
[root@localhost ~]# df -Th /srv/raid/
文件系统 类型 容量 已用 可用 已用% 挂载点
/dev/md0 xfs 3.0G 90M 2.9G 3% /srv/raid
# 要确定可以顺利挂载,并且没有发生任何错误
重启系统测试;
1.6 关闭软件 RAID(重要)
如果不使用这个/dev/md0
,需要关掉RAID,如果只是将/dev/md0卸除,然后忘记将RAID关闭,在未来重新分区/dev/sdbX时,可能出现一些莫名的错误状况,所以需要关闭RAID。以下是关闭步骤。
# 1.卸载且删除配置文件内与 /dev/md0有关的设定
[root@localhost ~]# umount /srv/raid
[root@localhost ~]# vim /etc/fstab
****
# 2. 覆盖掉 RAID 的 metadata 以及 XFS 的superblock
[root@localhost ~]# dd if=/dev/zero of=/dev/md0 bs=1M count=50
记录了50+0 的读入
记录了50+0 的写出
52428800字节(52 MB,50 MiB)已复制,0.174493 s,300 MB/s
[root@localhost ~]# mdadm --stop /dev/md0
mdadm: stopped /dev/md0
# 以上就关闭了
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb1 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb3 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb5 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb6 bs=1M
[root@localhost ~]# dd if=/dev/zero of=/dev/sdb7 bs=1M
# 查看状态 确实关闭了
[root@localhost ~]# cat /proc/mdstat
Personalities : [raid6] [raid5] [raid4]
unused devices: <none>
[root@localhost ~]# vim /etc/mdadm.conf
# 注释掉内容或删掉
RAID的相关数据会存一份在磁盘中,只是将配置文件移除,同时关闭RAID,但是分区槽并没有重新规划过,那么重新启动过后,系统还是会将这个RAID建立起来,只是名称会变成 /dev/md127,因此移除掉 software RAID时,上述的dd指令要执行,也不要dd到错误的磁盘。
本次模拟raid-5,采用的一个磁盘中的不同part,实际使用中最好还是使用不同的磁盘,才能使用到不同磁盘的读写,效能才更好,磁盘损坏时也能从其他磁盘挽救回来。
参考:
[1] 鸟哥.鸟哥的Linux私房菜[M]