不考虑存储器的存取速度度,长久保存,超过5T的存储用什么方案好(要求经济)

这不是杞人忧天:分布式存储存在的隐患(完整修正版)
我的图书馆
这不是杞人忧天:分布式存储存在的隐患(完整修正版)
&前言分布式存储存在的风险,其实就是因为“共享”、“大数据量”、“高性能”和X86服务器+廉价的磁盘为载体之间的矛盾所产生的。不是有些读者说的“数据架构”的问题。其实任何存储都存在这个问题,只是分布式存储更严重。本文其实是从主机的网络、磁盘的吞吐角度分析存在的风险,所以和用那个厂家的存储无关。还有人说你是危言耸听,如果按照你说的,这么多人用了分布式存储有这样的地雷岂不是要炸飞?软件定义的东西其实有很多BUG,重要的是能发现问题,事先做好弥补或方案。还有人说,分布式存储用到现在也不超过2年,发生你说的问题还早。但是我们已经发现问题了,不能搁置不管。钓鱼岛问题搁置了,现在还不是造成麻烦了吗?& & & 最后声明,我是独立自媒体运营者,就职于中国电信浙江公司,是浙江公司云计算资源池的架构师。不接受任何商业目的的宣传,也不会主动“吸粉”。我只写我在工作中遇到的问题和总结的经验。我所写的东西和提到的厂家,就是因为我用了,我有感想。我写了,就是为了共享经验。 & & &作为一个无利益的应用者的角度写的东西更加客观。==========开始==========存储最重要的指标是什么?很多人包括存储专家都会认为是存储的性能指标,比如IOPS和吞吐量。但是我认为存储最重要的是数据的安全性。一个跑的飞快的存储,突然数据丢失了,后果会怎么样?数据的丢失,对于任何系统来说,都是灭顶之灾。所以,不管什么样的存储,数据的安全可靠都是第一位的。原来传统的存储使用了专用硬件,从可靠性上有比较高的保证,所以大家首先会关注性能指标。但是用X86为基础的SRVSAN的可靠性就不容乐观。为什么说传统存储这个问题不是太突出呢?除了专用设备外,还有应用场景和数据量不同等原因。在传统行业如电信、银行原来的系统建设是烟囱模式。不但网络是独立一套,存储也是。往往是数据库服务和日志记录,用2台服务器和8个端口的小光交相连,小光交下只挂一个存储。数据量也没有这样大,存储的容量也在5T以下。这样存储的数据迁移是很容易和快速的,方法也很多。由于是专用存储,所以完全可以采用“非在线”的手段,数据量也不大,可以在夜深人静的时候停机完成。进入云计算时代,存储是共享的,数据是应用可靠,提供者不可控,数据量海量增加……传统的方法失灵了。(可见顾炯的云世界的“资源池内存储特点”的文章)我们在2014年下半年,开始搭建以X86为载体的分布式块存储,经过严格的测试,在同年底投入商用,是业界首个商用的软件定义的分布式存储,当时各种媒体都争相报道。到现在为止已经商用了近2年,存储运行稳定,表现优良。并从原来2P裸容量扩容到4.5P。但是近段时间我却越来越担心,因为SRVSAN与生俱来的数据安全隐患,一直被人忽视了,而且主流厂家也没有意识到这个问题。如果这个隐患在若干年以后爆发,会发生重大性系统故障。其实我在写这篇文章前2个月,我已经将这个担忧和想法告诉了现有分布式块存储的产品线总经理,得到他的重视,已经在弥补了。很多软件定义的东西,就怕想不到,突然发生了,想到了就会有相应的解决方案。存储这个东西,大部分读者并不是太了解,从比较基础知识开始写,并引出问题和大家一起讨论解决的办法。盘算了一下大致分为七个部分:·&&&&&&一、存储类型·&&&&&&二、文件系统·&&&&&&三、存储介质·&&&&&&四、Raid和副本·&&&&&&五、SRVSAN的架构·&&&&&&六、SRVSAN的安全隐患·&&&&&&七、解决的方法&一、存储类型一般情况下,我们将存储分成了4种类型,基于本机的DAS和网络的NAS存储、SAN存储、对象存储。对象存储是SAN存储和NAS存储结合后的产物,汲取了SAN存储和NAS存储的优点。&图1我们来了解一下应用是怎么样获取它想要的存在存储里的某个文件信息,并用大家熟悉的Windows来举例,如图1。1、& 应用会发出一个指令“读取本目录下的readme.txt 文件的前1K数据”。2、& 通过内存通信到目录层,将相对目录转换为实际目录,“读取C:\ test\readme.txt文件前1K数据”3、& 通过文件系统,比如FAT32,通过查询文件分配表和目录项,获取文件存储的LBA地址位置、权限等信息。文件系统先查询缓存中有没有数据,如果有直接返回数据;没有,文件系统通过内存通信传递到下一环节命令“读取起始位置LBA1000,长度1024的信息”。4、& 卷(LUN)管理层将LBA地址翻译成为存储的物理地址,并封装协议,如SCSI协议,传递给下一环节。5、& 磁盘控制器根据命令从磁盘中获取相应的信息。& && 如果磁盘扇区大小是4K,实际一次I/O读取的数据是4K,磁头读取的4K数据到达服务器上的内容后,有文件系统截取前1K的数据传递给应用,如果下次应用再发起同样的请求,文件系统就可以从服务器的内存中直接读取。&& && 不管是DAS、NAS还是SAN,数据访问的流程都是差不多的。DAS将计算、存储能力一把抓,封装在一个服务器里。大家日常用的电脑,就是一个DAS系统,如图1。图2&&&&&&&&如果将计算和存储分离了,存储成为一个独立的设备,并且存储有自己的文件系统,可以自己管理数据,就是NAS,如图2。计算和存储间一般采用以太网络连接,走的是CIFS或NFS协议。服务器们可以共享一个文件系统,也就是说,不管服务器讲的是上海话还是杭州话,通过网络到达NAS&的文件系统,都被翻译成为普通话。所以NAS存储可以被不同的主机共享。服务器只要提需求,不需要进行大量的计算,将很多工作交给了存储完成,省下的CPU资源可以干更多服务器想干的事情,即计算密集型适合使用NAS。图3计算和存储分离了,存储成为一个独立的设备,存储只是接受命令不再做复杂的计算,只干读取或者写入文件2件事情,叫SAN,如图3。因为不带文件系统,所以也叫“裸存储”,有些应用就需要裸设备,如数据库。存储只接受简单明了的命令,其他复杂的事情,有服务器端干了。再配合FC网络,这种存储数据读取/写入的速度很高。但是每个服务器都有自己的文件系统进行管理,对于存储来说是不挑食的只要来数据我就存,不需要知道来的是什么,不管是英语还是法语,都忠实记录下来的。但是只有懂英语的才能看懂英语的数据,懂法语的看懂法语的数据。所以,一般服务器和SAN存储区域是一夫一妻制的,SAN的共享性不好。当然,有些装了集群文件系统的主机是可以共享同一个存储区域的。&从上面分析,我们知道,决定存储的快慢是由网络和命令的复杂程度决定的。内存通信速度>总线通信>网络通信,网络通信中还有FC网络和以太网络。FC网络目前可以实现8Gb/s,但以太网络通过光纤介质已经普及10Gb/s,40Gb/s的网卡也在使用了。也就是说传统以太网络已经不是存储的瓶颈了。除了FCSAN,IPSAN也是SAN存储的重要成员。对存储的操作,除了熟悉的读/写以外,其实还有创建、打开、获取属性、设置属性、查找等等。对于有大脑的SAN存储来说,除了读/写以外的命令,都可以在本地内存中完成,速度极快。而NAS存储缺乏大脑,每次向存储传递命令,都需要IP封装并通过以太网络传递到NAS服务器上,这个速度就远远低于内存通信了。&& & &DAS特点是速度最快,但只能自己用;NAS的特点速度慢点但共享性好;SAN的特点是速度快,但共享性差。总体上来讲,对象存储同兼具SAN高速直接访问磁盘特点及NAS的分布式共享特点。NAS存储的基本单位是文件,SAN存储的基本单位是数据块,而对象存储的基本单位是对象,对象可以认为是文件的数据+一组属性信息的组合,这些属性信息可以定义基于文件的RAID参数、数据分布和服务质量等。采取的是“控制信息”和“数据存储”分离的模式,客户端用对象ID+偏移量作为读写的依据,客户端先从“控制信息”获取数据存储的真实地址,再直接从“数据存储”中访问。 对象存储大量使用在互联网上,大家使用的网盘就是典型的对象存储。对象存储有很好的扩展性,可以线性扩容。并可以通过接口封装,还可以提供NAS存储服务和SAN存储服务。VMware的vSAN本质就是一个对象存储。分布式对象存储就是SRVSAN的一种,也存在安全隐患。因为这个隐患是X86服务器带来的。&二、文件系统计算机的文件系统是管理文件的“账房先生”。首先他要管理仓库,要知道各种货物都放在哪里;然后要控制货物的进出,并要确保货物的安全。如果没有这个“账房先生”,让每个“伙计”自由的出入仓库,就会导致仓库杂乱无章、货物遗失。就像那年轻纺城机房刚启用的时候,大家的货物都堆在机房里,没有人统一管理,设备需要上架的时候,到一大堆货物中自行寻找,安装后的垃圾也没有人打扫,最后连堆积的地方都找不到,有时自己的货物找不到了,找到别人的就使用了……。大家都怨声载道,后来建立了一个仓库,请来了仓库管理员,用一本本子记录了货物的归宿和存储的位置,建立货物的出入库制度,问题都解决了,这就是文件系统要做的事情。文件系统管理存取文件的接口、文件的存储组织和分配、文件属性的管理(比如文件的归属、权限、创建事件等)。每个操作系统都有自己的文件系统。比如windows就有常用的FAT、FAT32、NTFS等,Linux用ext1-4的等。存储文件的仓库有很多中形式,现在主要用的是(机械)磁盘、SSD、光盘、磁带等等。拿到这些介质后,首先需要的是“格式化”,格式化就是建立文件存储组织架构和“账本”的过程。比如将U盘用FAT32格式化,我们可以看到是这样架构和账本(如图4):图4主引导区,记录了这个存储设备的总体信息和基本信息。比如扇区的大小,每簇的大小、磁头数、磁盘扇区总数、FAT表份数、分区引导代码等等信息。分区表,即此存储的账本,如果分区表丢失了,就意味着数据的丢失,所以一般就保留2份,即FAT1和FAT2。分区表主要记录每簇使用情况,当这位置的簇是空的,就代表还没有使用,有特殊标记的代表是坏簇,位置上有数据的,是指示文件块的下一个位置。目录区:目录和记录文件所在的位置信息。数据区:记录文件具体信息的区域。通过以下的例子来帮助理解什么是FAT文件系统。假设每簇8个扇区组成一个簇,大小是512*8=4K。根目录下的readme.txt文件大小是10K,如图5:图51、&&&在目录区找到根目录下文件readme.txt在FAT表中的位置是00042、&&&在0004位置对应簇的8个扇区读取相应文件块readme(1)保存在内存,并获取下一个数据块的位置0005。3、&&&在0005位置对应簇的8个扇区读取相应文件块readme(2)保存在内存,并获取下一个数据块的位置0008。4、&&&在0005位置对应簇的4个扇区读取相应文件块readme(3)保存在内存,并获得结束标志。5、&&&将readme(1)、readme(2)、readme(3)组合成为readme文件。& & & 在这个例子中,我们看到在FAT文件系统,是通过查询FAT表和目录项来确定文件的存储位置,文件分布是以簇为单位的数据块,通过“链条”的方式来指示文件数据保存的文字。当要读取文件时,必须从文件头开始读取。这样的方式,读取的效率不高。&不同的Linux文件系统大同小异,一般都采取ext文件系统,如图6.&图6启动块内是服务器开机启动使用的,即使这个分区不是启动分区,也保留。超级块存储了文件系统的相关信息,包括文件系统的类型,inode的数目,数据块的数目Inodes块是存储文件的inode信息,每个文件对应一个inode。包含文件的元信息,具体来说有以下内容:  * 文件的字节数  * 文件拥有者的User ID  * 文件的Group ID  * 文件的读、写、执行权限  * 文件的时间戳,共有三个:ctime指inode上一次变动的时间,mtime指文件内容上一次变动的时间,atime指文件上一次打开的时间。  * 链接数,即有多少文件名指向这个inode  * 文件数据block的位置&当查看某个目录或文件时,会先从inode table中查出文件属性及数据存放点,再从数据块中读取数据。&数据块:存放目录和文件数据。通过读取\var\readme.txt文件流程,来理解ext文件系统,如图7。&图71、根目录A所对应的inode节点是2,inode1对应的数据块是d1,2、在检索d1内容发现,目录var对应的inode=28,对应的数据块是d5,3、检索d5内容发现readme.txt对应的是inode=70。4、Inode70指向数据区d2、d3、d6块。读取这些数据块,在内存中组合d2、d3、d6数据块。&&& &&&硬盘格式化的时候,操作系统自动将硬盘分成两个区域。一个是数据区,存放文件数据;另一个是inode区,存放inode所包含的信息。当inode资源消耗完了,尽管数据区域还有空余空间,都不能再写入新文件。&总结:Windows的文件系统往往是“串行”的,而linux的文件系统是“并行”的。&再来看分布式的文件系统。如果提供持久化层的存储空间不是一台设备,而是多台,每台之间通过网络连接,数据是打散保存在多台存储设备上。也就是说元数据记录的不仅仅记录在哪块数据块的编号,还要记录是哪个数据节点的。这样,元数据需要保存在每个数据节点上,而且必须实时同步。做到这一点其实很困难。如果把元数据服务器独立出来,做成“主从”架构,就不需要在每个数据节点维护元数据表,简化了数据维护的难度,提高了效率。Hadoop的文件系统HDFS就是一个典型的分布式文件系统。图81、&Client将FileA按64M分块。分成两块,block1和Block2;2、.Client向nameNode发送写数据请求,如图紫色虚线13、NameNode节点,记录block信息。并返回可用的DataNode给客户端,如图红色虚线2&&&& & & & &Block1: host11,host22,host31&&&& & & & &Block2: host11,host21,host32&4、client向DataNode发送block1;发送过程是以流式写入。&& 流式写入过程,&1)将64M的block1按64k的package划分;&2)然后将第一个package发送给host11;&3)host11接收完后,将第一个package发送给host22,同时client想host11发送第二个package;&4)host22接收完第一个package后,发送给host31,同时接收host11发来的第二个package。&5)以此类推,如图黑色虚线3所示,直到将block1发送完毕。&6)host11,host22,host31向NameNode和 Client发送通知,说“消息发送完了”。 &7)client收到发来的消息后,向namenode发送消息,说我写完了。这样就真完成了。&8)发送完block1后,再向host11,host21,host32发送block2,如图蓝色虚线4所示。..........&HDFS是分布式存储的雏形,分布式存储将在以后详细介绍。&三、存储介质&& & &仓库有很多种存储的介质,现在最常用的是磁盘和SSD盘,还有光盘、磁带等等。磁盘一直以性价比的优势占据了霸主的地位。&& & &圆形的磁性盘片装在一个方的密封盒子里,运行起来吱吱的响,这就是我们常见的磁盘。磁片是真正存放数据的介质,每个磁片正面和背面上都“悬浮”着磁头。磁盘上分割为很多个同心圆,每个同心圆叫做磁道,每个磁道又被分割成为一个个小扇区,每个扇区可以存储512B的数据。当磁头在磁片上高速转动和不停换道,来读取或者写入数据。其实磁片负责高速转动,而磁头只负责在磁片上横向移动。决定磁盘性能的主要是磁片的转速、磁头的换道、磁盘、每片磁片的容量和接口速度决定的。转速越高、换道时间越短、单片容量越高,磁盘性能就越好。图9图10&图11&衡量磁盘性能主要参考 IOPS 和吞吐量两个参数。IOPS就是一秒钟内磁盘进行了多少次的读写,吞吐量就是读出了多少数据。其实这些指标应该有前提,即是大包(块)还是小包(块),是读还是写,是随机的还是连续的。一般我们看到厂家给的磁盘IOPS性能一般是指小包、顺序读下的测试指标。这个指标一般就是最大值。目前在X86服务器上我们常使用的 SATA、SAS磁盘性能:图12& & & &实际生产中估算,SATA 7200转的磁盘,提供的IOPS为60次左右,吞吐量在70MB/s。我们2014年首次使用的裸容量2P的SRVSAN存储的数据持久化层采用57台X86服务器,内置12块SATA7200 3TB硬盘。共684块磁盘,大约只提供41040次IOPS和47.88GB/s。这些指标显然是不能满足存储需要的,需要想办法“加速”。机械磁盘其实也做了很多优化,比如扇区地址的编号不是连续的。因为磁片转的够快(7200转/分钟即1秒钟转120转,转一圈是8.3毫秒,也就是在读写同一个磁道最大时延是8.3秒),防止磁头的读写取错过了,所以扇区的地址并不是连续的,而是跳跃编号的,比如2:1的交叉因子(1、10、2、11、3、12…..)。同时磁盘也有缓存,具有队列,并不是来一个I/O就读写一个,而是积累到一定I/O,根据磁头的位置和算法完成的。I/O并不是一定是“先到先处理”,而是遵守效率。&加速最好的办法就是使用SSD盘。磁盘的控制部分是由机械部分+控制电路来构成,机械部分的速度限制,使磁盘的性能不可能有大的突破。而SSD采用了全电子控制可以获得很好的性能。SSD是以闪存作为存储介质再配合适当的控制芯片组成的存储设备。目前用来生产固态硬盘的NAND Flash有三种,分别是单层式存储(SLC,存储1bit数据)、二层式存储(MLC,存储4bit数据)、三层式存储(TLC,存储8bit数据)。SLC成本最高、寿命最长、但访问速度最快,TLC成本最低、寿命最短但访问速度最慢。为了降低成本,用于服务器的企业级SSD都用了MLC,TLC可以用来做U盘。图13&& & SSD普及起来还有一点的障碍,比如成本较高、写入次数限制、损坏时的不可挽救性及当随着写入次数增加或接近写满时候速度会下降等缺点。& & &对应磁盘的最小IO单位扇区,page是SSD的最小单位。比如每个page存储512B的数据和218b的纠错码,128个page组成一个块(64KB),2048个块,组成一个区域,一个闪存芯片有2个区域组成。Page的尺寸越大,这个闪讯芯片的容量就越大。但是SSD有一个坏习惯,就是在修改某1个page的数据,会波及到整块。需要将这个page所在的整块数据读到缓存中,然后再将这个块初始化为1,再从缓存中读取数据写入。对于SSD来说,速度可能不是问题,但是写的次数是有限制的,所以块也不是越大越好。当然对于机械磁盘来说也存在类似问题,块越大,读写的速度就越快,但浪费也越严重,因为写不满一块也要占一块的位置。& & & 不同型号不同厂家的SSD性能差异很大,下面是我们的分布式块存储作为缓存使用的SSD参数:& & & 采用PCIe 2.0接口,容量是1.2T,综合读写IOPS(4k小包)是260000次,读吞吐量1.55GB/s,写吞吐量1GB/s。& & & 在1台SRVSAN的服务器配置了一块SSD作为缓存和12块7200转 3T SATA盘,磁盘只提供1200次、1200M的吞出量。远远小于缓存SSD提供的能力,所以直接访问缓存可以提供很高的存储性能,SRVSAN的关键是计算出热点数据的算法,提高热点数据的命中率。用高成本的SSD做为缓存,用廉价的SATA磁盘作为容量层。&四、Raid和副本& & & 把磁盘们相同偏移量的一块空间横向进行分割,组成一条逻辑上存储空间。数据是先写满一条条带,再写下一条条带。一个卷可以有很多条条带组成。条带的划分应该的磁盘配置初级就完成。条带包含扇区(或块)的个数叫条带长度;每个磁盘内包含属于这个条带的扇区(或块)的个数叫条带深度。为什么要引入条带的概念呢,是因为要解决单个磁盘一次只能同时并发一个IO和保证数据完整性。&图14&&& & 我们知道磁盘的IO实际上是磁盘寻找对应扇区地址的过程,是在磁片旋转和磁头在机械臂的控制下横向寻道的结果,而且一个磁盘一次只能完成一个IO申请,而通过条带的方式可以让多个磁盘一起协同完成任务,这种方法叫做raid0。从理论上看磁盘越多,条带深度越小,速度就越快。但是也不是条带深度越小速度就越快,因为深度太小,并发的概率就降低了。没有了并发,就不会提高速度了。所以一般来说当随机的小块IO多,就适当加大条带深度,当顺序的大块多,就减小条带的深度。Raid0体现的是人多力量大的哲理。&& & &但是如果raid0的方式下有一块磁盘出现故障了,那数据的完整性被破坏了,数据不可用了。为了确保数据完整性,所以就有了raid1。raid1就是将一份数据写到2个物理磁盘上,即数据有镜像,二数据副本。就算坏了一块盘也不会导致数据不可用。和单块盘比Raid1方式写的慢,读快,道理很明显。&& & & 将raid0和raid1组合起来,就可以吸取各自的优点,但是要注意组合的顺序,raid10比raid01冗余度高、数据更安全,如图:图15当左边的raid10系统有一块故障,底层数据是做raid1镜像的,数据的完整性没有被破坏,还可以再坏一块另外raid1组的一个磁盘。而raid01,当底层的raid0组的磁盘坏掉一块,整个raid0组数据就无效了,所有的IO都会到剩下的raid0组,并且如果再坏一块盘,整个数据就无效了。Raid5和raid6也是常用的raid方法。Raid5最少需要3块盘,有1个数据副本和1个数据校验;即最多可以坏1块盘;Raid6最少需要4块盘,有1个数据副本和2个数据校验,即最多可以坏2块盘。这些数据副本和数据校验都均匀的打散在磁盘中。Raid5和raid6的磁盘利用率最低为66.7%和50%,是兼顾利用率和性能的方案。Raid6的安全性比raid5更好,性能差别不大。Raid都有一定的计算量,来决定这些数据块存放的磁盘、计算出校验数据,或根据校验数据计算出数据。这些都需要CPU和内存资源。为了减少对主机CPU和内存的压力。现在一般在主机的PCI总线上配置raid卡,硬盘都连接在raid卡下。Raid 卡其实就是一台小型的计算机,有CPU、内存和缓存,减轻了主机的负担。但是raid卡不能跨越主机,所以在分布式存储中,网络raid就不能利用本地的raid卡,只能用主机的CPU和内存。综合各种因素,分布式存储一般都采用副本的方法。&五、分布式存储的架构一般来说,分布式存储不管是文件存储、对象存储还是块存储的基本架构都是大同小异的。即客户端或应用端、元数据(MDS)服务器和数据节点服务器。图16&&&& & &客户端和元数据服务器之间交互是“信令交互”,而客户端到数据节点是“媒体交互”。元数据服务器或通过数据节点服务器获取各节点服务器的基本配置情况和状态信息。比如,客户端需要读取某一个文件的信息,客户端会将相应的要求发给元数据服务器:“喂!我需要XXX,存在哪里了”,元数据服务器查询后回答“你到xxx服务器的xxx地址+xxx服务器的xxx地址取”。客户端拿到这个指示后,向这2台服务器发出指令,数据节点获得指令后,将相应的数据返回给客户端。大家可能都会奇怪,为什么块存储、对象和文件的架构都是一样的。有什么区别呢?我们在前面基础知识讲述中,块存储是一种裸设备,它是将存储设备以“块”的方式直接提供给客户,由客户自己的操作系统里的文件系统进行管理。即分布式块存储里是没有文件系统的,是通过客户端直接将最简单明了的命令传递给存储的“块”来执行。而对象存储和文件存储虽然结构类似,但并不将存储底层的“块”直接提供出来,而是通过隐藏着一个文件系统,包装成为“文件”或“对象”提供出来。这些存储“不挑”操作系统或终端,最终执行命令的是存储里面的文件系统操控存储执行的,所以共享性很好。文件存储通过“目录+文件名+偏移量”来检索,文件间有目录层次的;而对象存储采用“唯一对象ID +偏移量”来检索,对象扁平存储的,是没有层次的。而且块、对象、文件存储是可以相互转换的,这个问题以后单独讲。&华为的FusionStorage是一个典型的“块”存储,我们来了解一下结构。图17&&&&& FusionStorage也分成了MDC、OSD和Client三部分。和其他分布式存储重大的差别是,MDC是记录、更新OSD服务器、磁盘等的状态,并把这些状态数据实时同步给Vbs,由Vbs计算出来数据所落的位置。MDC可以单独部署,也可以集中部署,也可以分布部署。如果MDC全出现故障,并不会影响存储的正常运行。但是如果在MDC故障期间OSD的状态发生了改变,比如某块磁盘故障,就会导致部分IO访问不正常。所以一般MDC部署在3台OSD上,确保安全。一般分布式存储的MDC采用的是数据库或内存储数据库来记录数据块和物理位置关系。客户端向MDC发出询问位置的请求,MDC查询数据库后返回请求数据的存储位置。这种方法存储访问的速度较慢,而且MDC作为交通的“枢纽”,绝对是整个存储的核心,当MDC发生故障,会导致整个存储都不能使用。但是采取这个方式,也有好处,比如可以根据不同需求设置不同的副本策略等。VBS是计算数据块存储位置的重要网元。一个VBS就是一个“机头”。VBS部署很灵活,有很多种部署方法,可以根据不同的需求进行选择。比如,在VMWARE虚拟机中,可以在物理机上开设一台虚拟机部署VBS,在XEN/KVM部署在domain0上;或者部署在每台OSD服务器上,或专门设置VBS服务器群,。图18VBS采取一致性哈希算法,如图3,将数据块的逻辑地址计算出KEY值。并将计算出来的KEY映射到哈希环上,在哈希环上划分了N段(Partition),每个Partition对应一个硬盘,并根据出partition主和osd节点的映射关系ioview,和partitio主备对应的osd关系,得到该数据块的路由,如图4。在写入的时候,采用强一致性,即当主和备副本都返回写成功后,才认为这个IO写成功了。读IO时只读主副本,当主副本故障的时候,会在备副本中选举出主副本。目前,一个资源池可以支持2000块硬盘。图19&&&&&& 操作系统看到的连续的数据逻辑地址(LBA),实际上被打散到资源池内所有硬盘上了,类似所有硬盘都做了raid0,这样就利用了所有磁盘的性能,提高了存储的性能。操作系统实际是直接读写物理磁盘的块,并没有封装额外的文件系统,是一个raw设备。OSD是一台插了较多硬盘的X86服务器,我们采用的是12块SATA 3T的硬盘作为数据的持久化存储介质。如果VBS不承载在OSD上,那么OSD服务器的计算压力实际上很小,也没有必要配置计算能力很强、内存配置很高的服务器。上一篇文章计算过,12块SATA盘提供的iops或吞吐量其实很有限,需要配置SSD作为缓存,加速存储的性能。由此看来,分布式存储的性能是由SSD的性能和热点数据计算算法决定的。和一般存储不同,一般分布式存储的写性能会好于读性能。主要是主和备副本写入SSD就返回成功了,而SSD什么时候写入硬盘,怎么写入硬盘,客户端是不知道的。而读数据的时候,如果数据是热点数据,已经在缓存在SSD上,性能会很好,如果没有在缓存中,就需要到硬盘中直接读取,那性能就很差了。这也是当分布式存储在初始化的时候,测试性能指标不如运行一段时间后的指标。所以测试分布式存储有很多陷阱,大家要注意。&&&&&& 为了提高存储的安全性,达到6个9以上的安全性,我们采取的是通行的3副本(2副本在96块盘以下,可以达到6个9)。副本可以根据实际情况设置成为在不同机架、不同服务器、不同硬盘的安全级别。当磁盘或主机故障,会被MDC监控到,会选举主副本、踢出故障点、重构副本等操作。为了确保数据的安全,副本重构的时间很关键,我们要求,每T数据重构时间不超过30分钟。为了确保数据重构流量不影响正常存储IO访问流量,实现快速数据重构。我们没有采取华为推荐的网络方案,而是采用环形虚拟化堆叠的方案,交换机间的堆叠链路采用40G光路,如图5。将存储的重构流量都压制在存储环形网络中。交换机到服务器采用2*10G连接,可以根据情况采用主备或分担的模式。图20&说过了“块”存储,再简单了解一下“对象存储”。对象存储是在同样容量下提供的存储性能比文件存储更好,又能像文件存储一样有很好的共享性。实际使用中,性能不是对象存储最关注的问题,需要高性能可以用块存储,容量才是对象存储最关注的问题。所以对象存储的持久化层的硬盘数量更多,单盘的容量也更大。对象存储的数据的安全性保障也各式各样,可以是单机raid或网络raid,也可以副本。对性能要求不高,可以直接用普通磁盘,或利用raid卡的缓存,也可以配些SSD作为缓存。我们现在使用单机35块7200转4T SATA盘+raid卡缓存加速的自研对象存储,并计划在今年使用60块7200转8T SATA盘。即每台服务器提供480T的裸容量。Ceph和google基于GFS的存储就是典型的对象存储。Ceph是目前最为热门的存储,可以支持多种接口。Ceph存储的架构和华为的FusionStorage异曲同工,都是靠“算”而不是“查”。 一种是为数众多的、负责完成数据存储和维护功能的OSD,另一种则是若干个负责完成系统状态检测和维护的monitor。OSD和monitor之间相互传输节点状态信息,共同得出系统的总体工作状态,并形成一个全局系统状态记录数据结构,即所谓的cluster map。这个数据结构与特定算法相配合,便实现了Ceph“无需查表,算算就好”的核心机制以及若干优秀特性。图21但数据的的组织方法是不同的。首先ceph的核心是一个对象存储,是以对象为最小组织单位。1、首先文件是被映射成为一个或多个对象。2、然后每个对象再被映射到PG(Placement Group)上,PG和对象之间是“一对多”映射关系。3、而PG会映射到n个OSD上,n就是副本数,OSD和PG是“多对多”的关系。由若干个monitor共同负责整个Ceph集群中所有OSD状态的发现与记录,并且共同形成cluster map的master版本,然后扩散至全体OSD以及客户端。OSD使用cluster map进行数据的维护,而客户端使用cluster map进行数据的寻址。Google三大宝之一的“GFS”是google对象存储的基础。图22核心不同是数据的组织架构:master服务器(即元数据服务器)保存了文件名和块的名字空间、从文件到块的映射、副本位置,由客户端来查询。是一个典型的信令和媒体分开的架构。&六、分布式存储存在的问题分布式存储一般情况下都是靠“副本”来确保数据的安全性和完整性。每块盘记录的数据内容都不一样,当某一块盘出现问题,都需要从其他不同盘内的数据块中进行快速的数据重构。数据重构是需要时间的,如果大量盘同时故障,将会发生什么?另外,OSD的扩容,也会导致数据的迁移,也会影响存储。分布式存储一般都采用副本的方式来确保数据的安全性。写入磁盘前不需要进行额外复杂的计算,就可以将数据写入磁盘,是最快速的方式。是一种空间换时间的方法,即想得到较好的存储性能,就采用副本的方式。当有副本出现丢失的情况,系统就会启动数据重构。一般情况下,用于生产的分布式存储采用的是3副本。副本一般放置在不同机架、不同服务器主机的硬盘上。3副本就是放置在3台不同的服务器的硬盘上。而每个用户的数据是由很多个副本均匀的分布在存储资源池内的所有主机上的。所以,可以认为任意一台服务器会存储着所有用户数据的某些数据副本,一台服务器出现故障,会影响所有用户。从理论上来说,副本方式可以允许n-1台的服务器出现故障,n是副本数。比如3副本,不管这个分布式存储资源池内有几台服务器组成,就只能允许2台服务器出现故障。2台服务器出现故障,其实这个存储就很危险了。当数据的持久化层OSD出现故障的时候,必须启动副本的恢复工作,即要在短时间内恢复完整的副本数。不同存储的结构、算法不同恢复的时间长短也不一样。但从副本恢复所使用到的磁盘、网络等基础设备是一样的。今天我们从基础角度上来分析,看看副本的恢复到底需要多少时间和当新增加OSD节点需要多长时间,并看看因为采用了X86服务器带来的隐患。&我们在实验室内做了实验,具体了解一下:试验环境:2台万兆交换机、4台X86服务器(12块3T 7200转 SATA盘+1块1.2G PCIeSSD)。包括所有副本在内,每块磁盘有1T数据,共有48T数据。实验一、无IO情况在,拔出一个磁盘实验二、在存储上建立了4个360G的虚拟卷,加载少量的IO,即8K随机读写,队列深度为1,总iops为2600左右。在拔出一个磁盘后,在15分钟后(可配,延迟15分钟是为了防止无操作、无报警等),系统开始对缺失的副本进行重构,得出结果:图23(为了便于计算1T=1000G)分析:在实验分布式存储中,原来共有数据48块*1T数据,拔出1块磁盘数据重构完成后,还是48T数据,即每块盘增加了(1T/47)*GB的数据。&在无IO情况下12分钟内重构了1T的数据:网络速度:(1*1000 )/(12*60)=1.39GB/s*8=11Gb/s,也就是说在无IO的情况下,网络的总的流量是11Gb/s。其中3台服务器网络速度是2.84Gb/s,1台被拔出硬盘的服务器流量是2.57Gb/s。为了计算方便,平均每台服务器为2.75Gb/s,网络利用率是27.5%。磁盘写入速度:21.28*)=29.56MB/s。&在少量IO情况下24分钟内重构了1T的数据:网络速度:(1*1000 )/(24*60)=1.39GB/s*8=5.5Gb/s,也就是少量IO的情况下,网络的总的流量是5.5Gb/s。平均每台服务器为是1.38Gb/s。磁盘写入速度:21.28*)=15MB/s。&实验现象:1、无流量压力情况下数据重构速度即每块盘最大写速度为30MB/s。但随着IO的增加,写的速度也会越来越慢。2、虽然每个服务器接入网络是10Gb/s,但受到存储软件的控制,重构时最大网络利用率近30%。在有IO的情况下,重构时间迅速增加。主要是为了不影响正常IO的处理,软件对副本重构的速度进行了控制。&在实际生产中,用于副本重构的网络利用率控制在5%以下,对存储正常的IO不会产生影响。由此计算:29.56M/(27.5%/5%)=5.37M,即在10G接入网络下,每台服务器重构流量在0.5Gb/s( 62.5MB/s)和每块磁盘读写数据在5MB/s以下,数据重构是安全的。副本恢复的过程,实际上是从现有的磁盘中读取需要重构的副本,再根据一定的规则写入某些磁盘的过程。每块盘承担了读取副本,也承担了写入副本的职责。也就是说平均每块磁盘读2.5M,写也是2.5M。&从这个角度上看,每台服务器配置12块硬盘(60MB/s)是能产生读写能力和网络( 62.5MB/s)能力匹配。服务器接入带宽越大,可以配置的硬盘数量就越大。小结:如果主机和磁盘比大于等于12:1TB数据重构时间=1000*8/(0.25*n)&&&& &n: 服务器数量比如 57台12块磁盘的2P资源池重构1T数据的最短时间=(1000*8)/(0.25*57)=560秒。如果主机和磁盘比小于12:1TB数据重构时间=/(2.5*m)&& m:参与重构磁盘数量&如果1台12块盘的服务器故障,最大重构36T数据,需要最短时间是342分钟,5.7小时。结论:服务器或参与重构的磁盘数量越多,重构的速度就越快&我们继续实验,在数据重构完成后,重新插入这块盘,我们会发现,副本又开始重构了,但这次数据是搬家,并不生成新的副本。是因为系统认为插入了新盘,数据需要均衡导致的。分布式存储采用的是“共产主义”,扩容服务器的数量可以线性的增加存储的能力,但新扩容的磁盘并不是只接受新的副本数据,而是需要搬迁写入平均值大小的“老”副本数据。实际上每次非正常IO的副本的写入,都伴随着其他节点副本的删除。频繁的写入、删除对磁盘的寿命有较大的影响。我们再看看实验结果:图24& & & & 在无io时,磁盘写入的速度是68MB/s,68MB/s其实也已经达到SATA磁盘平均写入速度的最大值的正常范围。这样,平均每台服务器网络中平均贡献68*8/4=136Mb/s流量。数据副本的搬迁是一个动态过程。磁盘里的数据副本一定有1/3的数据是主副本,可能会被正常的IO读取到,所以新加入的磁盘也不是全力进行数据搬迁,也和其他磁盘一样,只能用有限的能力应付副本迁移。测试结果上看,在少量IO业务下测试磁盘写速度为45MB/s, 平均每台服务器网络中平均贡献90Mb/s。在无IO的情况下,数据完成重新部署居然需要4.3小时了。大家一定没有想到吧,因为这次是47块盘共1T的数据搬到1块磁盘上,就像47个人喂1个人吃饭,饭总得一口一口吃,所以增加磁盘的时候,在大部分情况下和网络的速度无关,和磁盘写入的速度直接相关。上面提过,为了不让副本迁移不影响正常IO,每台服务器可以提供主机网络的5%的带宽,即62.5MB/s,磁盘读写为5MB/s来处理副本的迁移。&如果主机和磁盘比大于等于12:一起重构的磁盘数量=62.5*n/m& n:服务器的数量&m:磁盘写入速度如果主机和磁盘比小于12一起重构的磁盘数量=5*n/m& n:磁盘的数量&&m:磁盘写入速度&如果m=5M,n= 57, 可以一起写入磁盘=712块 &1-712块磁盘,1T数据迁移完成最长需要55.56个小时。可以这样认为,在目前2PB容量的分布式存储,在不影响业务情况下,如果扩容在2PB以下,数据副本迁移1TB需要56个小时。&大家一直在问我,分布式存储的风险在哪里。风险就是因为多副本特性所引起的。首先不管这个集群有多大,最多可以有n-1台服务器出现故障。一般是3副本,就是允许有2台服务出现故障。当出现故障的时候,就进行了数据重构,重构副本的时间相对较短,在2P的存储,每T数据恢复需要10分钟,恢复时间是以小时计。但是2台服务器同时出现故障,本身存在的风险就很大了,应尽量避免。当故障的服务器恢复了,重新加入存储资源池,副本就需要迁移,那恢复的时间需要用天计算。所以当存储的OSD出现故障到完全恢复的时间很长。但在正常情况下,还是能接受的。但非正常情况呢?怎么会出现非正常情况呢?因为分布式存储常用的是X86服务器,x86服务器是有正常使用周期,大约是5年。同一批次的服务器的寿命是差不多的,在使用寿命的末期,服务器出现故障的概率是很大的。1台服务器发生故障,副本重构,可能会是最后一根稻草,导致服务器群的“老太太们”压力发生变化,也出现故障。一旦发生2台以上的同时故障,存储就会出现严重故障,存储就只能停止服务,运气好可以离线恢复数据,运气不好,副本完全丢失,数据完全不可用了。大家知道,在资源池里,存储一旦停止服务,整个资源池就瘫痪了。这种情况一定会发生,只是早晚的问题,所以要提前干预,不能让这样的事情发生。&七、解决的办法于是定期更换服务器,别让服务器变成“老太太”,不断补充新鲜血液。但是,更换服务器和扩容不一样,扩容的时候可以一下子增加几十台服务器,用个2天时间就可以静悄悄的完成扩容。更换服务器的过程是先将服务器退出服务,再增加服务器的过程。原来服务器上有多少数据,就需要搬迁多少数据,比如原来服务器每块有2T数据了,就需要搬迁12*2T的数据。为了确保存储的正常使用,最好只能同时退出n-2台服务器,并增加相应的服务器。比如3副本,就只能先退出1台服务器,再增加1台服务器。换1台服务器需要2*2=4天时间。最多同时换2台,但风险很大,万一更换的过程中出现1台故障,那这个存储系统就挂了。所以一台一台更替是最妥当的方法,57台服务器全部替换完成,不停的干,顺利的话,也需要大半年时间,算上节假日1年可能都做不完。这个过程漫长而复杂,充满的变数,却一定是可行的。当然划小分布式存储的故障域,在一个故障域的服务器减少,对应替代服务器的工作时间相应减少了,风险也相应减小。但是分布式存储是云计算快速发展后对存储性能、容量带来新需求发展起来的。几百台服务器共享一个存储,运行几千、上万台虚拟机,从这个角度考虑,分布式块存储最好是一个可以无限线性扩容的存储系统。但是就是因为有了上面的问题,只能将存储资源池划分成为一个一个较小的故障域。这个故障域的大小我们认为在裸容量在2P(有效容量666T)、IOPS在100万次以上是可以满足资源池的需要,即在60台服务器左右。分布式块存储实际上是来替代所谓高端FCSAN存储的。小集群替代低端小容量的FCSAN在价格上、性能上都没有优势。如果只是服务器出故障,而磁盘是正常的,还有一种比较快速的人工介入办法。这个办法是一种应急方案的延伸。实现的原理就是利用检测到磁盘故障后15分钟后才启动副本的重建。如果15分钟内磁盘又恢复了,那在故障时间内原来需要写入的副本是需要追溯的。也就是说在这15分钟内,其实有些副本只写了2个,还有一个1副本原来要写到这个磁盘中的。如果15分钟内原磁盘恢复了,就将增量数据补充进去,如果15分钟不恢复,就进行副本重构。当然这个时间长短是可以配置,但不是所有的分布式存储系统都有这个功能。不少存储系统一检测到磁盘或服务器不在线,就会立即启动副本重构,本质上就是没有“追溯”。知道这个原理了,下面的事情就简单了。发现整台服务器发生故障后,将服务器设置成为“维护/更换”模式,就不受15分钟的限制了(可能需要新开发这模式)。准备好装了系统的服务器(不插入持久化层的磁盘),当主机发生故障或更换的时候,人工将故障服务器里的磁盘插入备用服务器里,加入存储系统中,提供服务。这个服务器,在写入新数据的同时,还要追溯故障时间段的数据。这种方法是应急方案的延伸,可以快速解决非磁盘故障的情况,但并不根本解决问题。因为如果这插拔磁盘的过程中,如果有一块盘损坏了,又回到以前数据搬迁慢的问题上了。而且只换主机,不换磁盘,老化问题还是存在,还是不能高枕无忧。全SSD分布式存储的拥护者会兴奋了,因为用全SSD的好像可以提高速度,加快这个过程。用全SSD的同时,最好也提高服务器接入的带宽,比如用40G网卡或用IB网络,不要让网络成为新的瓶颈,但分布式存储带来的隐患不可能根除,只是快了,问题还是一样。其实还有一个比较严重的老化问题——作为缓存的SSD。SSD作为整个存储“性能担当”在存储中起到核心作用。但SSD的写寿命是一个突出问题,怎么样在线更换SSD也是一个需要解决的问题。分布式“块”存储存在这样的风险,服务器加载更多磁盘的对象存储和文件存储类似的问题更突出,风险更大。存储内的数据一定要有价值,因为存储他们的代价很大。但是现在存储的使用是一种多多益善的观念,只管写,不管删,不管什么需求都往块存储里写等等。存储按需选择类型和容量是目前存储使用中遇到的最普遍问题,这个问题将来详谈。&分布式存储当下不存在风险,而远期的风险巨大!&&&&&&&&&&&
TA的最新馆藏[转]&
喜欢该文的人也喜欢

我要回帖

更多关于 存储器的存取速度 的文章

 

随机推荐