大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)

4.2 七种RAID技术详解

        首先需要阐述Stripe的概念。Stripe完全是由程序在内存中虚拟出来的,说白了就是一个map公式。即仿佛给程序戴了一个特殊的眼镜,程序戴上这个眼镜之后,就能看到“条”和“带”,就会知道将数据分布到条带上了,一旦摘下这个眼镜,那么看到的就是普通的物理磁盘扇区。这个眼镜就是实现RAID的程序代码,物理磁盘上只有扇区,没有“条”和“带”。另外程序会在磁盘特定的一些扇区中写入自己运行时需要的信息,比如一些RAID标签信息等。

        如下图所示,就是一个典型的RAID0的系统

大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)

        1.扇区、块、段(Segment)、条带、条带长度和深度

        上图所示的五个竖条,分别代表五个磁盘。然后在磁盘相同偏移处横向逻辑分割,形成Stripe。一个Stripe横跨过的扇区或块的个数或字节容量,就是条带长度,即Stripe Length。而一个Stripe Length所占用的单块磁盘上的区域称之为一个Segment。一个Segment中所包含的data Block或者扇区的个数或者字节容量,称之为Stripe Depth。Data Block可以是N倍个扇区大小的容量,应该可调或者不可调,由控制器而定。

        RAID 0便是将一系列连续编号的Data Block分布到多个物理磁盘上,扩散IO提高性能,其分布的方式如上图所示。这个例子中,条带深度为4,则0、1、2、3号Data Block被放置到第一个条带的第一个Segment中,然后4、5、6、7号Block放置到第一个条带的第二个Segment中,以此类推,条带1被放满之后,继续放条带2。这种特性称为“局部连续”,因为Block只有在一个Segment中是物理连续的,逻辑连续就需要跨物理磁盘了。

        2.关于几个与IO相关的重要概念

        IO可以分为读写IO、大小快IO、连续/随机IO、顺序/并发IO、稳定/突发IO、持续/间断IO和实/虚IO。下面就分别介绍这几种IO。

        (1)读/写IO:读IO就是发出指令从磁盘读取某段序号连续的扇区的内容。指令一般是通过磁盘开始扇区的位置,然后给出需要从这个初始扇区往后读取的连续扇区的个数,同时给出动作是读还是写。磁盘收到这条指令就会按照指令的要求读写数据。控制器发出这种指令加数据并得到对方回执的过程就是一次IO读或者写。注意,一个IO所要提取的扇区段一定是连续的,如果想提取或写入两段不连续的扇区段,只能把他们放入两个IO中分别执行,这也就是为什么随机IO对设备的IOPS指标要求比较高的原因。

        (2)大/小块IO:控制器的指令中给出的连续读取扇区数目的多少。如果数目很大,如128,64等,就应该算是大块IO,如果很小比如1,4,8等,就算小块IO。大块和小块IO之间没有明确的界限。

        (3)连续/随机IO:连续和随机是指本次IO给出的初始扇区地址和上一次IO的结束扇区地址是不是完全连续的或者相隔不多的。如果是,则本次IO应该算是一个连续IO;如果相差太大,则算一次随机IO。连续IO因为本次初始扇区和上次结束扇区相隔很近,则磁头几乎不用换道或者换道时间极短。如果相差很大,则磁头需要很长的换道时间。如果随机IO很多,则会导致频繁换道,效率大大降低。

        (4)顺序/并发IO:磁盘控制器如果可以同时对一个RAID系统中的多块磁盘同时发送IO指令(当然这里的同时是宏观的概念。如果所有磁盘都在一个总线或者环路上,则这里的同时就是指向一块磁盘发送一条指令后不必等他回应,接着向另一块磁盘发送IO指令),并且这些最底层的IO数据包含了文件系统级下发的多个IO数据,则为并发IO。如果这些直接发向磁盘的IO只包含了文件系统级下发的一个IO的数据,则此时为顺序IO。即控制器缓存中的文件系统下发的IO队列,只能一个一个来。并发IO模式在特定的条件下可以很大程度的提高效率和速度。

        (5)持续/间断IO:持续不断地发送或者接受IO请求数据流,这种情况为持续IO;IO数据流时断时续则为间断IO。

        (6)稳定突发IO:某存储设备与某程序在一段时间内接受或者发送的IOPS以及Throughput(吞吐量)保持相对稳定和恒定,则称为稳定IO;如果单位时间的IOPS或者Throughpou突然猛增,则为突发IO。

        (7)实/虚IO:某IO请求中包含对应实际数据地址的,比如磁盘LBA地址,或者文件偏移量,请求读或者写实际文件或者磁盘扇区数据的,称为实IO;而应用程序针对文件元数据操作的(在文件系统层以上没有文件主体数据操作),或者针对磁盘发送的非实体数据IO请求,称为虚IO。

        (8)IO并发几率:单盘,IO的并发几率为0,因为一块磁盘同时只能进行一次IO。对于RAID 0,在两块盘情况下,条带深度比较大的时候(条带太小不能并发IO),并发两个IO的几率为1/2。

        (9)IOPS:完成一次IO所用的时间=寻道时间+旋转延迟时间+数据传输时间,IOPS=IO并发系数/完成一次IO所用的时间。由于寻道时间相对于传输时间要大几个数量级,所以影响IOPS的关键因素就是降低寻道时间。在连续IO情况下,寻道时间很短,仅在换磁道时候需要寻道。在这个前提下,传输时间越少,IOPS就越高。

        (10)每秒IO吞吐量:显然,每秒IO吞吐量=IOPS x 平均IO SIZE。IO SIZE越大,IOPS越高,每秒IO吞吐量也越大。设磁头每秒读写速度为V,V为定值。则IOPS = IO并发系数/(寻道时间+旋转延迟时间+IO SIZE/V)。代入的每秒IO吞吐量 = IO并发系数 x IO SIZE x V/(Vx寻道时间+Vx旋转延迟时间+IO SIZE)。可以看出影响每秒IO吞吐量的最大因素就是IO SIZE和寻道时间以及旋转延迟时间。IO SIZE越大,寻道时间越少,吞吐量越高。相比能显著影响IOPS的因素只有一个,就是寻道时间。

