分布式存储有块存储、对象存储、文件存储有不同的开源项目如Ceph、GlusterFS、Sheepdog、Swift,还有不同的商业实现如Google、AWS、微软、金山、七牛、又拍、阿里云还有Qingcloud等思路或多或少都有些不哃,可选的硬件种类也很多似乎可选的东西太多了,而且各有优缺点
选择的多样性是好事,同时也对技术选型人员的知识和能力提出叻更高的要求我们提出了有关分布式存储的三个基本问题解决三个基本特点,邀请领域内各路专家来分享他们的解读
对于一套分布式存储的方案,怎样评估它是好还是不好
如何对分布式存储的不同实现进行分类?
分布式存储中的“数据可靠性”是如何计算的
InfoQ:无论昰在做方案的选型,还是实现一套存储系统权衡的因素主要考虑哪些?有没有一套比较全面的考量/评估方式来决定哪种存储方案更适合哪种场景换句话说:当你去看一个存储方案的实现,无论是看代码还是实测你如何评估这套方案哪里好,哪里不好
其实评价一个存儲方案好和不好,只有一个客观的标准那就是是否能满足用户的需求。不站在这个立场上思考这个问题解决三个基本特点就会将技术淩驾于用户需求之上,而技术应该是服务于用户需求的
那么我们可以简单的剖析一下用户对存储的需求到底是什么。从青云的角度来说有以下几点是用户需要的:
运行或在线系统需要高性能。这个不用多说用户的业务数据几乎都会存储在数据库里面,没有一个用户会覺得数据库性能不重要
离线或备份数据需要高容量低价格。这部分数据通常量很大但是对性能要求不高,对不经常用的东西也不希望負担高额成本
所有的数据都必须是可靠的,绝对不能丢这是用户对于存储的容忍底线,所有负责任的企业都会将可靠性放在最重要的位置上在这个基础上能达到多高的性能就看技术实力了。
所以从上面的分析来看之所以没有银弹方案,是因为用户对存储的需求差异佷大不同的需求需要用不同的方式来解决。这就好像现在机械 硬盘已经存在这么多年了磁带依然没有消失的原因,因为它用一种最廉價的方式解决了大容量离线数据的存储问题解决三个基本特点虽然它是最慢的。
首先对象存储和文件存储的区别是不大的存储的都是┅样的东西,只是抛弃了统一的命名空间和目录树的结构使得扩展起来桎梏少一些。
独立的互联网存储服务一般都是做对象存储的因為块存储是给计算机用的,对象存储是给浏览器等HTTP客户端用的独立服务所提供的存储系统,访问都来自互联网自然是做对象存储;与の相对应,大部分类AWS的主机服务商都会提供一个块存储服务搭配主机服务
同一个服务商同时提供两个服务是有好处的,除了提供的服务仳较全这个优点以外对象存储还可以支撑块存储的快照、主机的系统镜像存储等应用,可以相互结合的
权衡的因素有很多——可靠性偠求、可用性要求、时延要求、一致性要求、使用模式相关要求(包括请求大小、QPS/IOPS、吞吐)等。
对于块存储要求的访问时延是 10ms 级的,因為给虚拟机用的传统硬盘也是10ms 级的时延,请求尺寸都很小但qps(iops)可能会很高,那么在这种情况下:
异地多中心是不现实的存储要和主机尽量接近,相应地可靠性必然会有所打折
强一致副本不会过多强一致要求对时延有影响
对于对象存储,要求的访问时延是 100ms - 1s 级的请求一般是中到大尺寸,低 qps 的在这种情况下
可以用更多的分散副本数来换取更高的可靠性,但过多副本增加维持一致性的难度需要折衷
叧外SSD随着成本降低,在块存储里逐渐成为主流了以便提供更好的IOPS,AWS这个月开始创建的EBS卷缺省就是SSD的了。
对于评价一个实现首先是看適合不适合这个用途,然后看这个方案有没有显著的缺点是否有严重的影响,然后成本之类的也是一个因素做软件的人总觉的用便宜硬件实现高大上的服务才值得吹牛,呵呵
我得补充一点就是,做存储这东西是需要良心的一致性这种东西有的时候用户是很难看出来嘚,偶尔一个程序出错了你一般不会怀疑是硬盘上存着的数据坏了,做存储服务的人还是要尽量避免出现这种情况的底层存储服务(囿别于数据库)的一致性是一种很难被用户观测到的,但是如果一个实现根本没达到应有的一致性比如块服务,只写了一个副本就返回給应用说写成功了这样是不太道德的,反正我个人坚持应该(EBS块存储)应该写两个副本再返回在这个约束之内来优化。
也就是说我嘚观点是,先看是否满足约束然后看架构是否恰当,最后看细节流程的优化
InfoQ:目前分布式存储从应用场景、实现等层面来看,是如何汾类的
分布式存储的应用场景相对于其存储接口,现在流行分为三种:
对象存储: 也就是通常意义的键值存储其接口就是简单的GET、PUT、DEL和其怹扩展,如七牛、又拍、Swift、S3
文件存储: 通常意义是支持POSIX接口它跟传统的文件系统如Ext4是一个类型的,但区别在于分布式存储提供了并行化的能力如Ceph的CephFS(CephFS是Ceph面向文件存储的接口),但是有时候又会把GFSHDFS这种非POSIX接口的类文件存储接口归入此类。
按照这三种接口和其应用场景很容易叻解这三种类型的IO特点,括号里代表了它在非分布式情况下的对应:
对象存储(键值数据库):接口简单一个对象我们可以看成一个文件,只能全写全读通常以大文件为主,要求足够的IO带宽
块存储(硬盘):它的IO特点与传统的硬盘是一致的,一个硬盘应该是能面向通鼡需求的即能应付大文件读写,也能处理好小文件读写但是硬盘的特点是容量大,热点明显因此块存储主要可以应付热点问题解决彡个基本特点。另外块存储要求的延迟是最低的。
文件存储(文件系统):支持文件存储的接口的系统设计跟传统本地文件系统如Ext4这种嘚特点和难点是一致的它比块存储具有更丰富的接口,需要考虑目录、文件属性等支持实现一个支持并行化的文件存储应该是最困难嘚。但像HDFS、GFS这种自己定义标准的系统可以通过根据实现来定义接口,会容易一点
因此,这三种接口分别以非分布式情况下的键值数据庫、硬盘和文件系统的IO特点来对应即可至于冷热、快慢、大小文件而言更接近于业务。但是因为存储系统是通用化实现通常来说,需偠尽量满足各种需求而接口定义已经一定意义上就砍去了一些需求,如对象存储会以冷存储、大文件为主
实现方面,主要有两层区别:
系统的分布式设计:主从、还是全分布式或者是兼而有之目前现在存储系统因为一致性的要求,以主从为主
底层的单机存储:一种昰依赖本地文件系统的接口,如GlusterFSSwift,SheepdogCeph。一种是依赖块接口的目前只知道Nutanix是使用这个的。最后一种是依赖键值接口的目前应该只有Ceph是支持(Ceph支持多种单机存储接口)。第一种依赖文件系统是因为分布式存储系统本身已经够复杂实现者很难从上层一直到底层存储都去实現,而本地文件系统已经是一个通用化并且非常成熟的实现因此分布式存储系统绝大部分(上述提到的都应该是)都会直接依赖本地文件系统。第二种接口目前只知道Nutanix是支持的(传统的存储厂商的存储产品一般会使用这种方式)这种接口也就是比第一种去掉了文件系统層,实现一个简单的物理块管理即可第三种它的主要原因是“存储定义”和对象存储的普及,希望硬盘来提供简单的键值接口即可如唏捷的Kinetic
API,Fusionio NVMKV这种接口另一方面是闪存厂商非常喜爱的,因为闪存的物理特性使得它支持键值接口比快接口容易得多目前Ceph是支持这种接口,而希捷和华为最近推出了IP硬盘听说已经实现了Swift上的原型。
从这里可以发现分布式存储系统是在传统的单机接口上重新包装了一层,嘫后实现三种类似的接口
策略方面,三副本、多AZ六副本和网络RAID都是一类的它们都是指数据的分布策略来提供数据可用性,通常来说前兩者情况就是数据的多个副本分布在所有服务器的几个中也就是只要超过副本数的服务器挂掉,存储系统就面临部分数据不可用的情况网络RAID是为了避免这种情况,比如在1000台服务器的情况将其分成10台一组的100组,这样同样是一份数据(Data1)的三个副本都只属于某一个组它鈈可用只当1组内(10台)中超过3个台机器不可用时才会发生,这样概率会小非常多
EC是一个类副本策略,它可以理解为增强版的复制更少嘚副本可以达到更好的数据可用。
硬件方面SSD,SASSATA和内存的组合是为了提供数据访问的性能。千兆、万兆甚至Inifiniband是组合是为了提供网络传输嘚性能
如果我们按存储的业务逻辑分,那么可以分为:键值存储(Key-Value Storage)、文件系统(File System)、数据库(Database不是很严谨,只是作为所有支持多键徝的存储的统称)、消息队列(MQ)等等按这种分类方法存储的种类是无穷尽的,我曾经说过
“存储即数据结构”表达的就是这个意思。数据结构无穷尽存储也会无法穷尽。块存储我们很少把它划分到上面的分类中因为它是虚拟存储设备,是为 VM 服务的一个东西并不矗接面向用户业务(用户不需要调用块存储设备的 api 来完成业务,当然如果我们把 VM 也认为是一个业务系统的话块存储也勉强可以作为一种特定的数据结构存在)。对象存储(Object
Storage)是键值存储(Key-Value Storage)的特例它假设Value是文件,尺寸范围可以很大(比如七牛可以支持文件大小从0字节到1TB)如果要对对象存储做进一步分类,我能够想到的就是按实现方案来分类比如按冗余方案来分,可分为多副本、RAID、纠删码等等;或者峩们按一致性方案分可以分为主从结构和对等结构等。
不会有什么存储方案能够一统天下不同业务系统的场景需求不同,对存储的诉求会不同选择自然会不同。基于纠删码的存储系统复杂性远高于三副本的存储系统。从易维护的角度如果业务对存储成本不敏感,那么人们自然而然会选择三副本的方案
除了开源服务外,这些私有的实现都没有太公开自己的实现不同的实现确实差异很大。但另一方面因为有共同的目标常常有很多细节是做得差不多的,比如很多对象存储都会把小对象放到一些预分配的大块存储区域里然后定期莋compaction,来提高存储效率、避免文件系统碎片等
对于块服务,有些实现是比较简单直接的直接把存储分成块,用户有申请就调度到某几囼机器上,分配一些块组成卷给用户用,而有些实现是比较高层的会先构建一个底层的分部式存储系统,然后再从中分配块给用户用后者技术含量更高一些,但一般前者的实现都属于简单直接型实际效果反而更好(性能、故障处理等)一些。
InfoQ:所有做云存储的都表礻数据丢失是不可接受的但数据丢失的概率——即理论上的数据可靠性(reliability),不同方案的计算方式是不同的你们是怎么做的,或者现茬有哪些比较成熟的资料描述这个计算方法的
实际上这个计算是需要依赖于存储系统本身的。我们使用CephCeph的优势是提供了一个叫CRush算法的實现,可以轻松根据需要来规划数据的副本数和高可用性参考Ceph提供的模型定义来规划自己的。这是我的同事朱荣泽做的故障计算这个計算只针对副本策略,并不适合使用EC(擦除码)的情况
硬盘发生故障的概率是符合泊松分布的。
我们对丢失数据是不能容忍的所以只計算丢失数据的概率,不计算丢失每个object的概率
计算1年内任意R个OSD发生相关故障概率的方法是
1年内OSD故障的概率。
以上概率相乘假设结果是Pr
鈳靠性的定义可以有不同,比如有人会定义为:假设整个系统有 L 个对象在 1 年内会损失 m 个对象,那么可靠性为 1 - m/L我在我那篇文章中的定义昰:整个系统有 L 块硬盘,1 年内丢失数据的概率是多少(而不管丢失了多少个对象)
沿用文章中的可靠性定义,数据可靠性的计算涉及到鉯下几个量:
集群规模-总硬盘数目(L)
单盘可靠性(p:在t时间内损坏的概率)
我的计算方法是先计算这L块硬盘在t时间内同时损坏M+1块硬盘嘚概率是多少(Pt,也就是丢失数据的概率当然有细心的网友说t时间内同时损坏M+1块盘不一定会丢失数据,这点当然是正确的但是这个丢夨数据的概率虽然不为1但是非常接近1,而且此时对软件系统来说已经是失控状态为了简化计算假设为1),然后把时间拉长到1年(T)的数據丢失概率(P)这个拉长是非常简单换算公式:
所以关键是计算 Pt(这L块硬盘在t时间内同时损坏M+1块硬盘的概率)。我们扩展一下用 Pt(i) 表示 t 時间内有且仅有 i 块盘损坏的概率。前面的 Pt 实际上是 Pt(>M)而不是 Pt(M+1)。不难得出:
好了我们就剩下计算 Pt(i) 了。这个概率的计算比较常规:
至此整个計算过程完成不过有一个细节需要说明下,由于以下两个原因你无法用计算机常规的浮点数计算来得到 P:
C(L,i) 值会很大甚至会超过 float64 浮點类型的最大值(约为1e308),用浮点运算最终会变 Inf(无穷大)
p 非常小,这会导致计算过程精度损失非常大计算的累计误差无法忽略,答案和理论值大相径庭
所以如果你真要去算这个概率,需要用无损计算的数学包
我们这个概率的计算和RAID是类似的,我们可以将RAID的概念延伸一下其实RAID的本 质就是replication,通过多个副本来解决一个或者多个节点出问题解决三个基本特点造成的影响所以不管是本机的副本,还是跨網络或者跨地域的副本本质上都是在用replication做冗余。
其实只是丢数据的概率问题解决三个基本特点没有云存储服务可以承诺绝不丢的。国內有个问题解决三个基本特点就是——如果我在服务条款里说了可能丢数据,那用户就不愿意用了(“云还丢数据!”),竞争对手嘚公关也要找上门来了;可是丢数据的 case 总是可能存在的那么,一旦丢了就是没有尽到告知义务而且还是会被炒作(“云还丢数据” again),但实际上这是个 SLA 嘛生意上的事,最后要用钱解决的嘛
AWS的两个主要资源层存储服务是 EBS 和 S3,后者是对象存储服务强调数据可靠性,承諾11个9的 Durability据说实际能达到更高;而EBS承诺的是年平均故障率(AFR),一年中发生块设备故障而导致卷无法使用的概率这个要求实际上不高的。
对于存储服务对象存储可以视为在线数据的最终存储方案,要保证更高的可靠性而EBS是半永久存储方案,只有结合备份方案、多副本方案或者快照才可以保证高可靠性的,教育用户是云服务行业不能回避的任务骗用户说我绝对可靠是不行的,出来混是要还的