1 Ceph分布式存储系统分析
Ceph是一个统一的分布式存储系统,可同时提供块、文件和对象3种接口的存储服务。与传统的分布式存储系统不同,它采用了无中心节点的元数据管理方式,因此具有良好的扩展性和线性增长的性能。经过十余年的发展,Ceph已被广泛地应用于云计算和大数据存储系统。
1.1 Ceph分布式存储系统关键技术分析
1.1.1 CRUSH算法分析
存储系统的数据分布算法要解决数据如何分布到各个节点的问题,随着大规模分布式存储系统(PB级的数据和成百上千台存储设备)的出现,数据分布算法面临了几个挑战:
- 数据分布和负载的均衡。数据分布的均衡是指算法要能够将数据均匀的存储到各个节点和磁盘上。负载均衡指的是数据的访问的等操作的负载在各个节点之间负载均衡。
- 扩展性和高可用性。系统方便的增加或者删除存储设备。当增删设备之后,数据恢复和数据迁移,将会使得数据重新均衡,算法需要是这样的移动、迁移的数据量尽可能的少。
- 支持大规模集群。为了支持大规模的存储集群,要求数据分布算法维护的元数据要相对较小,且计算量不能太大。
传统的存储使用数据中心式的元数据、索引表来保存有关客户端的数据如何存放的问题。而Weil提出了CRUSH(Controlled Scalable Decentralized Placement of Replicated Data)算法,将数据与节点的映射关系通过哈希函数来表示,避免了大量并发地访问元数据服务器的过程。因此它消除了对中心式的服务器、网关的需求(去中心化),CRUSH有两个突出的优点:
- 任何组件都可以独立计算出每个object所在的位置。
- 只需要很少的元数据(cluster map),只要当删除添加设备时,这些元数据才需要改变。
CRUSH算法解决PG(Placement Group,是Objects的逻辑集合)如何映射到OSD(Object Storage Devices,负责存储所有的Objects数据)列表中。其过程可以看成如下函数:
其中代表需要映射PG的ID,一个文件的存储的映射如图1.1所示。
图1.1.1 Ceph存储映射
Cluster Map
层次化的Cluster Map定义了OSD集群具有层级关系的静态拓扑结构。OSD的层级使得CRUSH算法在选择OSD时实现了机架感知(rack awareness)的能力,也就是通过规则定义,使得副本可以分布在不同的机架、不同的机房中,提供数据的安全性。层级化的Cluster Map的一些基本概念如下:
- Device: 最基本的存储设备,也就是OSD,一个OSD对应一个磁盘存储设备;
- Bucket: 设备的容器,可以递归的包含多个设备或者子类型的bucket。Bucket的类型可以有很多种,例如host就代表了一个节点,可以包含多个device;rack就是机架,包含多个host等。在ceph里,默认的有root、datacenter、room、row、rack、host六个等级。用户也可以自己定义新的类型。每个device都设置了自己的权重,和自己的存储空间相关。bucket的权重就是子bucket(或者device)的权重之和。
如图1.1.2所示,描述了Cluser Map的具体结构,它直接映射了Ceph集群的状态,rack表示了机架,host代表一个机器。
图1.1.2 Cluster Map的层级结构
Placement Rules
有了Cluster Map下面就需要一种选择策略来决定最终的ODS,这个策略在Ceph里就是Placement Rules,具体的内容如下:
rule replicated_ruleset {
ruleset 0 // ruleset的编号id
type replicated // 类型replicated或者erasure code
min_size 1 // 副本数最小值
max_size 10 // 副本数最大值
step take root // 选择一个root bucket,做下一步的输入
step choose firstn 1 type row // 选择一个row,同一排
step choose firstn 3 type cabinet // 选择三个cabinet,三副本分别在不同的cabinet
step choose firstn 1 type osd // 在上一步输出的3个cabinet中,分别选择一个OSD
step emit
}
该规则的过程如下:
图1.1.3 Rules在 Cluster Map上的选择过程
根据上面的定义和图中所示的Cluster Map,选择算法的执行过程如下:
- 选中root bucket作为下一个步骤的输入;
- 从root类型的bucket中选择一个row类的子bucket,其选择的算法在root的定义中设置,一般设置为straw算法;
- 从上一步的输出row中,选择三个cabinet,其选择的算法在row中定义;
- 从上一步输出的三个cabinet中,分别选出一个OSD,并输出。
根据本rule sets,选择出三个OSD设备分布在一个row上的三个cabinet中。需要注意的是每次从bucket中选择子item的算法是在bucket定义中指定的,下面将介绍四个选取的算法。
Bucket随机选择算法
Bucket随机选择算法解决了如何从Bucket中选择出需要的子item的问题。它定义了四种不同的Bucket选择算法,每种Bucket的选择算法基于不同的数据结构,采用不同的伪随机选择函数。具体算法请参考官方文档,这里只给出一个总体的概览,如表1.1所示。
表1.1.1 Bukect选择算法
通过以上分析,可以了解到CRUSH算法实质是一种可分层确定性伪随机选择算法,它是Ceph分布式存储系统的一个亮点和创新。