Akemi

管理Ceph的StorageMap--CRUSH MAP与OSD MAP

2025/07/04

Ceph通过CRUSH放置算法,来计算哪些OSD应该保存哪些对象,对象是放到PG中,而CRUSH决定这些PG应该放在哪些OSD中,

CRUSH算法与对象放置策略

CRUSH算法

CRUSH算法使Ceph客户端可以直接与OSD通信:Ceph客户端与osd使用CRUSH算法来有效计算关于对象位置的信息,而不是依赖于中央查找表,避免了单点故障和性能瓶颈

作用:在对象存储中均匀分布数据、管理复制、响应系统增长和硬件故障

当新增OSD或已有OSD或OSD主机故障时,Ceph使用CRUSH来重新平衡集群中活动OSDs之间的对象。

CRUSH映射组件

一个CRUSH映射包含两个组件,整个集群只有一份CRUSH Map,不同pool可以使用不同Rule

CRUSH hierarchy层次结构

通常用于表示osd位置

列出了所有可用的osd,并将它们组织成树状的桶结构

默认情况下有一个根桶代表整个层次结构,下面每个主机对应一个主机桶

At least one CRUSH rule至少一个CRUSH规则

CRUSH规则决定了如何从这些桶中为PG分配osd,决定了PG的对象存储在哪里。不同的池可能使用不同的CRUSH规则




CRUSH 桶类型

对于大规模的安装,可以创建一个特定的层次结构来描述存储基础设施
比如:数据中心—机架—主机—OSD设备

桶是CRUSH层次结构中的容器或分支。设备是osd,是CRUSH层次结构中的叶子。

桶属性

1.桶ID为负数,便于和存储设备区分ID

2.桶名称

3.桶类型
默认的映射定义了几种类型。比如:根root、区域region、数据中心dc、房间、pod、pdu、行、机架、机箱、主机
也可以添加自定义类型

4.算法
当PG副本映射到osd时,ceph用来选择桶内项目的算法。有几种可用的算法:uniform、list、tree、straw2,默认为straw2

自定义故障域与性能域

CRUSH映射是CRUSH算法的中心配置机制,可以通过编辑此映射来影响数据放置和自定义CRUSH算法

创建独立的故障域允许OSD和集群节点在不发生数据丢失的情况下发生故障,集群会进入降级状态下运行,直到问题解决

创建独立的性能域可以减少ceph客户端和应用程序的性能瓶颈

定制CRUSH映射的一个经典用例是针对硬件故障做额外的保护:缺省情况下,CRUSH算法将复制的对象放在不同主机的OSD上

自定义OSD CRUSH设置

CRUSH映射包含了存储设备的列表,对每个存储设备,可获取的信息包括:
1.存储设备ID
2.存储设备
3.存储设备的权重,通常以TB为单位,比如4TB的权重约为4.0。以确保对象的均匀分布

ceph OSD crush reweight可以设置OSD的权重,但不推荐修改

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class反应了设备的类型,比如hdd,ssd,NVMe ssd等

查看当前crush层级
ceph osd crush tree
ID CLASS WEIGHT TYPE NAME
-1 0.52734 root default
-5 0.17578 host cephadm-1
4 hdd 0.05859 osd.4
6 hdd 0.05859 osd.6
8 hdd 0.05859 osd.8
-7 0.17578 host cephadm-2
3 hdd 0.05859 osd.3
5 hdd 0.05859 osd.5
7 hdd 0.05859 osd.7
-3 0.17578 host cephadm-3
0 hdd 0.05859 osd.0
1 hdd 0.05859 osd.1
2 hdd 0.05859 osd.2

使用CRUSH RULE规则

CRUSH Map包含多个CRUSH Rule(规则集),决定了如何将PG映射到OSD中存储对象副本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
ceph osd crush rule ls
replicated_rule
ceph osd crush rule dump replicated_rule # 详细信息
{
"rule_id": 0,
"rule_name": "replicated_rule",
"type": 1,
"steps": [
{
"op": "take",
"item": -1,
"item_name": "default"
},
{
"op": "chooseleaf_firstn",
"num": 0,
"type": "host"
},
{
"op": "emit"
}
]
}

