假定给你一台存储,这个存储上面有16个raid组(就假定是raid10),现在,将要有4台不同应用(Oracle数据库)的主机连接到这台存储,我们又假定4台应用的负载相差不大,数据量也相差不大,你会怎么分配这16个raid组?
一般来说,想到的是以下2种常见的分配方法:
规则一:4个数据库都可以访问所有的raid组,但是每个数据库只能访问其中的1/4。
规则二:因为有16个RAID组,最简单,每个数据库分4个RAID组,互不干涉。
如图:
支持规则1的人说,因为每个数据库都可以访问到所有的RAID组,数据打散到所有的磁盘上,当一个数据库忙的时候,就可以充分利用所有的资源。
支持规则2的人说,太打散不好,看不到热点,数据不集中,不利于存储的cache有效命中,一个库会拖累其它的数据库,造成大家都慢。
可能上面有点难理解的就是不利于存储cache命中了,不过我这里可以稍微解释一下,现在的存储产品,本身是存在一定大小的cache的,如有些高端存储可以配置到512G的cache,其实也就是一个数据缓冲池,类似Oracle的data buffer,一般才采用LRU算法(IBM是ARC算法)管理cache单元,cache单元有可能大于数据库的block大小,如64K,甚至256K。
或许,我们还要假定,如果是同样的应用,两种方式下都能跑,但是,谁更优一些,也就是响应会更快一些?
这是一个疑问题,不好意思,现在没有答案,只想听听你的看法,或者你也可以参考该帖:
http://www.ixpub.net/showthread.php?threadid=645991
前面我介绍了IBM的ds 8000系列与HDS的usp系列,这里我介绍最后一个高端系列,EMC的dmx3系列。

点这里看大图
DMX3是在早先SYMMTRIX 2000/3000系列上发展过来的,基本的体系结构没有改变,但是cache算法却做了一个比较大的改动,在以前的高端系统中,EMC是不采用写cache镜相技术的,而别的厂商基本都采用写cache镜相、读cache不镜相、读写cache分离这样的技术。那么,他们分别采用什么样的方式来保证写cache数据的正确性呢?
第一,因为cache肯定都是电池或者ups保护的,可以保证不掉电,或者是掉点以后系统还能维持一定时间,如果在一定时间内还没有供电,再把数据写到硬盘上,防止丢失。
第二,因为写cahce镜相保护数据也很简单,就是防止cache损坏,如果坏掉一个cache,还有另外一个,只要马上把坏的cache标记起来不用,镜相到新的地方即可。
第三,早先的SYMMTRIX系列采用了一种类似raid5的电极校验法来对cache进行校验,保证数据的可靠性,提高cache的利用率。但是,在新的dmx3中,又采用了一种完全不一样的镜相方法,读写全局cache全镜相,也就是说,如果100Gcache,有效cache是50G。
那么,“全局读写cache全镜相”与“读写cache分离,写cache镜相技术”谁好谁差,我不做评论,不过有些关键点大家还是要知道
1、全局cache中,读写是混在一起的,类似oracle的buffer,读可以直接在一个cache中命中。
2、读写分离中,如果一个要读的数据在写cache中存在,需要先从写cache拷贝到读cache,可能存在多份。
3、读cache一般远远大于写cache。
除了cache算法差别,我们从体系结构图中,还可以发现,emc一样以cache为核心,有前段卡有后端卡之分,如一个前端卡上有8个光纤接口,可以连接主机,一个后端卡上同样有8个后端口,用来连接磁盘。磁盘与hds一样采用光纤环路方式。
不过,emc前端与后端卡连接cache的方式与hds有很大差别,hds是通过内部交换方式连接,而EMC是直接连接,每个卡与每个cache板之间都有数据通道,所以,emc的连接方式又叫直连矩阵。
另外,emc的raid方式与hds也很不一样,hds的raid方式很死板,如raid10就支持2D+2D,其实所谓的4D+4D不过是把2个2D+2D简单的连接在一起。而emc中,raid方式比较奇特,如做10,他们先是把磁盘划成很多道(叫split,如8split,10split,16split等等),每一split可以镜相到一个磁盘。如一个磁盘有16个split,则3.8G/split,那么这个磁盘最多可以镜相到其它16块磁盘上,同样,其它的盘也可以交错镜相到这里,形成一个比较大的磁盘pool。之后,emc在每个split上做strip,形成metalun,这才是主机最后使用的LUN,对应到一个pv。

