Linux Software RAID实践

在计算机术语中,RAID(Redundant Array of Independent Disks,独立磁盘冗余数组)的基本思想就是把多个相对便宜的硬盘组合起来,成为一个磁盘数组,使性能达到甚至超过一个价格昂贵、容量巨大的硬盘.
        根据选择的版本不同,RAID比单颗硬盘有以下一个或多个方面的好处:
                增强数据集成度
                增强容错功能
                增加处理量或容量
        另外,磁盘数组组对于计算机来说,看起来就像一个单独的硬盘或逻辑存储单元.简单来说,RAID把多个硬盘组合成为一个逻辑磁区,因此,操作系统只会把它当作一个硬盘.RAID常被用在服务器计算机上,并且常使用完全相同的硬盘作为组合.由于硬盘价格的不断下降与RAID功能更加有效地与主板集成,它也成为了玩家的一个选择,特别是需要大容量储存空间的工作,如:视频与音频制作.

常用RAID的等级介绍
        为了各自的特定应用,所需要的磁盘的组合方式也有所不同,通常我们将这种组合方式称为RAID等级.常用的RAID等级如下:
        RAID0(Stripping,条带)
        将多个磁盘合并成一个大的磁盘,不具有冗余,并行I/O,速度最快.RAID0亦称为带区集.它是将多个磁盘并列起来,成为一个大磁盘.在存放数据时,其将数据按磁盘的个数来进行分段,然后同时将这些数据写进这些盘中.所以,在所有的级别中,RAID0的速度是最快的.但是RAID0没有冗余功能,如果一个磁盘(物理)损坏,则所有的数据都会丢失.
        理论上越多的磁盘效能就等于[单一磁盘效能]x[磁盘数],但实际上受限于总线I/O瓶颈及其它因素的影响,RAID效能会随边际递减,也就是说,假设一个磁盘的效能是50MB/秒,两个磁盘的RAID0效能约96MB/秒,三个磁盘的RAID0也许是130MB/秒而不是150MB/秒.所以,两个磁盘的RAID0最能明显感受到效能的提升.
                Size = 2 * min(S1, S2)
        但如果是以软件方式来实现RAID,则磁盘的空间则不见得受限于此(例如Linux Software RAID),通过软件实现可以经由不同的组合而善用所有的磁盘空间.
                Size = sum of all disk
 
        RAID1(Mirror,镜像)
        两组以上的N个磁盘相互作镜像,速度没有提高,除非拥有相同数据的主磁盘与镜像同时损坏,否则数据不会丢失,可靠性最高.其原理为在主硬盘上存放数据的同时也在镜像硬盘上写一样的数据.当主硬盘(物理)损坏时,镜像硬盘则代替主硬盘的工作.因为有镜像硬盘做数据备份,所以RAID1的数据安全性在所有的RAID级别上来说是最好的.但无论用多少磁盘做RAID1,仅算一个磁盘的容量,是所有RAID上磁盘利用率最低的一个级别.
                Size = 2 * min(S1, S2)
 
        RAID5(分布奇偶位条带)
        RAID5是一种存储性能,数据安全和存储成本兼顾的存储解决方案.它使用的是Disk Striping(硬盘分割)技术.RAID5至少需要三颗硬盘,RAID 5不对存储的数据进行备份,而是把数据和相对应的奇偶校验信息存储到组成RAID5的各个磁盘上,并且奇偶校验信息和相对应的数据分别存储于不同的磁盘上.当RAID5的一个磁盘数据发生损坏后,利用剩下的数据和相应的奇偶校验信息去恢复被损坏的数据. RAID5可以理解为是RAID0和RAID1的折衷方案.RAID5可以为系统提供数据安全保障,但保障程度要比镜像低而磁盘空间利用率要比镜像高.RAID5具有和RAID0相近似的数据读取速度,只是多了一个奇偶校验信息.写入数据的速度相当的慢,若使用"回写高速缓存"可以让效能改善不少.同时由于多个数据对应一个奇偶校验信息,RAID5的磁盘空间利用率要比RAID1高,存储成本相对较便宜.
        Size = (N - 1) * min(S1, S2, ...Sn)
 
        RAID10/01
        RAID10/01其实可细分为RAID1+0或RAID0+1.
        RAID1+0(镜像阵列条带)是先镜射再分割数据.是将所有硬盘分为两组,视为是RAID0的最低组合,然后将这两组各自视为RAID1运作.RAID1+0有着不错的读取速度,而且拥有比RAID0更高的数据保护性.
        RAID0+1则是跟RAID1+0的程序相反,是先分割再将数据镜射到两组硬盘.它将所有的硬盘分为两组,变成RAID1的最低组合,而将两组硬盘各自视为RAID0运作.RAID0+1比起RAID1+0有着更快的读写速度,不过也多了一些会让整个硬盘组停止运转的机率;因为只要同一组的硬盘全部损毁,RAID0+1就会停止运作,而RAID1+0则可以在牺牲RAID0的优势下正常运作.
        RAID10巧妙的利用了RAID0的速度以及RAID1的保护两种特性,不过它的缺点是需要的硬盘数较多,因为至少必须拥有四个以上的偶数硬盘才能使用.