4.2.1 RAID 0技术详析

大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)        

        以上图的“一个典型的RAID 0 系统”为例。对外来说,参与形成RAID 0的各个物理盘会组成一个逻辑上连续、物理上也连续的虚拟磁盘。一级磁盘控制器(指使用这个虚拟磁盘的控制器,如果某台主机使用适配卡链接外部盘阵,则指的就是主机上的磁盘控制器)对这个虚拟磁盘发出的指令,都能被RAID控制器收到并分析处理,根据Block映射关系算法转换成RAID 0的各个物理盘的真实物理磁盘IO请求指令,收集或写入数据之后,再提交给主机磁盘控制器。

        RAID 0还有另一种非条带化模式,即写满其中一块物理磁盘之后,再接着写另一块,知道所有组成的磁盘全部写满。这种模式对IO写没有任何优化,但是对IO读能提高一定的并发IO读几率。

        下面具体分析一个具体从上到下访问RAID 0磁盘的过程。假如某一时刻,主机控制器发出指令,读取 初始扇区 10000 长度128。RAID控制器接收到这个指令之后,立即进行计算,根据对应公式(这个公式是RAID控制器在做逻辑条带化的时候制定的)算出10000号逻辑扇区多对应的物理磁盘的扇区号。依次计算出逻辑上连续的下128个扇区所在物理磁盘的扇区号。分别向对应这些扇区的磁盘再次发出指令。这次是真实的读取数据了,磁盘接收到指令,各自将数据提交给RAID控制器,经过控制器在Cache中的组合,再提交给主机控制器。

        分析以上过程,发现如果这128个扇区都落在同一个Segment中的话,也就是说条带深度容量大于128个扇区的容量(64KB),则这次IO就只能真实的从这一块物理盘上读取,性能和单盘相比会减慢,因为没有任何优化,反而还增加了RAID控制器额外的计算开销。所以,在某种特定条件下要提升性能,让一个IO尽量扩散到多块物理盘上,就要减小条带深度。在磁盘数量不变的条件下,也就是减小条带大小(Stripe SIZE,也就是条带长度)。让这个IO的数据被控制器分割,同时放满一个条带的第一个Segment、第二个Segment等。以此类推,这样就能极大地占用多块物理盘。注意这里的同时,因为控制器把每块磁盘要写入或者读取的数据都计算好了,所以是同时进行读或者写的。

        所以,RAID 0要提升性能,条带需要越小越好。但是又一个矛盾出现了,就是条带太小,导致并发IO几率降低。因为如果条带太小,则每次IO一定会占用大部分物理盘,队列中的IO就只能等待这次IO结束后才能使用物理盘。而条带太大,又不能充分提高传输速度。这两个是一对矛盾,要根据需求来采用不同的方式。如果随机小块IO多,则适当加大条带深度;如果连续大块IO多,则适当减小条带深度。

        下图是原书中作者做的RAID 0系统相对于单盘的IO对比表。(这里的Strip Size=Stripe Depth x Strip Width)