点这里查看大图
CHA(channel adapter,9970/9980也叫chip),usp的前端卡,上面可以有多个(如8个)前端口,是连接主机与存储阵列cache的通道,一般默认是2Gb通道,现在可以配置到4Gb通道。
DKA(disk adapter,9970/9980叫acp),usp的后端卡,上面一般可以有多个(如8个)后端口,连接阵列的磁盘控制器(DKU)与cache,现在还是2Gb的后端光纤环路通道。在USP的后端,磁盘放在DKU的HDU中,每个HDU最多可以放16个硬盘,而USP的一个环路最多可以接3个HDU,则一个环路最多可以是48块硬盘。
注意,所谓前端卡与后端卡,只是叫法上的分别以及功能上的差别,物理位置可以是在一起的。另外,前端卡与后端卡总是成对出现。
USP最核心的就是cache了,有控制cache与数据cache之分,控制cache也可以叫sheard cache,保存着阵列的配置信息以及数据cache的地址信息,在前端口过来寻找数据的时候,会先经过这里,如果能找到,则去数据cache,如果找不到,则可能需要磁盘读取。
数据cache也叫标准cache,如果采用4G的内存标准,最大可以到128G,而如果采用8G的内存标准,可以到256G,数据cache是整个阵列的核心所在。usp的内存cache最小单元叫segment,固定为64K,最小使用单元叫slot,在有些版本=4个segment=256K,有些版本则=1个segment=64K,因为这个slot中在磁盘上的数据必须是连续的,所以,太大的slot可能对离散度高的oltp应用不是太适合。
前端卡与后端卡连接cache,是要经过一个交换机的(Crossbar Switch),交换机最小可以是2个(冗余需要),最大可以是4个,因为所有的数据都要经过前端卡/后端卡,再经过交换机到cache,所以switch也是一个核心部件,而且数据流量会很大。
USP跟IBM的8000系列(见我的前一篇介绍)的构架已经完全不一样了,如果说IBM8000系列还是在对称体系结构上发展,依靠其强大的主机优势来保证存储的高可用性,那么USP已经发展到多模块化设计了,以cache为核心,并且cpu集成在前端与后端模块中,操作系统则集成在微码之中。
cache的命中率是一个阵列的响应速度以及处理能力的一个重要体现,因为cache命中的话,返回速度是非常快的,而不命中的话,就需要去磁盘寻找数据,可能会比较慢。而cache的命中率,与应用访问规则,数据分布规则都有很大关系。
不要太迷信厂家给出的IOPS值,他们一般都是在cache命中的基础上算出来的。
接下来的时间,我给大家介绍几款高端存储的体系结构,包括IBM的DS8000系列,HDS的USP系列(有些厂商也叫9990系列)以及EMC的DMX3系列。我不评价其好坏,只是对内部结构做一些简单的介绍。
先看DS8000的一个体系结构图:

