面对着业务的发展,不管是在线,近线还是离线系统,其所需要的存储规模以及存储成本,成倍上涨。如果还是采取传统的分散式存储管理方式,不但带来高昂的管理分散式存储的成本,而且还会增加存储成本。
因此,我们极需要有一种即高效且省成本的数据存储以及存储管理方式。自然的,我们把目光聚焦在了分布式存储系统上。
从目前行业发展趋势来看,各大互联网公司都设计或者维护了自己的分布式存储系统。如Google的GFS(Colossus 为GFS第二代分布式存储系统),Facebook和LinkedIn的HDFS等。因此,分布式存储也是大势所越趋,目前社区上非常火爆的开源分布式存储软件Ceph,就是OpenStack的一朵奇葩。各大传统厂商如Intel,Red Hat,San Disk等纷纷加盟,正愈演愈烈,有望成为存储领域的“Linux”。
我们也紧跟开源社区,不断吸收其优秀成果,并对Ceph做了大量的研究,测试和验证。另外,我们根据业务场景,也进行了深入的源码开发和软硬件优化,在分布式存储开源领域正与社区积极合作,为集团业务的发展赋能。
分布式存储系统所具备的优点就是为了克服传统存储方式的缺点。那么,它将会给我们带来哪些收益呢?
分布式存储系统所带来的收益主要体现在以下几个方面。总体上来讲,主要是降低存储成本,同时也提高了资源的分配效率,助力计算资源的弹性调度: 2.1解除机型配比
一般性的,我们将服务器分为两部分,计算资源和存储资源。计算资源如CPU和内存,计算资源的特点就是无状态,资源分配比较灵活。存储资源有状态,需要保证数据的一致性和持久性,资源分配比较固定,会涉及到数据的迁移。如果数据量太大,就会遇到迁移性能的问题。
传统的存储方式,是单台服务器类型的,将计算资源与存储资源(HHD和SSD等存储设备)绑定在一起。因此一台机器CPU,内存与存储设备比值都是固定的。这带来的一个问题,就是我们会比较频繁的改变我们的机型,因每年我们的计算资源与存储资源的配比都在变化,业务数据的增长非常快。这也在某种程度上提高了每年采购机器的成本。
引入分布式存储系统后,解除了这两者紧密耦合的现状,使得降低存储成本成为了可能。计算资源和存储资源解耦后,各自可以按不同的策略进行过保,在一定程度上降低了成本。 2.2解决存储碎片
传统分散式的存储模型,必然会有存储碎片问题的存储。因为每台服务器都会为线上业务预留一定的存储空间,以满足将来业务数据增长的需要。但是采用预留空间的方式会有一个问题,就是我们无法准确的评估真实的实际空间需求,往往预留的会比较多,业务实际需求与预留空间这两者的差距就是存储空间浪费量。
这些服务器残留了独立的10G,20G等空间碎片,在一定程度上也并不能满足业务实例申请的规格,但将这些碎片合并在一起就能满足业务所需。
引入分布式存储系统后,大大减少这种碎片,业务实际的数据存储空间按需进行动态分配。我们引入数据增长趋势分析,每天或者每周进行存储在线动态扩容,以提高管理效率,降低存储成本。 2.3计算资源弹性
传统资源配置下,我们的计算资源调度水平受限于单台机器的存储容量。在制定Docker容器化规格时,连同存储容量一起考虑,其调度和资源分配算法异常复杂。当CPU,内存以及存储容量这三者在某种程度上发生冲突时,往往会牺牲一定的存储资,来达成Docker实例规格的妥协。
将计算资源与存储资源分离后,计算资源得到解脱。我们在安排机器的过保时,采用不同的策略,降低机器采购成本。另外,计算资源是无状态的,独立之后,进行容器化,就可以方便的进行调度,提高效率。 2.4解决差异化需求
某些新星业务,往往会呈现爆发式增长。自然而然,其数据量也会呈跳跃式的爆炸。此时对存储的规格的需求就会比较大,因为业务短时间内往往来不及做架构优化,或者做数据分片来降低单机的数据存储容量。这会给传统的存储模型带来非常的挑战,因为传统的分散式的单台服务器的存储容量已经不能满足需求。
分布式存储系统破除了这种大存储容量实例规格的天花板限制,业务不再关心底层存储的实现,我们根据业务数据的增长趋势分析,动态扩展存储空间。
尽管分布式存储有上述的诸多优点,然而如何设计其高可用性,如何减少数据丢失的概率,是摆在我们面前必须要去克服的问题。那么我们又是如何来架构和设计的呢? 3.1数据丢失
在分布式文件系统中,为了防止单机故障而造成数据丢失,往往会引入多个数据副本,我们称之为replica set。此replica set中数据的副本个数用R来表示。一般的,R等于3,就表示是这份数据的存储份数是“3”,也就是我们通常所说的 3-way replication。
在随机的模式下,有可能replica set的3份数据位于同一个RAC中,那么当此RAC掉电就会导致数据丢失,对线上业务造成影响。随着集群规模的变大,如果有超过1%的数据节点遭遇断电,并且断电之后又有一部分机器重起失败,或者进程异常导致数据文件损坏;那么其影响都将随着集群规模的增长而变得异常严重,成为分布式存储系统致命的问题。
当然,我们可能通过增加数据的副本数即“replica set size“,来降低数据丢失的概率。又或者提高底层IDC以及网络的高可用性,减少断网或者网络故障发生的概率。但是这些方法都是绕开问题的本质来优化的,另外带来的存储成本的增长也是不能接受的。
早期,Facebook和LinkedIn在使用HDFS时,也同样面临这样的问题,也做了这方面不少的验证和测试。最终较为一个合理的方案就是通过合理安排replica set中数据存储的位置来降低数据丢失的可能性。 3.2数据散射度
为了能够更好的理解数据副本存储位置(data locality),我们引入数据散射度(scatter width)的概念。怎么来理解数据散射度?
假设一个集群,有N个节点,数据副本replica set size为R,那么数据散射度最差的情况就是从N个节点中任意取R个的组合数,也就是C(N,R)。我们假定N为“9”,R为“3”。
同时,我们定义三个copy set(存放的都是不同的数据):{1,2,3},{4,5,6},{7,8,9}。任意一组copy set中存放的数据没有重复,也就是说一份数据的三个副本分别放置在:{1,4,7}或者{2,5,8}或者{3,6,9}。那么这个时候,我们称之为其数据散射度S为“3”,远小于随机组合的C(9,3)。
随机组合时,任意3台机器Down机都会存在数据丢失。而采用Copy Set方案后,只有当{1,4,7}或者{2,5,8}或者{3,6,9}其中的任意一个组合不可用时,才会影响高可用性,才会有数据丢失。
综上可知,我们引入copy set的目标就是尽量的降低数据散射度“S“。但是现实远非这么简单,当我们降低数据散射度后,其数据恢复速度变小,也就是说恢复时间变长。因此,我们必须在数据散射度“S”和恢复速度中找到一个平衡。
一般地,业务统一用N个“9”来表示一个分布式系统的高可用性。一般业界做得好的,都已经能达到9个“9”。那么,我们的分布存储系统又如何来设计,又能达到多个“9”呢?
在设计高可用架构之前,我们先来看一下Ceph的数据存储的拓扑结构,即CRUSH MAP。 4.1Ceph OSD Domain
Ceph默认的OSD节点bucket是基于Host的,也就是说取决于一台机器上存储设备的数量。如下图所示,一台Host上面有4个OSD(device,如HDD或SSD等)。所以当Ceph存储数据时,会寻找数据存放位置。首先会将Primary放入到Host0的四个节点中,即{0,1,2,3}。同一组中的OSD会根据权重进行平衡。另外两个副本按同样的权重计算方法放到Host1和Host2中。从总上来看,就是三份数据分别放到Host0,Host1和Host2上面,在每一个Host中数据均匀的分布在4个OSD节点上。
当Host0中的OSD 0节点(存储设备)挂掉,会做两个事情:
l 会从Host0中剩余的OSD节点中,找可替代节点,将新增数据写到剩余的节点中
l 当OSD 0恢复时,会将Host0其它OSD节点中刚才新增的数据copy回OSD 0,这个叫recovery的backfill过程
我们的目的,就是减少recovery时backfill的时间。所以如果一个Host下面的OSD节点越多,就会有越多的节点参加backfill,恢复速度就会越快。一般单台机器的存储设备挂载都是有限制的,我们很快就会遇到瓶颈。另外,目前的SSD 128K的写入速度也在400-500M/s之间,跟我们的目标相比,并不算太高。
基于此,我们根据CRUSH MAP新设计了一种OSD domain,它摆脱了单台机器的设备挂载量限制。如下所示,其中黄色虚线框中的OSD都在同一个OSD domain中。一个OSD domain中包含4台机器,每台机器有4个OSD节点(存储设备)。此时,当一个OSD挂掉后,会有15个OSD参加新增数据的平衡和recovery的backfill,大大缩短了恢复时间。
4.2Ceph Replica Domain
在第三个章节中,我们提到了数据散射度问题,数据散射度越大,可用性越差,丢失数据的可能性越高。因此,我们怎么来解决这个问题呢?
还是要从CRUSH MAP入手,再结合copy set的的原理来做合理架构与设计。基于上面OSD domain的设计,我们再新增replica domain,将三个不同RAC中的OSD domain组成三个copy set,用于存放replica set的三个数据副本。具体架构图如下,这样部署后,copy set做到了一个非常低的水平。
另外,为了节省IDC机架位资源,我们在一个集群下分为两个replica domain,每个replica domain下面又有3个OSD domain:
4.3泊松分布
到这里,我们的CRUSH MAP架构设计差不多完成了,那么接下来,我们来计算下这种部署能做到多个“9”呢?
在分布式存储集群中,X个磁盘发生故障的事件是独立的,其概率是符合泊松分布的。
拿磁盘来讲,其MTTF为1million,因此AFR为“1-(24*365/1million)= 0.98832“,约为“0.99”。泊松分布中,两个重要的变量因还素X和Mean我们都确定了。对于分布式存储池来讲,X就是replica set size “R”,Mean就是“0.99”。
我们拿Ceph为例,Ceph集群的高可用性可以简单的按以下函数来量化:P = f(N, R, S, AFR),其中:
l P: 丢失所有副本的概率
l R: 副本数,也就是replica set size
l S: Ceph中,Item Bucket中OSD的个数
l N: 整个Ceph 集群中OSD的总数
l AFR: 磁盘的年平均故障率
进行演化后,我们得到可用性公式:P = Pr * M / C(N,R),其中:
Pr:为R个数据副本同时失效的概率,在Ceph中相当于是Primary在做recovery恢复时,其它R-1个副本也Fault掉了。
M:为Ceph可能的Copy set数目
R:为replicat set size,即副本数
N:为Ceph集群OSD总数
C(N,R):为N个OSD节点中,取R个副本的组合数
从上面的高可用性公式可以看出,一般在给定Ceph集群OSD节点数和副本数“R”后,C(N,R)也就确定了。那么,为了提高可用性,我们必须想办法降低Pr和M的值。
在Ceph系统中,存储节点的拓扑结构,统一由CRUSH MAP来管理,因此要想改变高可用性,就得从CRUSH MAP入手。这个点,我们在上面的篇章中已经提到,而且做了架构优化:
l 为了降低Pr,我们引入了OSD domain,Ceph默认基于Host单机,无法发挥网络“多打一”的优势,我们引入OSD domain,提高单个OSD恢复的速度。将原来三个OSD节点扩大到16个,恢复速度提高了5倍以上。
l 为了降低M,也就是copy set的size,我们引入了replica domain。同一个PG中所有的OSD必须在同一个replica domain中,降低了数据丢失的概率了,提高了高可用性。
以下经我们架构设计后,再根据泊松分布计算出来的高可用性:
Ceph默认配置 |
|||
N=96,S=4 |
R=1 |
R=2 |
R=3 |
C(N,R) |
96 |
4560 |
142880 |
M |
96 |
3072 |
32768 |
Pr |
0.99 |
4.95E-05 |
1.64E-07 |
P |
0.99 |
3.33E-05 |
3.76E-08 |
可用性 |
0 |
4 |
8 |
增加osd domin,提高恢复速度,降低Pr |
|||
N=96,S=16 |
R=1 |
R=2 |
R=3 |
C(N,R) |
96 |
2556 |
59640 |
M |
96 |
3072 |
32768 |
Pr |
0.99 |
3.12E-06 |
2.59E-09 |
P |
0.99 |
3.75E-06 |
1.42E-09 |
可用性 |
0 |
5 |
9 |
增加replica domain,减少replica set,减少M值 |
|||
N=96,S=16 |
R=1 |
R=2 |
R=3 |
C(N,R) |
96 |
2556 |
59640 |
M |
96 |
1536 |
8192 |
Pr |
0.99 |
3.12E-06 |
2.59E-09 |
P |
0.99 |
1.87E-06 |
3.56E-10 |
可用性 |
0 |
5 |
10 |
根据这个架构设计,在同一个IDC内,我们基本上能做到接近于10个“9”的高可用性。比之于默认的算法,高可用性整整提高了将近100倍。 4.4网络拓扑结构
根据上面的分布式拓扑结构设计,再结合现有的网络拓扑结构,我们的架构设计最终方案为:
一个Ceph集群24台机器,两个replica domain,每个replica domain中有三个OSD domain,每个OSD domain中4台机器:
2(一般为两个,由网络交换机下挂的机器数决定)* 3(replica set,replica domain) * 4(scatter width,OSD domain)= 24
原则性的,replica domain的机器位于三个不同的RAC时,这三个RAC不能在同一个port中。一个交换设备下挂16台机器,两个OSD domain,这两个OSD domain属于不同的replica domain。