Ceph Pool&PG&CRUSH 设置

 

 

当用户在 Ceph 存储集群中创建 POOL ,并为 POOL PG 时,如果用户 未指定具体的参数值,则 Ceph 使用配置文件中的默认值来创建 POOL 和设置 PG 数目。 通常情况下,建议用户根据实际情况在配置文件中自定义 POOL 的对象副本数目 osd pool default size osd pool default min size )和 PG 数目( osd pool default pg num 与osd pool default pgp num )。 关于对象副本数目,用户可以根据自身对数据安全性的要求程度进行设置, Ceph默认存储 份主对象数据和两份副本数据(即 osd pool default size=3 ) 对于 PG 数目,假设数据对象副本数目为N ,集群 OSD 数目为M ,每个 OSD 上的 PG 数目为 X(官方推荐为100 ), 则官方推荐的 PG 数目计算公式为:
Number of PG/PGP = M*100/N

 

上述公式计算出的值通常不是 2的幕次方值,为了最大优化 CRUSH 算法,通常将 PG数目取 2的幕次方值,如 Ceph 集群有 100 OSD ,副本数目为3 ,则实际算出的 PG 数目为3333.3 ,而与此值最接近的 2的幂次方值为 4096 ,因此最终的 PG 数目为 4096。 POOL的对象副本数和 PG 数目设置通常位于配置文件的[gloal ]配置段,如下:
[global) 
sd pool default size = 4 
osd pool default min size = 1 
osd pool default pg num = 4096 
osd pool default pgp num = 4096

 

 

当然,用户也可以在创建 POOL 时指定对象副本数和 PG 数目,还可以在后期运维中通过 ceph osd pool set {pool-name} size {size }命令修改副本数目 此外, Ceph 还提供了很多与 POOL PG CRUSH 相关的配置选项,其中比较常见的配置选项如表 14-10 所示

Ceph Pool&PG&CRUSH 设置

 

 

 

 

二、Ceph CRUSH 自定义

 

 

CRUSH (Controlled Replication Under Scalable Hashing )是 Ceph 存储集群使用的一种数据分发算法,类似于 OpenStack Swift和 AWS 的对象存储所使用的哈希和一致性哈希数据分布算法。 Ceph 采用 CRUSH 而非哈希算法的主要原因,在于当数据增长时哈希不能动态增加 Bucket ,而一致性哈希在增加 Bucket 时需要进行大量的数据迁移。此外,其他常见的数据分发算法依赖中心化的 Metadata 服务器来存储元数据,因此造成了数据存取的效率较低,而 CRUSH 则是通过接受多维参数并通过一定的计算来解决数据动态分发的问题。与其他分布式存储集群相比, CRUSH 算法可以认为是 Ceph 存储集群的核心设计之一,Ceph 使用 CRUSH 算法对客户端对象数据进行分布存储,这也是 Ceph 存储集群区别于其他分布式存储系统并具备高扩展性、高可用性和高性能的主要原因。    
当 Ceph 客户端将文件存储到 Ceph 集群时,文件被条带化切割为特定大小的对象块( Object ),对象块经过 HASH 之后得到存放对象的 PGID ,之后 再经过 CRUSH 算法将对象存储到 Ceph 集群的存储设备中(即 OSD 中), CRUSH 算法将数存储到一组 OSD 集合中的伪随机映射过程可简单表述如下:
CRUSH(X}->(OSDl 0802 0803 ...... OSDn}

 

 

其中, Ceph 存储池中数据存储的副本数目 Ceph 的数据存储过程中, CRUSH算法提供了配置可更改和数据动态再平衡等关键特性, CRUSH 算法存储数据对象的过程 可通过 CRUSH Map 控制并进行自定义修改, CRUSH Map 由不同层次的逻辑 Buckets和Devices 组成,其中的 Devices 主要指 OSDs 存储设备, RUSH Map 层次结构中的叶子节点,而层次结构中叶子节点外的全是虚拟 Bucket 设备, CRUSH Map 的层次结构如图所示:   Ceph Pool&PG&CRUSH 设置

 

 