Linux Software RAID实践
        在Linux系统中目前以MD(Multiple Devices)虚拟块设备的方式实现软件RAID,利用多个底层的块设备虚拟出一个新的虚拟块设备,并且利用条带化(stripping)技术将数据块均匀分布到多个磁盘上来提高虚拟设备的读写性能,利用不同的数据冗余算法来保护用户数据不会因为某个块设备的故障而完全丢失,而且还能在设备被替换后将丢失的数据恢复到新的设备上.软RAID阵列实际上可以使用任何标准的块设备作为底层设备,如SCSI设备,IDE设备,RAM disk磁盘和NBD(Network Block Device)等,甚至是其他的MD设备.目前MD支持linear,multipath,raid0(stripping),raid1(mirror),raid4,raid5,raid6,raid10等不同的冗余级别和组成方式,当然也能支持多个RAID阵列的层叠组成raid1+0,raid5+1等类型的阵列.
        RHEL5已经将MD驱动模块直接编译到内核中,我们可以在机器启动后通过cat /proc/mdstat看内核是否已经加载MD驱动或者cat /proc/devices是否有md块设备.
                [root@server ~]# cat /proc/mdstat
                Personalities :
                unused devices: <none>
                [root@server ~]# cat /proc/devices | grep md
                  1 ramdisk
                  9 md
                254 mdp
        在Linux系统中用户层以前使用raidtool工具集来管理MD设备,目前广泛使用mdadm软件来管理MD设备,而且该软件都会集成在Linux的发布版中.mdadm主要有7种使用模式,分别如下:
                --assemble       -A: 将原来属于一个阵列的每个块设备组装为阵列
                --build          -B: 构建没有元数据块的阵列
                --create         -C: 构建一个新阵列,与build的不同之处在于每个设备具有元数据块
                --manage           : 管理已经存储阵列中的设备,比如增加热备磁盘或者删除磁盘
                --misc             : 报告或者修改阵列中相关设备的信息,比如查询阵列或者设备的状态信息
                --monitor        -F: 监控一个或多个阵列,上报指定的事件
                --grow           -G: 改变阵列中每个设备被使用的容量或阵列中的设备的数目
        在RHEL5中可以直接使用YUM来安装mdadm软件包,也可以从安装光盘上找到该软件包用RPM安装.
                [root@server ~]# mdadm --version
                mdadm - v2.6.4 - 19th October 2007
        安装好后,就可以开始今天的试验了.
 
        1.准备源盘
        我们先在虚拟机下虚拟9块SCSI硬盘.
                RAID0:  sdb    sdc
                RAID1:  sdd    sde    sdf
                RAID5:  sdg    sdh    sdi    sdj
        新建一文件answer,内容如下:
                n
                p
                1

                t
                FD
                w
        然后执行如下操作:
                [root@server ~]# for i in b c d e f g h i j; do fdisk /dev/sd$i < answer; done
                [root@server ~]# fdisk -l | grep 'Linux raid autodetect'
                /dev/sdb1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sdc1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sdd1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sde1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sdf1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sdg1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sdh1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sdi1               1        1044     8385898+  fd  Linux raid autodetect
                /dev/sdj1               1        1044     8385898+  fd  Linux raid autodetect
        以上操作确保把每个盘分区,再设置为FD的磁盘.
 
        2.创建新的阵列
        用sdb1,sdc1创建RAID0
                mdadm --create /dev/md0 --level=0 --chunk=32 --raid-devices=2 /dev/sd[bc]1
                选项解释:
                        --level=,-l:指定raid的级别,可选的值为0,1,4,5,6,linear,multipath和synonyms
                        --chunk=,-c:指定条带数据块的大小,以K为单位.默认为64K,条带单元的大小配置对不同负载的阵列读写性能有很大影响
                        --raid-devices=,-n:指定活动磁盘的数量
                以上命令也可写作:mdadm -C /dev/md0 -l0 -c32 -n2 /dev/sdb[bc]1
        用sdd1,sde1,sdf1创建RAID1
                mdadm --create /dev/md1 --level=1 --raid-devices=2 --spare-devices=1 /dev/sd[d-f]1
                选项解释:
                        --spare-devices=,-x:表示阵列中热备盘的个数,一旦阵列中的某个磁盘失效,MD内核驱动程序自动用将热备磁盘加入到阵列,然后重构丢失磁盘上的数据到热备磁盘上.
                以上命令也可写作:mdadm -C /dev/md1 -l1 -n2 -x1 /dev/sd[d-f]1
        用sdg1,sdh1,sdi1,sdj1创建RAID5
                mdadm --create /dev/md2 --level=5 --raid-devices=3 /dev/sd[g-i]1 --spare-devices=1 /dev/sdj1
                以上命令也可写作:mdadm -C /dev/md2 -l5 -n3 /dev/sd[g-i]1 -x1 /dev/sdj1
        此外还可以参考如下命令,创建一个RAID1+0设备
                mdadm -C /dev/md0 -l1 -n2 /dev/sd[bc]1
                mdadm -C /dev/md1 -l1 -n2 /dev/sd[de]1
                mdadm -C /dev/md2 -l1 -n2 /dev/sd[fg]1
                mdadm -C /dev/md3 -l0 -n3 /dev/md[0-2]
        当RAID1/4/5/6/10等创建成功后,需要计算每个条带的校验和信息并写入到相应磁盘上,使用cat /proc/mdstat信息查询RAID阵列当前状态,重构的速度和预期的完成时间.
                [root@server ~]# cat /proc/mdstat
                Personalities : [raid0] [raid1] [raid6] [raid5] [raid4]
                md2 : active raid5 sdi1[4] sdj1[3](S) sdh1[1] sdg1[0]
                      16771584 blocks level 5, 64k chunk, algorithm 2 [3/2] [UU_]
                      [>....................]  recovery =  1.9% (167760/8385792) finish=9.7min speed=13980K/sec
               
                md1 : active raid1 sdf1[2](S) sde1[1] sdd1[0]
                      8385792 blocks [2/2] [UU]
               
                md0 : active raid0 sdc1[1] sdb1[0]
                      16771584 blocks 32k chunks
               
                unused devices: <none>
 
        3.管理阵列
        mdadm可以在manage模式下,对阵列进行管理.最常用的操作是标识损坏的磁盘,增加热备磁盘,以及从阵列中移走失效的磁盘等等.
        使用--fail(或者其缩写-f)指定磁盘损坏.
                [root@server ~]# cat /proc/mdstat
                Personalities : [raid6] [raid5] [raid4] [raid1] [raid0]
                md2 : active raid5 sdj1[3](S) sdi1[2] sdh1[1] sdg1[0]
                      16771584 blocks level 5, 64k chunk, algorithm 2 [3/3] [UUU]
                [root@server ~]# mdadm /dev/md2 --fail /dev/sdh1
                mdadm: set /dev/sdh1 faulty in /dev/md2
                [root@server ~]# cat /proc/mdstat
                Personalities : [raid6] [raid5] [raid4] [raid1] [raid0]
                md2 : active raid5 sdj1[3] sdi1[2] sdh1[4](F) sdg1[0]
                      16771584 blocks level 5, 64k chunk, algorithm 2 [3/2] [U_U]
                      [>....................]  recovery =  0.8% (74172/8385792) finish=7.4min speed=18543K/sec
         第一次查看状态时,sdj1是热备盘,当我们指定sdh1损坏后,系统自动将数据重构到热备盘sdj1上,在重构过程中,状态是U_U.
         用--remove命令可以将损坏的磁盘移走.
                  [root@server ~]# mdadm /dev/md2 --remove /dev/sdh1
                  mdadm: hot removed /dev/sdh1
         此时查看状态时,已经只有三个盘了,没有备用的热备盘.
                  [root@server ~]# cat /proc/mdstat
                  Personalities : [raid6] [raid5] [raid4] [raid1] [raid0]
                  md2 : active raid5 sdj1[1] sdi1[2] sdg1[0]
                        16771584 blocks level 5, 64k chunk, algorithm 2 [3/3] [UUU]
         当我们的损坏的磁盘经过处理后,可以将其添加到阵列中作热备盘.
         用--add命令可以添加热备盘.
                  [root@server ~]# mdadm /dev/md2 --add /dev/sdh1
                  mdadm: added /dev/sdh1
                  [root@server ~]# cat /proc/mdstat
                  Personalities : [raid6] [raid5] [raid4] [raid1] [raid0]
                  md2 : active raid5 sdh1[3](S) sdj1[1] sdi1[2] sdg1[0]
                        16771584 blocks level 5, 64k chunk, algorithm 2 [3/3] [UUU]
         此外还可以用--grow命令增加可用的活动磁盘.
                  [root@server ~]#mdadm --grow /dev/md0 --raid-disks=4
 
        4.使用阵列
        新建三个挂载点:
                [root@server ]# mkdir /mnt/MD0
                [root@server ]# mkdir /mnt/MD1
                [root@server ]# mkdir /mnt/MD2
        对RAID设备做文件系统格式化:
                [root@server ]# mkfs.ext3 /dev/md0
                [root@server ]# mkfs.ext3 /dev/md1
                [root@server ]# mkfs.ext3 /dev/md2
        挂载:
                [root@server ]# mount /dev/md0 /mnt/MD0
                [root@server ]# mount /dev/md1 /mnt/MD1
                [root@server ]# mount /dev/md2 /mnt/MD2
        查看效果:
                [root@server ]# df -h
                ......
                /dev/md0               16G  173M   15G   2% /mnt/MD0
                /dev/md1              7.9G  147M  7.4G   2% /mnt/MD1
                /dev/md2               16G  173M   15G   2% /mnt/MD2
        现在我们就可以正常使用RAID设备了.
        当我们要停止RAID设备时,需要先将其卸载:
                [root@server ~]# umount /mnt/MD0
        然后再用如下命令停止设备:
                [root@server ~]# mdadm --stop /dev/md0
                mdadm: stopped /dev/md0
        此时再用命令查看发现,已经没有md0了.
                [root@server ~]# cat /proc/mdstat | grep md0
        如果需要再次使用则需要将其"组装起来",由于先前曾创建过,mdadm的assemble模式可检查底层设备的元数据信息,然后再组装为活跃的阵列.
                [root@server ~]# mdadm --assemble /dev/md0 /dev/sd[bc]1
                mdadm: /dev/md0 has been started with 2 drives.
                [root@server ~]# cat /proc/mdstat  | grep md0
                md0 : active raid0 sdb1[0] sdc1[1]
        这样就又可以重新挂载使用了.
 
        5.阵列的元数据应用
        Build模式可以用来创建没有元数据的RAID0/1设备,不能创建RAID4/5/6/10等带有冗余级别的MD设备,而create模式建立的RAID设备都是带有元数据的.以使用命令--examine(-E)来检测当前的块设备上是否有阵列的元数据信息.
                [root@server ~]# mdadm -E /dev/sdh1
                /dev/sdh1:
                          Magic : a92b4efc
                        Version : 00.90.00
                           UUID : cea9dd57:59f61370:00969939:2ef303d5
                  Creation Time : Sun May 17 12:15:50 2009
                     Raid Level : raid5
                  Used Dev Size : 8385792 (8.00 GiB 8.59 GB)
                     Array Size : 16771584 (15.99 GiB 17.17 GB)
                   Raid Devices : 3
                  Total Devices : 4
                Preferred Minor : 2
               
                    Update Time : Sun May 17 13:07:43 2009
                          State : clean
                 Active Devices : 3
                Working Devices : 4
                 Failed Devices : 0
                  Spare Devices : 1
                       Checksum : 95f50002 - correct
                         Events : 0.2
               
                         Layout : left-symmetric
                     Chunk Size : 64K
               
                      Number   Major   Minor   RaidDevice State
                this     1       8      113        1      active sync   /dev/sdh1
               
                   0     0       8       97        0      active sync   /dev/sdg1
                   1     1       8      113        1      active sync   /dev/sdh1
                   2     2       8      129        2      active sync   /dev/sdi1
                   3     3       8      145        3      spare   /dev/sdj1
        从以上信息可以看到sdg1,sdh1,sdi1和sdj1共同组成了一个raid5设备,sdj1做备份盘,该设备创建于2009 12:15:50,条带数据块大小采用了默认值64k.此外还有一个重要的数据那就是UUID,它是阵列的唯一标识,组成同一阵列的相关磁盘上的UUID是相同的.
        可以用以下命令来将具有相同元数据的磁盘重先组装成RAID.
                [root@server ~]# mdadm --assemble -v --uuid=cea9dd57:59f61370:00969939:2ef303d5 /dev/md2 /dev/sd[b-j]1
                mdadm: looking for devices for /dev/md2
                mdadm: /dev/sdb1 has wrong uuid.            --1--
                mdadm: /dev/sdc1 has wrong uuid.
                mdadm: cannot open device /dev/sdd1: Device or resource busy    --2--
                mdadm: /dev/sdd1 has wrong uuid.
                mdadm: cannot open device /dev/sde1: Device or resource busy
                mdadm: /dev/sde1 has wrong uuid.
                mdadm: cannot open device /dev/sdf1: Device or resource busy
                mdadm: /dev/sdf1 has wrong uuid.
                mdadm: /dev/sdg1 is identified as a member of /dev/md2, slot 0.
                mdadm: /dev/sdh1 is identified as a member of /dev/md2, slot 1.
                mdadm: /dev/sdi1 is identified as a member of /dev/md2, slot 2.
                mdadm: /dev/sdj1 is identified as a member of /dev/md2, slot 3.
                mdadm: added /dev/sdh1 to /dev/md2 as 1
                mdadm: added /dev/sdi1 to /dev/md2 as 2
                mdadm: added /dev/sdj1 to /dev/md2 as 3
                mdadm: added /dev/sdg1 to /dev/md2 as 0
                mdadm: /dev/md2 has been started with 3 drives and 1 spare.
        --1--,/dev/sdb1与我们命令中的UUID不匹配.
        --2--,/dev/sdd1正忙,无法获取到相关UUID.
 
        6.RAID的配置文件
        在RHEL5的rc.sysinit配置文件中,有这样一段代码:
                if [ -f /etc/mdadm.conf ]; then
                    /sbin/mdadm -A -s
                fi
        即:如果RAID的配置文件mdadm.conf存在,则调用mdadm检查配置文件里的选项,然后启动RAID阵列.
        所以我们如果要让软RAID的配置在机器下次启动时自动生效的话,得把配置写进配置文件/etc/mdadm.conf,可用下面的命令来完成.
                [root@server ~]# echo DEVICE /dev/sd[b-j]1 > /etc/mdadm.conf
                [root@server ~]# mdadm --detail --scan >> /etc/mdadm.conf
                [root@server ~]# cat /etc/mdadm.conf
                DEVICE /dev/sdb1 /dev/sdc1 /dev/sdd1 /dev/sde1 /dev/sdf1 /dev/sdg1 /dev/sdh1 /dev/sdi1 /dev/sdj1
                ARRAY /dev/md0 level=raid0 num-devices=2 UUID=8d4ebb05:b74a1b15:de9a89ee:b2b3a642
                ARRAY /dev/md1 level=raid1 num-devices=2 spares=1 UUID=fa205b5a:0bb04eff:279165d9:b39ba52d
                ARRAY /dev/md2 level=raid5 num-devices=3 spares=1 UUID=cea9dd57:59f61370:00969939:2ef303d5
        这样我们在下次启动时,RAID就会自动生效了.

相关推荐