分布式系统需要解决什么问题?
- 大规模分布式系统中,存储的设备发生变化(添加或者删存储设备),如何最小化迁移数据量,使整个分布式系统中数据分布趋于均衡,这是分布式存储需要解决的第一个问题
- 大规模分布式存储系统中,一般数据存储的策略会多种多样,比如在多副本的存储策略上,对于一个数据如何的合理分布到存储设备上,从而使得数据具有较高的可靠性,这是分布式存储需要解决的第二个问题
主流分布式存储如何解决数据分布问题?
Gluster 如何解决的?
- 每个数据文件在最终写入Gluster集群中之前,首先是需要客户端根据文件名称和父目录的layout,计算出哈希值,以此作哈希值和副本策略为输入,采用固定的哈希算法,最终数据映射到后端的某个Brick上,客户端直接和后端Brick对应的进程进行实际的IO操作。比如是在多副本存储模式下,Gluster采用
Best Effort Write
方式去写数据,具体就是一个数据三个副本对应跨节点的三个Brick,三个Brick都是正常的,写三个;如果2个是正常的,写2个;如果1个是好的,就写1个。 - Gluster目前仅支持无副本、多副本、EC三种存储策略,比如是
3*12
三副本模式下,如果有一个brick损坏,需要在添加一个存储设备到Gluster 集群,数据迁移是以整个Brick的维度来做,整个是无法控制细粒度的。
Ceph 如何解决?
- Ceph采用了CRUSH算法,CRUSH是一种基于哈希的数据分布算法,以PGID、当前集群拓扑结构、存储策略规则作为CRUSH输入,计算获取数据所在的底层所在的存储设备并直接与之通信,从而实现去中心化和高并发的目的。通常一个文件,需要经过切分,按照默认对象的大小切分为多个对象,每个对象都有唯一的标识符,每个文件都会通过哈希函数计算获取哈希值,通过哈希值对当前集群中的PG个数取模,来确定这个对象应该存储在哪个PG中,随后根据CRUSH算法,,输入PGID、集群拓扑、存储策略规则,获取一组OSD,然后直接和OSD通信写入数据
- Ceph在演进过程中有2种CRUSH基本算法straw和straw2算法, CRUSH是基于层级的深度优化的遍历算法,越处于顶层的结构变化可能性越小,处于底层的结构变化越是频繁。一般会有这几类层级,IDC->机架->机柜->主机,其中IDC位于顶层,主机位于底层。straw算法将所有的存储设备当做习惯,针对指针输入,为每个存储设备计算一个长度,最后选择长度最长的那个存储设备作为输入,这个过程形象被称为抽签。如果所有的存储设备是一致的,那么每个存储设备被选择的概率都是一样的。后续CRUSH算法引入额外的权重参数,来区分存储设备之间的差异,权重越大的存储设备承担更多的数据,权重小的存储设备承担更少的数据存储。
- straw算法在添加一个存储设备时候,会随机的将一些原有的集群中其他存储设备数据映射到新的存储设备上;当删除一个存储设备时候,straw算法将该存储设备的数据全部随机的重新映射到集群的其他的存储设备上;straw算法在实际中存在一个缺陷,当集群每次添加或者删除存储设备,总会触发不相关的数据迁移,具体是由于straw算法最终的选择结果不但取决于存储设备的自身权重,也和集群中所有的存储设备的权重强相关。针对这个问题优化了straw算法更该为straw2算法,这个算法仅仅依赖存储设备的自身权重