大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)

4.2.2 RAID 1技术详析

        RAID 1用下图的两块盘的例子来说明

大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)

        RAID 1和RAID 0不同,RAID 0对数据没有任何保护措施,每个Block都没有备份或者校验保护措施。RAID 1对虚拟逻辑盘上的每个物理Block都在物理盘上有一个镜像备份,也就是说数据有两份。对于RAID 1的写IO,速度不但没有提升,而且有所下降,因为数据要同时向多块物理磁盘写,时间以最慢的那个为准,因为是同步的。而对于RAID 1的读IO请求,不但可以并发,而且就算顺序IO的时候,控制器也可以像RAID 0一样,从两块物理盘上同时读数据,提升速度。RAID 1可以没有Stripe概念,当然也可以·有,同样也可以总结出下表。

大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)

        在读、并发IO的模式下,由于可以并发N个IO,每个IO占用一个这就相当于提升了N倍的IOPS。由于每个IO只独占了一个物理盘,所以数据传输速度相对于单盘没有改变,所以不管是随机IO还是顺序IO,相对单盘都不变。

        在读、顺序IO、随机IO模式下,由于IO不能并发,所以此时一个IO可以同时读取N个盘上的内容。但是在随机IO模式下,由于IO不能并发,所以此时一个IO可以同时读取N个盘上的内容。但是在随机IO模式下,寻道时间影响很大,纵使同时分块读取多个磁盘的内容,也架不住寻道时间的抵消,所以性能提升极小。

        在读、顺序IO、连续IO模式下,寻道时间影响最低,此时传输速率为主要矛盾,同时读取多块磁盘的数据,时间减少为1/N,所以性能提升了N倍。

        写IO的时候和读IO情况相同,就不做分析了。写IO因为要同时向每块磁盘写入备份数据,所以不能并发IO,也不能分块并行。但是如果控制器把优化算法做到极致的话,还是可以并发IO的。比如控制器从IO队列中提取连续的多个IO,可以将这些IO合并,并发写入磁盘,前提是这几个IO必须是事务性的,也就是说LBA必须连续,不然不能作为一个大的合并IO。而且和文件系统也有关系,文件系统碎片越少,并发几率就越高。

