一、ceph对象
(1)ceph object
- Object由数据和元数据构成
- 每个object都有全局唯一的ID
- 不同于文件存储,object的大小可以突破文件级的限制,并且还有丰富的元数据
- 整个Object索引是一个扁平结构里实现的,不同于传统文件系统的树状结构
(2)查看object
查看pool
$:rados lspool
查看pool里的object
rados -p {poolname} ls
示例:
$:rados ls -p rbd
二、crush算法对比一致性hash
设想你曾几何时存了一部爱情动作片到ceph集群中,你拿着笔记本来到机房,你所看到的Ceph集群是数个机架的服务器。你在想,我的爱情动作片最终是存储在哪里?
你考虑的实际是数据定位的问题:
常见有两种数据定位方法:
- 记录:将“数据A:位置location(A)”这样的信息记录下来,访问数据时查询记录,获取位置,再进行读取。
- 计算:存放数据A时,其存储位置location(A)是即时计算得到的
常见的计算方式是一致性哈希(consistent hashing):
- 基本思路是,面对数据A,以数据A的文件名等类似信息为key,通过一致性哈希计算consist_hash(keyA) = location(A)得到存储位置。
ceph使用的是crush算法:Controlled,Scalable,Decentralized placement of Replicated Data
(1)数据分布是分布式存储系统的一个重要部分:
- 故障域隔离:同份数据的不同副本分布在不同的故障域,降低数据损坏的风险;
- 负载均衡: 数据能够均匀的分布在磁盘容量不等的存储节点,避免部分节点空闲部分节点超载,从而影响系统性能;
- 控制节点加入离开节点上的数据被移到其他节点,而正常工作的节点的数据不会发生迁移。
(2)对象存储中一致性Hash和ceph的crush算法是使用地比较多的数据分布算法。
(3)使用一致性Hash存储系统:
Aamzon的Dyanmon键值存储系统
Openstark的Swift对象存储系统
(4)一致性hash分析
假设数据为X,存储节点数目为N,存储节点:Hash(X)%N
计算Hash值目的:让数据均匀分布,当加入新节点则节点离开时,几乎所有数据都会受到影响,需要重新分布。导致数据迁移量非常大。
一致性Hash算法将数据和存储节点映射到同个Hash空间:
如图(a)所示,Hash环中的3存储节点把Hash空间划分成3个分区,每个存储节点负责一个分区上的数据。例如,落在分区[N2,N0]上的数据存储在节点N0。
如图(b)所示,当节点N0离开时,原来由它负责的[N2,N0]分区将同[N0,N1]分区合并成[N2,N1]分区,并且都由节点N1负责。也就是说,本来存储在节点N0上的数据都迁移到节点N1,而原来存储在N1和N2节点的数据不受影响,图(c)给出了当节点N3加入时,原来[N2,N0]分区分裂成[N3,N0]两个分区,其中[N3,N0]分区上是数据迁移到新加入的N3节点。
虚拟节点:
1、一致性Hash的不足,存储节点不能将Hash空间划分地足够均匀:
如图(a)所示,分区[N2,N0]的大小几乎是其它两个分区大小之和。这容易让负责该分区的节点N0负载过重。假设3个节点的磁盘容量相等,容易当节点N0的磁盘已经写满数据时其它两个节点上的磁盘还有很大的空闲空间,但此时系统已经无法继续向分区[N2,N0]写入数据,从而造成资源浪费。
2、虚拟节点是相对于物理存储节点而言的,虚拟节点负责的分区上的数据最终存储到其对样的物理节点:
NI_0代表该虚拟节点对应于物理节点 i 的第0个虚拟节点。增加虚拟节点后,物理节点N0负责[N1_0,N0]和[N0,N0_0]两个分区,物理节点N1负责[N0_0,N1]和[N2_0,N1_0]两个分区,物理节点N2负责[N2,N1]和[N2_0,N2]两个分区,三个物理节点负责的总的数量趋于平衡。
实际应用中,可以根据物理节点的磁盘容量的大小来确定其对应的虚拟节点数目。虚拟节点数目越多,节点负责的数据区间也越大。
3、分区和分区位置
当节点加入或者离开时,分区会相应的进行分裂或合并。这不对新写入的数据构成影响,但对已经写入到磁盘的数据需要重新计算Hash值以确定它是否需要迁移到其他节点。因为需要遍历磁盘中的所有数据,这个计算过程非常耗时。
CRUSH算法
Ceph分布数据的过程:首先计算对象X的Hash值并将结果和PG数目取余,以得到数据X对应的PG编号。然后,通过CRUSH算法将PG映射到一组OSD中。最后把数据Xcunf存放到PG对应的OSD中。这个过程中包含了两次映射,第一次是对象X到PG的映射。如果把PG当做存储节点,那么这和文章开头提到的Hash算法一样。不同的是,PG是抽象的存储节点,它不会随着物理节点的加入或离开而增加或减少,因此数据到PG的映射是稳定的。
1、PG功能:
- 第一个作用是划分数据分区。每个PG管理的数据区间相同,因而数据能够均匀地分布到PG上
- 第二个作用是充当Dvanmo中Token的角色,即决定分区位置,实际上,这和Dyanmo中固定分区数目,以及维持分区数目和虚拟节点数目相等的原则是同一回事。
2、在没有多副本的情况下,Dynamo中分区的数据直接存储到Token,而每个Token对应唯一的一个物理存储节点。
3、在多副本(假设副本数目为N)的情况下,分区的数据会存储到连续的N个Token中。但这会引入一个新的问题:因为副本必须保持在不同的物理节点,但是如果这组Token中存在两个或多个Token对应到同个物理存储节点,那么就必须要跳过这样的节点。Dynamo采用preference列表来记录每个分区对应的物理节点。然而,Dynamo论文中没有详述分区的Preference列表如何选择物理节点,以及选取物理节点时该如何隔离故障域等问题。
4、(osd0, osd1, osd2, .... osdn) = CRUSH(x)
5、Ceph的PG担当起Dynamo中Token、固定分区以及Preference列表的角色,解决的是同样的问题。PG的Acting集合对应于Dynamo的Perferenceli列表。CRUSH算法解决了Dynamo论文中未提及的问题。
6、CRUSH算法的目的是,为给定的PG(即分区)分配一组存储数据的OSD节点。
选择OSD节点的过程,要考虑以下几个因素:
- PG在OSD间均匀分布
假设每个OSD的磁盘容量都相同,那么我们希望PG在每个OSD节点上是均匀分布的,也就是说每个OSD节点包含相同数目的PG。假如节点的磁盘容量不等,那么容量大的磁盘的节点能够处理更多数量的PG。
- PG的OSD分布在不同的故障域
因为PG的OSD列表用于保存数据的不同副本,副本分布在不同的OSD中可以降低数据损坏的风险。
7、Ceph使用树形层级结构描述OSD的空间位置以及权重(同磁盘容量相关)大小。
8、OSD节点在层级结构中也被称为Device,它位于层级结构的叶子节点,所有非叶子节点称为Bucket。Bucket拥有不同的类型。
9、CRUSH通过重复执行Take(bucketID)和Select(n,bucketType)两个操作选取副本位置
Placement group(PG)
1、数据分布和复制的单位
2、获取Pool的PG/PGP数量
(方法一)
$:ceph osd pool get data pg_num
$:ceph osd pool get data pgp_num
(方法二)
$:ceph osd dump | grep pg_num
3、修改PG/PGP(通pool指增不减)
$:ceph osd pool get cp pg_num
$:ceph osd pool set cp pg_num 256
4、PG的角色
Primary PG:主副本,所有读写的承受者
Secondary PG:从副本,数据的备份
Pool池管理
1、创建pool池
$:ceph osd pool create test 128 128 //128 pg、pgp
2、查看pool池
$:ceph osd lspools
$:rados lspools
$:ceph osd dump | grep -i pool
3、变更pool的副本数
$:ceph osd pool set test size 4
4、上传文件
$:rados -p cp put object1 /etc/hosts
$:rados -p cp ls
$: rados mksnap snapshot01 -p cp
$: rados lssnap -p cp
$: rados -p cp rm object1
$: rados -p cp listnaps object1
$:rados rollback -p cp object1 snapshot01
$: rados -p cp ls
数据管理---找对象
$:ls /var/lib/ceph/osd/ceph-0/current/XXX*
三、filejournal的意义
Write data包括journal + objstore,均写完成才返回client端