或者
ceph osd getcurshmap -o ./map.bin
crushtool -d ./map.bin -o ./map.txt
cat map.txt
...
# rules
rule replicated_rule {
id 0
type replicated
step take default
step chooseleaf firstn 0 type host
step emit
}

CRUSH规则的属性

1.rule_name规则的名称,使用ceph osd pool create时,会指定规则的名称
2.rule_id规则的ID,有些命令会使用规则的ID而不是名称
3.min_size如果生成的副本少于这个数,则CRUSH不选择此规则
4.max_size如果生产的副本多于这个数,则CRUSH不选择此规则
5.step take从这个桶开始迭代,这里是default,一般不会设定为根桶
6.step chooseleaf以这个桶作为最小单位来划分,这里是host主机桶
(1)如果三副本的池,那就需要3个主机桶,这三个主机桶中分别找三个OSD
(2)如果firstn后是0,则池中有多少副本就选多少桶
(3)如果firstn大于0且小于副本数,那就需要额外的步骤来定义规则,来存放多出来的副本

使用CRUSH MAP映射

使用ceph命令自定义CRUSH MAP

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
创建桶的命令格式:
ceph osd crush add-bucket <name> <type>
name名字
type桶类型

创建三个桶,一个dc类型的,两个rack类型的
ceph osd crush add-bucket DC1 datacenter
ceph osd crush add-bucket rackA1 rack
ceph osd crush add-bucket rackB1 rack

重新组织树的命令格式:
ceph osd crush move <name> <type>=<上级桶的名称>

两个机架桶挂载到数据中心桶上,并将数据中心桶挂载到default根桶上
ceph osd crush move rackA1 datacenter=DC1
ceph osd crush move rackB1 datacenter=DC1
ceph osd crush move DC1 root=default

设置OSD位置

自定义了层次结构之后,就要加入OSD作为leaf来存放数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
OSD的位置是一个字符串,记录了从根开始完整的路径
和linux的绝对路径差不多
root=default datacenter=DC1 rack=rackA1

当Ceph启动时,使用Ceph-crush-location utility自动验证每个OSD
是否在正确的crush位置,如果不在映射中的预期位置,会自动移动到默认的
root=default host=hostname下

命令行配置crush_location参数(推荐)
ceph orch daemon reconfig osd.0 --crush-location 'root=default,datacenter=DC1'
或者
ceph osd crush set osd.0 1.0 root=default datacenter=DC1 rack=rackA1 host=<主机名>

/etc/ceph/ceph.conf配置文件中,配置crush_location参数(不推荐)
[osd.0]
crush_location = root=default datacenter=DC1 rack=rackA1
[osd.1]
crush_location = root=default datacenter=DC1 rack=rackB1

给CRUSH MAP添加规则

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
创建新的CRUSH规则
ceph osd crush rule create-replicated <rule-name> <root> \
<failure-domain-type> [class]

rule-name规则名称
root起始桶
failure-domain-type故障域类型(确保副本分布在不同故障域中)
class要使用的设备的类,可选,如hdd ssd

ceph osd crush rule create-replicated inDC2 DC2 rack
ceph osd crush rule ls
表示

使用新的CRUSH规则
ceph osd pool create mypool 128 128 inDC2

PG优化

一般不会做

在集群生命周期中,pg的数量必须随着集群布局的变化而调整。CRUSH尝试确保池中osd之间的对象均匀分布,但是存在pg变得不平衡的情况。

数量或者体积大的对象,都会导致PG对象分布不平衡

红帽建议每个OSD中创建100~200个PG

PG数量计算

对于单池的集群,可以使用以下公式:

1
2
3
120个OSD,3副本池,目标每个OSD承载100个PG

(120 OSD × 100 PG/OSD) / 3 副本 = 4000

管理OSD MAP

集群OSD映射中包含了每个OSD的地址、状态、池列表和详细信息,以及OSD临近容量限制信息等

每次OSD加入或退出集群时,ceph都会更新OSD映射,OSD退出集群的原因包括OSD故障或者硬件故障

不使用leader,OSD之间互相传播映射,标记他们与OSD map epoch交换的每个消息,当检测到自己落后时,就会进行更新