我们可以看到,DS8000沿用了一个比较典型的对称处理结构,利用其高性能与高可靠的P570作为阵列的双控制器,两台570互相做冗余,形成一个双active的HA结构。在处理器上也是采用其先进的Power5系列的CPU。另外,因为p系列的570支持逻辑分区(LPAR),所以,8000系列的存储也支持逻辑分区。
在结构图的最上方,就是阵列负责对外的光纤卡通道或者是主机适配器,一般高端阵列中都叫前端卡(前端口),支持2Gb带宽(bit),好象到目前为止,8000好象还不支持4Gb的对外接口(如果支持,应当也是迟早的事情,因为其它厂商都已经支持了)。
在结构图的最下方,就是磁盘适配器或者是RIAD适配器接口,一般高端阵列这里叫后端卡(后端口),IBM与其它存储这里有点不一样的是,它没有采用典型的环路设计,而是采用了交换设计,也就是说,后端卡通过内部交换机其实是可以访问到每一块磁盘的。
因为IBM采用了570作为8000系列的核心控制器,所以阵列的cpu与内存也都是在570内部控制的,而且阵列的可靠性是需要570来保证的,IBM希望凭借其570的稳定性与强悍的处理能力带给存储高的可用性。
上次有朋友谈到这个话题,关于netapp与其改良型raid4,希望我能介绍这个东西,估计知道的人也不太多,我这里尽量用简单的语言来介绍一下他的特点,希望大家能看明白。
Netapp公司创建时间不算长,1992年才创建,但是netapp还是写下了一系列的神话,包括现在IBM的nas系统,都是OEM的netapp的产品。那么,netapp的优势在哪里呢?我在这里分析一下它的特点,WAFL与RAID4+。
WAFL文件系统是netapp自己设计的,运行在netapp专用操作系统DATA ONTAP上的一个文件系统,WAFL是“Write Anywhere File Layout”的意思,即“任意位置写入文件布局”的缩写。正因为有WAFL的这个特点,所以才有了RAID4+,一个改进型的raid4,使得没有校验瓶颈存在,而且能随意扩充硬盘的raid方式。
如果说传统的存储方式中,如果修改一个数据块,我们必须先定位到那个数据块,然后再修改,在我的前面写的raid5内部分析中,我们也看到了,如果修改一个单独的数据,我们必须先读出这个数据与校验,然后修改数据,计算校验,最后写入到同样的位置,这些特点,不仅仅是raid决定的,而且也是运行在raid之上的文件系统决定的。
在WAFL中,如果它也修改一个数据,他可能不管以前的数据的位置,直接把新数据与新校验写到新的位置,之后更改指针,告诉文件系统说,新的数据在这里,而不是原来那里了。这么做还有一个最大的好处就是,新的数据可能等到足够多以后,可以凑齐raid的一个条带以后,一起写进去,就可以大大的提高写的速度。
raid4+就在WAFL的配合下诞生了,传统的raid4是把所有的校验写在一块单独的硬盘上的,如果数据修改量很大,那么这个单独的硬盘就变成了性能瓶颈,而raid4+可以最大可能的把一个条带的数据,一次性的写入,所以,使得校验盘与其它的盘基本相当的写入量,而没有瓶颈出现。而且,当这个raid组想增加硬盘的时候,只是简单的放入新的硬盘即可,任意位置写的规则可以保证新的硬盘马上就被使用起来。
WAFL与raid4+为了尽量保证把数据合并后一次性写入,就必须依赖cache,在cache中才可以等到一定数量的数据之后再一起分批写入,而且,本身WAFL的日志也是记录在cache中的,也包括WAFL的inode的指针操作,也都是在cache中完成。所以,netapp也必须依赖电池或者ups对cache实施保护。
我们先看一个传统的raid4与改良型的raid4之间写的差别,如图,在传统型的raid4中,如果改写我如图的数据,每个数据需要读一次,校验盘可能会写6次,每个数据写一个,涉及到6个条带。但是,在改良型的raid4中,读已经不存在了,而且写的话,最小的可能性,只需要写2个条带,8个写io,一次性写入即可,至于指针,则由WAFL文件系统在cache中完成。
注意,这里为什么说最小可能写2个条带,因为写的时候还需要根据磁盘空间剩余情况,cache的利用情况来综合决定的,有可能也会涉及到3-4个条带,但是,可以肯定的是,算法尽量保证最少的磁盘写次数。

我们上面分析了改良型的raid4的写,那么我们再分析一下它的raid组增加磁盘的过程,在一般的raid组中,想要给raid组增加一个磁盘,是非常困难的,因为数据以前就分布好了,除非再强行改变分布,但是,netapp不一样,它的文件系统本来就是任意写,所以很容易把新加的磁盘给用上。