4.2.3 RAID 2技术详解

        RAID2是一种比较特殊的模式,它是一种专用RAID,现在早已被淘汰。它的基本思想是在IO到来之后,控制器将数据按照位分散开,顺序在每块磁盘中存取1b,并非只写入1b。我们知道上层IO可以先经过文件系统,然后才通过磁盘控制器驱动来向磁盘发出IO。最终的IO大小,都是N倍的扇区,也就是Nx512B,N大于等于1,不可能发生N小于1的情况。即使需要的数据只有几个字节,那么也同样要读出或者写入整个扇区,也就是512B。

        明白这个原则之后,再来看一下RAID2中所谓的“每个磁盘写1b”是个什么概念。IO最小单位为扇区(512B),我们就拿一个4块数据盘和3块校验盘的RAID2系统为例给大家说明一下。这个环境中,RAID2的一个条带大小是4b(1bx4块数据盘),而IO最小单位是一个扇区,那么如果分别向每块盘写1b,就需要向每块盘写一个扇区,每个扇区只包含1b有效数据,这显然是不可能的,因为太浪费空间,且没有意义。

        下面以IO请求为例来说明。

        写入“初始扇区10000 长度1”,这个IO的目的是要向LBA10000写入一个扇区的数据,就是512B。 RAID2控制器接收到这512B的数据之后,在Cache中计算需要写入的物理磁盘的信息,比如定位到物理扇区,分割数据成比特。然后一次性写入物理扇区。也就是说第一块物理盘,控制器会写入本次IO数据的第1、5、9、13、17、21等位,第二块物理盘会写入2、6、10、14、18、22等位,其他两位物理盘同样方式写入。直到将这样的数据写完。我们可以计算出这512B的数据写完之后,此时每块物理盘只包含128B的数据,也就是一个扇区的四分之一,那么这个扇区的剩余部分就是空余的。为了利用起这些空间,等下一次IO到来之后,控制器会对数据进行比特分割,将数据填入这些空白区域,控制器将首先读出原来的数据,然后和新的数据合并之后,一并再写回这个扇区,这样做效率和速度都大打折扣。

        其实RAID2就是将原本连续的一个扇区的数据,以位为单位,分割存放到不连续的多块物理盘上,因为这样可以在任意条件下都迫使其全磁盘组并行读写,提高性能,也就是说条带深度为1位。这种极端看上去做的有点做的过火了,这是导致它最终被淘汰的原因之一。

         RAID2系统中的每个物理磁盘扇区其实是包含了N个扇区的“残体”。那么如果出需要更新这4个扇区中某一个扇区的情况怎么办?这种情况下,必须先读出原来的数据,和新数据合并,然后再一并写入。其实这种情况出现的非常少。我们知道上层IO的产生,一般需要先经过OS的文件系统,然后才到磁盘控制器这一层的。所以磁盘控制器产生的IO一般是事务性的,也就是这个IO中所有的扇区很大概率上对于上层文件系统来说是一个完成的事务,所以很少会发生只针对这个事务中某一点进行读写的情况。这样的话,每次IO就有很大几率都会包含入这些逻辑上连续的扇区,所以不必担心经常会发生那种情况。即使发生了,控制器也只能按照那种低效率的做法来做,不过总体影响较小。但是如果随机IO较多,那么这些IO初始LBA,很有可能命中在一两个事务交接的扇区处。这种情况就会导致速度和效率大大降低。连续IO出现这种情况的几率非常小了。

        RAID2因为每次读写都需要全组磁盘联动,所以为了最大化其性能,最好保证每块磁盘主轴同步,使同一时刻每块磁盘磁头所处的扇区逻辑编号都一致,并存并取,达到最佳性能。如果不能同步,则会产生等待,影响速度。

        基于RAID2并存并取的特点,RAID2不能实现并发IO,因为每次IO都还占用了每块物理盘。RAID2的校验盘对系统不产生瓶颈,但是会产生延迟,因为多了计算校验的动作。校验位和数据位是一同并行写入或者读取的。RAID2采用汉明码来校验数据,这种码可以判断修复一位错误的数据,并且使用校验盘的数量太多,4块数据盘需要3块校验盘。但是随着数据盘数量的增多,校验盘所占的比例会显著减少。RAID2与RAID0有些不同,RAID0不能保证每次IO都是多磁盘并行,因为RAID0的条带深度相对于RAID2以位为单位来说是太大了。而RAID2由于每次IO都保证是多磁盘并行,所以其数据传输率是单盘的N倍。为了最好地利用这个特性,就需要将这个特性的主导地位体现出来。

        而根据IOPS=IO并发系数/(寻道时间+旋转延迟时间+数据传输时间),寻道时间比数据传输时间要大几个数量级。所以为了体现数据传输时间减少这个优点,就必须避免寻道时间的影响,而最佳做法就是尽量产生连续IO而不是随机IO。所以,RAID2最适合连续IO的情况。另外,根据每秒IO吞吐量=IO并发系数xIO SIZExV/(Vx寻道时间xVx旋转延迟时间+IO SIZE),如果将IO SIZE也增大,则每秒IO吞吐量也显著提高。所以,RAID2最适合的应用就是产生连续IO、大块IO的情况。不言而喻,视频流服务等应用适合RAID2,。不过,RAID2的缺点太多,比如校验盘数量多、算法复杂等,它逐渐被RAID3代替了。下表比较了RAID2系统与单盘的性能。

大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)

4.2.4 RAID技术详解

        下图所示为一个RAID3系统的条带布局图。

大话存储II----第四章七星北斗--大话/详解七种RAID(4.2)