在图中,有 Root、Datacenter、 Room、Rack、Host和OSD 几种 Bucket。 其中Root 包含的 item Datacenter (即数据中心), 而 Datacenter 包含的 item Room (即机房),Room 包含的 item是Rack (即机柜), Rack 包含的 item是Host (即主机服务器),最后 Host包含的 item 才是最终的存储设备 OSD 。对于每个 Ceph 集群而言, CRUSH Map 在正式上线前是已经确定的,因此如果用户需要自定义更改 CRUSH Map 的层次结构,必须在上线前进行更改井核实更改已成功应用到 CRUSH 算法中。    
CRUSH Map 中的 Bucket 是用户可以自定义增加的,每个层级的 Bucket 对应不同的故障域,在实际应用中,为了更加精细化地隔离故障域,用户还可以增加 PDU、ROW、CHASSIS等Bucket (Bucket 的名称可以自定义),例如在 Ceph 0.80.7 版本中, Ceph 默认的CRUSH Map 中便声明了如下的 11 Bucket:    
type O osd 
type 1 host 
type 2 chassis 
type 3 rack 
type 4 row 
type 5 pdu 
type 6 pod 
type 7 room 
type 8 datacenter 
type 9 region 
type 10 root

 

 

 

在CRUSH 算法中,决定数据应该如何分布以及分布到哪个 Bucket 中,是通过 Pacement Rule 来决定的 换言之, Ceph 存储管理员可以将用户数据分布存储到不同的数据中心、机房、机柜和存储节点上。     例如生产环境中 Ceph 默认的数据副本数目为3,则管理员可以通过修改 CRUSH Map 中的 Pacement Rule ,将相同数据的三个副本分别存储到不同的故障域中,这里的故障域可以是不同的数据中心、不同的机房、不同的机柜、不同的主机甚至是不同地理位置的数据中心,从而用户可以根据数据的不同安全级别将其实现不同程度的故 障域保护 CRUSH Map 中,每个 Rule 均定义了一系列操作,其中 Take 操作定义了入口Bucket ,即 CRUSH Map 层级结构的根节点( CRUSH Map 中可以有多个 Rule ,因此可能有多个根),而 Select (N, Type )操作定义了选取 个类型为 Type 的项目,最后的 Emit 操作则是提交选择的结果, CRUSH Map 中的 Rule 定义语句如下所示:    
rule<rulename> { 
ruleset<ruleset> //rule ID 
type [ replicated | raid4 ] 
min_size <min-size> //数据最小副本数
max_size <max-size> //数据最大副本数
step take <bucket-type >//从bucket-type开始挑选存储设备
step [choose|chooseleaf]firstn <N>type <bucket-type >//挑选规则
step emit
}

 

  其中, step take和step emit 之间的语句即是 Rule 定义的 Select 操作语句。由于 Bucket包含的项目可以全部是 Bucket ,也可以全部是 Device ,因此如果 Select 操作中有如下语句:
step choose firstn <N>type <bucket-type>

 

 

则表示从<bucket- pe>层级的 Bucket 中选择 个项目,这些项目依然是 Bucket。 而如果Select 操作中有如下语句:  
step chooseleaf firstn <N>type <bucket-type>

 


则表示从<bucket-type>层级的 Bucket (通常为 Host )中选择N 个叶子节点,即 OSD 层级设备。因此,在 Rule Select 操作中,不管有多少个 choose 操作,最后一定以 chooseleaf选择 OSD 存储设备结尾 。此处的< N>值可能有三种情况:    
等于0 :从<bucket-type>层级的 Bucket 中选择与 POOL 副本数目相同的项目,例如Ceph 存储池默认副本数目为3 ,如果N为0,并且是 choose leaf 操作,而且 type
  为host ,则表明从不同的 host 中选择3个OSD 用来存储对象数据及其副本


 大于0 :从<bucket-type>层级的 Bucket 中选择N个项目,例如 Ceph 存储池默认副本数目为3,如果N为1,并且是 chooseleaf 操作,而且type为host ,则表明从
  host 层级的Bucket中选择1个OSD用来存储对象数据,注意此时另外两个副本数据需要从其他的 Bucket 中选择 OSD 来存放。


 小于0 :小于0的情况通常与大于0操作同时使用,即同一个Rule 中有 N>0的Step ,再有 N<0的Step。假设存储池的副本数目为 M,而 N<0的Step 通常表示从<bucket-type>层级的Bucket 中选择 M-|N|个项目。例如 Ceph 存储池默认副本数目为3 ,如果N为-1,并且是 chooseleaf 操作,而且 type为host ,则表明从 host层级的 Bucket 中选择 3-|-1|=2个OSD 用来存储对象数据,注意此时另外一个 OSD(通常为 Primary OSD )可能已经通过 N>l的Step 进行了选取  

 