那么说了这么多,netapp的WAFL与raid4+的优势已经很清楚了:
1、尽量保证数据一次性的写入,减少磁盘争用,提高写速度
2、因为任意写的特点,使得snapshot变得非常简单,而且,就算你不做snapshot,系统本身也一直在不停的产生snapshot,因为这样可以大大减少文件系统的恢复时间。
那么,有缺点吗?肯定有的,这个世界总是没有完美的东西存在的
1、因为任意写,为了保证每次都能操作一个条带,那么,系统希望尽量有充足的空闲空间,如使用率不要超过80%,否则,因为空闲空间太少而不能保证每次都写一个条带
2、因为任意写,可能会使本来连续的空间,分布在存储的任意位置,如数据库应用中,本来连续的表,在存储中多次修改以后,就不连续了,使得全表扫描或者备份变得很慢。
上篇我们分析了raid5与raid10的内部运行细节,这里我们主要分析一下存储阵列的瓶颈,因为瓶颈的出现,与raid方式是有很大差别的,所以我们需要先分析raid5与raid10的具体差别。
阵列的瓶颈主要体现在2个方面,吞吐量与IOPS。
1、吞吐量
吞吐量主要取决于阵列的构架,光纤通道的大小(现在阵列一般都是光纤阵列,至于SCSI这样的SSA阵列,我们不讨论)以及硬盘的个数。阵列的构架与每个阵列不同而不同,他们也都存在内部带宽(类似于pc的系统总线),不过一般情况下,内部带宽都设计的很充足,不是瓶颈的所在。
光纤通道的影响还是比较大的,如数据仓库环境中,对数据的流量要求很大,而一块2Gb的光纤卡,所能支撑的最大流量应当是2Gb/8(小B)=250MB/s(大B)的实际流量,当4块光纤卡才能达到1GB/s的实际流量,所以数据仓库环境可以考虑换4Gb的光纤卡。
最后说一下硬盘的限制,这里是最重要的,当前面的瓶颈不再存在的时候,就要看硬盘的个数了,我下面列一下不同的硬盘所能支撑的流量大小:
10 K rpm 15 K rpm ATA
——— ——— ———
10M/s 13M/s 8M/s
那么,假定一个阵列有120块15K rpm的光纤硬盘,那么硬盘上最大的可以支撑的流量为120*13=1560MB/s,如果是2Gb的光纤卡,可能需要6块才能够,而4Gb的光纤卡,3-4块就够了。
2、IOPS
决定IOPS的主要取决与阵列的算法,cache命中率,以及磁盘个数。阵列的算法因为不同的阵列不同而不同,如我们最近遇到在hds usp上面,可能因为ldev(lun)存在队列或者资源限制,而单个ldev的iops就上不去,所以,在使用这个存储之前,有必要了解这个存储的一些算法规则与限制。
cache的命中率取决于数据的分布,cache size的大小,数据访问的规则,以及cache的算法,如果完整的讨论下来,这里将变得很复杂,可以有一天好讨论了。我这里只强调一个cache的命中率,如果一个阵列,读cache的命中率越高越好,一般表示它可以支持更多的IOPS,为什么这么说呢?这个就与我们下面要讨论的硬盘IOPS有关系了。
硬盘的限制,每个物理硬盘能处理的IOPS是有限制的,如
10 K rpm 15 K rpm ATA
——— ——— ———
100 150 50
同样,如果一个阵列有120块15K rpm的光纤硬盘,那么,它能撑的最大IOPS为120*150=18000,这个为硬件限制的理论值,如果超过这个值,硬盘的响应可能会变的非常缓慢而不能正常提供业务。
另外,我们上一篇也讨论了,在raid5与raid10上,读iops没有差别,但是,相同的业务写iops,最终落在磁盘上的iops是有差别的,而我们评估的却正是磁盘的IOPS,如果达到了磁盘的限制,性能肯定是上不去了。
那我们假定一个case,业务的iops是10000,读cache命中率是30%,读iops为60%,写iops为40%,磁盘个数为120,那么分别计算在raid5与raid10的情况下,每个磁盘的iops为多少。
raid5:
- 单块盘的iops = (10000*(1-0.3)*0.6 + 4 * (10000*0.4))/120
- = (4200 + 16000)/120
- = 168
这里的10000*(1-0.3)*0.6表示是读的iops,比例是0.6,除掉cache命中,实际只有4200个iops
而4 * (10000*0.4) 表示写的iops,因为每一个写,在raid5中,实际发生了4个io,所以写的iops为16000个
为了考虑raid5在写操作的时候,那2个读操作也可能发生命中,所以更精确的计算为:
- 单块盘的iops = (10000*(1-0.3)*0.6 + 2 * (10000*0.4)*(1-0.3) + 2 * (10000*0.4))/120
- = (4200 + 5600 + 8000)/120
- = 148
计算出来单个盘的iops为148个,基本达到磁盘极限
raid10
- 单块盘的iops = (10000*(1-0.3)*0.6 + 2 * (10000*0.4))/120
- = (4200 + 8000)/120
- = 102
可以看到,因为raid10对于一个写操作,只发生2次io,所以,同样的压力,同样的磁盘,每个盘的iops只有102个,还远远低于磁盘的极限iops。
在一个实际的case中,一个恢复压力很大的standby(这里主要是写,而且是小io的写),采用了raid5的方案,发现性能很差,通过分析,每个磁盘的iops在高峰时期,快达到200了,导致响应速度巨慢无比。后来改造成raid10,就避免了这个性能问题,每个磁盘的iops降到100左右。
一直以来,看到关于raid5与raid10的性能之争还是非常多的,甚至很多人那拿出了测试数据,但是,到底谁是谁非。这里,我就这两种raid的内部运行原理来分析一下,我们在什么情况下应当适合选哪一种raid方式。
为了方便对比,我这里拿同样多驱动器的磁盘来做对比,raid5选择3D+1P的raid方案,raid10选择2D+2D的Raid方案,分别如图:

那么,我们分析如下三个过程:读,连续写,随机写,但是,在介绍这三个过程之前,我需要介绍一个特别重要的概念:cache。
cache技术最近几年,在磁盘存储技术上,发展的非常迅速,作为高端存储,cache已经是整个存储的核心所在,就是中低端存储,也有很大的cache存在,包括最简单的raid卡,一般都包含有几十,甚至几百兆的raid cache。
cache的主要作用是什么呢?体现在读与写两个不同的方面,如果作为写,一般存储阵列只要求写到cache就算完成了写操作,所以,阵列的写是非常快速的,在写cache的数据积累到一定程度,阵列才把数据刷到磁盘,可以实现批量的写入,至于cache数据的保护,一般都依赖于镜相与电池(或者是UPS)。
cache的读一样不可忽视,因为如果读能在cache中命中的话,将减少磁盘的寻道,因为磁盘从寻道开始到找到数据,一般都在6ms以上,而这个时间,对于那些密集型io的应用可能不是太理想。但是,如果cache能命中,一般响应时间则可以在1ms以内。
不要迷信存储厂商的iops(每秒的io数)数据,他们可能全部在cache命中的基础上做到的,但是实际上,你的cache命中率可能只有10%。
介绍完cache,我们就可以解释raid5与raid10在不同的模式下,工作效率问题了,那么我们来分别分析以上三个问题。
1、读操作
因为raid5与raid10的磁盘都可以提供服务,所以,在读上面他们基本是没有差别的,除非是读的数据能影响cache命中率,导致命中率不一样。

2、连续写
连续写的过程,一般表示写入连续的大批量的数据,如媒体数据流,很大的文件等等,这个写操作过程,如果有写cache存在,并且算法没有问题的话,raid5比raid10甚至会更好一些(这里要假定存储有一定大小足够的写cache,而且计算校验的cpu不会出现瓶颈)。因为这个时候的校验是在cache中完成,如4块盘的raid5,可以先在内存中计算好校验,同时写入3个数据+1个校验。而raid10只能同时写入2个数据+2个镜相。

如,4块盘的raid5可以在同时间写入1、2、3到cache,并且在cache计算好校验之后,我这里假定是6(实际的校验计算并不是这样的,我这里仅仅是假设),同时把三个数据写到磁盘。而4块盘的raid10不管cache是否存在,写的时候,都是同时写2个数据与2个镜相。
但是,我前面也说过了,写cache是可以缓存写操作的,等到一定时期再写到磁盘,但是,写操作不比读操作,这个写是迟早也要发生的,也就是说,最后落到磁盘上的写还是避免不了的,不过,如果不是连续性的强连续写,只要不达到磁盘的写极限,差别都不是太大。
3、离散写
这里可能是最难理解,但是,也是最重要的部分,数据库,如oracle 数据库大部分操作就是离散写,如每次写一个数据块的数据,如8K;联机日志虽然看起来是连续写,但是因为每次写的量不多,不保证能添满raid5的一个条带(保证每张盘都能写入),所以很多时候也是离散写入。

我们再接上图,假定要把一个数字2变成数字4,那么对于raid5,实际发生了4次io,
先读出2与校验6,可能发生读命中
然后在cache中计算新的校验
写入新的数字4与新的校验8
对于raid10,我们可以看到,同样的单个操作,最终raid10只需要2个io,而raid5需要4个io。
但是,这里我忽略了raid5在那两个读操作的时候,还可能会发生读命中操作,也就是说,如果需要读取的数据已经在cache中,可能是不需要4个io的,也证明了cache对raid5 的重要性,不仅仅是计算校验需要,而且对性能的提升由为重要。曾经测试过,在raid5的阵列中,如果关闭写cache,raid5的性能将差很多倍。
这里,并不是说cache对raid10就不重要了,因为写缓冲,读命中等,都是提高速度的关键所在,不过的是,raid10对cache的依赖性没有raid5那么明显而已。
到这里,大家应当也大致明白了raid5与raid10的原理与差别了,一般来说,象小io的数据库类型操作,建议采用raid10,而大型文件存储,数据仓库,则从空间利用的角度,可以采用raid5。
待续。。。。。。