使用epoch标记与更新OSD信息,与ceph客户端连接时,也会给ceph客户端进行更新增量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ceph osd dump
ompat_client luminous
require_osd_release quincy
stretch_mode_enabled false
pool 1 '.rgw.root' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 51 lfor 0/0/23 flags hashpspool stripe_width 0 application rgw
pool 2 'default.rgw.log' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 51 lfor 0/0/23 flags hashpspool stripe_width 0 application rgw
pool 3 '.mgr' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 1 pgp_num 1 autoscale_mode on last_change 20 flags hashpspool stripe_width 0 pg_num_max 32 pg_num_min 1 application mgr
pool 4 'default.rgw.control' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 57 lfor 0/0/54 flags hashpspool stripe_width 0 application rgw
pool 5 'default.rgw.meta' replicated si
min_cze 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 32 pgp_num 32 autoscale_mode on last_change 57 lfor 0/0/55 flags hashpspool stripe_width 0 pg_autoscale_bias 4 application rgw
max_osd 9
osd.0 up in weight 1 up_from 12 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.143:6800/2523430589,v1:192.168.10.143:6801/2523430589] [v2:192.168.10.143:6802/2523430589,v1:192.168.10.143:6803/2523430589] exists,up f6177fb9-920a-4fe3-a739-4d607bd567de
osd.1 up in weight 1 up_from 14 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.143:6808/1943165126,v1:192.168.10.143:6809/1943165126] [v2:192.168.10.143:6810/1943165126,v1:192.168.10.143:6811/1943165126] exists,up aa74b56a-0307-458b-8016-d98563f08798
osd.2 up in weight 1 up_from 16 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.143:6816/1907316690,v1:192.168.10.143:6817/1907316690] [v2:192.168.10.143:6818/1907316690,v1:192.168.10.143:6819/1907316690] exists,up 20144dcf-136a-49e6-ba1b-b6e10975024b
osd.3 up in weight 1 up_from 37 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.142:6800/3086155865,v1:192.168.10.142:6801/3086155865] [v2:192.168.10.142:6802/3086155865,v1:192.168.10.142:6803/3086155865] exists,up af6bed47-8287-43a8-a7ba-8e927bda1e58
osd.4 up in weight 1 up_from 37 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.141:6800/352319272,v1:192.168.10.141:6801/352319272] [v2:192.168.10.141:6802/352319272,v1:192.168.10.141:6803/352319272] exists,up 155a4723-e4ce-4e5a-9791-85f8d84a3a3c
osd.5 up in weight 1 up_from 40 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.142:6808/1669659193,v1:192.168.10.142:6809/1669659193] [v2:192.168.10.142:6810/1669659193,v1:192.168.10.142:6811/1669659193] exists,up 0b74231f-8c31-40c7-92fe-51b995a82446
osd.6 up in weight 1 up_from 40 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.141:6808/2374217427,v1:192.168.10.141:6809/2374217427] [v2:192.168.10.141:6810/2374217427,v1:192.168.10.141:6811/2374217427] exists,up cd382a85-1b85-406c-a792-8a2bf1b29b3a
osd.7 up in weight 1 up_from 43 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.142:6816/2034759112,v1:192.168.10.142:6817/2034759112] [v2:192.168.10.142:6818/2034759112,v1:192.168.10.142:6819/2034759112] exists,up 7417a159-b3a0-4995-b39b-4fd0648c33ee
osd.8 up in weight 1 up_from 43 up_thru 116 down_at 0 last_clean_interval [0,0) [v2:192.168.10.141:6816/3067034779,v1:192.168.10.141:6817/3067034779] [v2:192.168.10.141:6818/3067034779,v1:192.168.10.141:6819/3067034779] exists,up 1cfdad67-9201-462f-9fb4-3e0665d4a059
...

CATALOG
  1. 1. CRUSH算法与对象放置策略
    1. 1.1. CRUSH算法
    2. 1.2. CRUSH映射组件
    3. 1.3. CRUSH 桶类型
    4. 1.4. 自定义故障域与性能域
  2. 2. 自定义OSD CRUSH设置
    1. 2.1. 使用CRUSH RULE规则
    2. 2.2. 使用CRUSH MAP映射
    3. 2.3. 给CRUSH MAP添加规则
  3. 3. PG优化
  4. 4. 管理OSD MAP