CRUSH Map 中可以有多个 Rule ,而每个 Rule 都对应有自己的 ID。此外, Ceph 客户端通过 POOL 来访问 Ceph 存储集群,而每个 POOL 都有对应的 Rule ID ,当客户端数据写人此 POOL 时, Ceph 将从 CRUSH Map 中获取与此 POOL 对应的 Rule ,并根据 Rule定义的操作将数据分布存储到不同的 Bucket Device。
例如Ceph 实验集群共有5个OSD, 576个 PG和6个 POOL, Ceph 存储集群的运行情况如下所示:   Ceph Pool&PG&CRUSH 设置

 

 

 
为了查看 Ceph 集群的 CRUSH Map 信息,首先需要通过 getcrushmap 命令获取集群的CRUSH Map ,如下:
[root@controllerl -]# ceph osd getcrushmap -o compiled-crushmap.txt 
got crush map from osdmap epoch 81

 


getcrushmap 命令获取到的 CRUSH Map 是编译过的二进制信息,并不能直接编辑或查看,必须使用 crushtool 命令行工具对其进行反编译,如下:
[root@controllerl ]# crushtool -d compiled-crushmap.txt -o decompiled-crushmap.txt 
[root@controllerl ]# ls -1 decompiled-crushmap.txt 
-rw-r--r-- 1 root root 1450 Feb 1 23:10 decompiled-crushmap.txt

 

 

经过反编译的 CRUSH Map 即可进行编辑修改,当前 Ceph 集群(版本为 80.7 )默认CRUSH Map 信息、如下:

 

[root@controllerl ~]# more decompiled-crushmap.txt 
# begin crush map 
tunable choose_local tries o 
tunable choose_local f allback tries 0
tunable choose_total tries 50

tunable chooseleaf descend once 1 
//Ceph存储集群中的Devices, 即OSDs 
# devices 
device 0 osd.0
device 1 osd.1 
device 2 osd.2 
device 3 osd.3 
device 4 osd.4


// Buckets名称声明,一共11个
# types 
type 0 osd 
type 1 host 
type 2 chassis 
type 3 rack 
type 4 row 
type 5 pdu 
type 6 pod 
type 7 room 
type 8 datacenter 
type 9 region 
type 10 root


//具体的Bucket 实例定义 # buckets host computel { id -2  # do not change unnecessarily     #weight 0.010 alg straw hash 0 # rjenkinsl   item osd.0 weight 0.010 //Bucket 包含的项目 }   host compute2 { id - 3   # do not change unnecessarily       # weight 0.010 alg straw hash 0 # rjenkinsl   item osd.l weight 0.010 //Bucket 包含的项目 }   host networkl { id -4  # do not change unnecessarily     #weight 0.010 alg straw hash 0 # rjenkinsl   item osd.2 weight 0.010 //Bucket包含的项目 }   host network2 { id -5  # do not change unnecessarily     #weight 0.010 alg straw hash 0 # rjenkinsl
  item osd.3 weight 0.010 //Bucket包含的项目 host storage1 { -6  # do not change unnecessarily    #weight 0.010 alg straw hash 0 # rjenkinsl   item osd.4 weight 0.010 //Bucket包含的项目   root default { id -1 # do not change unnecessarily       #weight 0.050 alg straw hash 0 # rjenkinsl   item compute1 weight 0.010 //Bucket包含的项目   item compute2 weight 0.010 //Bucket包含的项目   item networkl weight 0.010 //Bucket 包含的项目   item network2 weight 0.010 //Bucket包含的项目   item storage1 weight 0.010 //Bucket 包含的项目   //pacement rule定义 # rules rule replicated_ruleset {   ruleset 0   //Rule ID   type replicated   min size 1  //最小副本数,如果小于此值,则该规则无效   max size 10 //最大副本数,如果大于此值 ,则该规则无效   step take default  //从defualt这个bucket 开始遍历挑选存储设备    step chooseleaf firstn O type host //从全部host 选择3个存储设备   step emit # end crush map  

 

 

 

   

 

上一篇:ceph bluestore 写操作源码分析(上)


下一篇:cephfs挂载+nfs+nginx