Ceph CRUSH 规则
一、CRUSH 规则和概念
Ceph 的 CRUSH(Controlled Replication Under Scalable Hashing)规则用于定义数据在集群中的分布策略。CRUSH 规则决定了数据在不同层级的分布方式,从根节点到具体的 OSD。
1. CRUSH Map
CRUSH Map 是描述存储集群层次结构和数据放置策略的蓝图。它包含了集群中的所有节点和设备的信息,以及 CRUSH 规则和其他配置(下面红色字段在示例中注释部分)
-
Devices
:存储设备(OSD)的列表。 -
Buckets
:存储设备的分组,用于定义层次结构。 -
Rules
:定义数据在存储设备之间的分布策略。 -
Tunables
:一些可调整的参数,用于优化数据分布和性能。
2. CRUSH Bucket
CRUSH Bucket 是存储设备的逻辑分组,表示集群中的层次结构。常见的 bucket 类型包括:
-
Root
:最顶层的 bucket,表示整个集群的根节点。 -
Datacenter
:数据中心级别的 bucket。 -
Room
:房间级别的 bucket。 -
Row
:行级别的 bucket。 -
Rack
:机架级别的 bucket。 -
Chassis
:机箱级别的 bucket。 -
Host
:主机级别的 bucket。 -
OSD
:最底层的存储设备。
3. CRUSH Root
CRUSH Root 是一个特殊类型的 bucket,位于 CRUSH 层次结构的最顶层。它表示整个存储集群的根节点,其他所有的 bucket 和 OSD 都属于某个 root。一个 Ceph 集群可以有多个 root,用于隔离不同的数据池或存储策略。
4. CRUSH Rule
CRUSH Rule 定义了数据在不同 bucket 和 OSD 之间的放置和复制策略。规则指定数据应如何在不同层次结构和故障域之间分布,以确保高可用性和容错性。CRUSH 规则包括以下要素:
- 规则名称:规则的标识符。
- 根节点:规则应用的起始节点(通常是某个 root bucket)。
- 故障域:数据副本应分布的层次(例如 host、rack)。
- 操作步骤:描述如何选择和分布数据副本的具体操作。
5. Weight
Weight 是每个存储设备(OSD)在 CRUSH Map 中的权重,用于表示设备的相对容量或重要性。CRUSH 算法根据设备的权重来分配数据,权重越高的设备将存储更多的数据。通过调整权重,可以平衡集群中的数据分布和负载。
6. Placement Group (PG)
Placement Group (PG) 是 Ceph 中的一个逻辑分组,用于将对象映射到特定的 OSD 集合。每个 PG 在多个 OSD 上都有副本,以实现数据的冗余和高可用性。PG 是 CRUSH 算法工作的基本单位,通过将对象分配到 PG,再由 PG 确定具体的 OSD,CRUSH 算法实现了高效的数据分布和定位。
7. CRUSH Algorithm
CRUSH Algorithm 是一种伪随机数据分布算法,用于根据 CRUSH Map 中的规则和权重,将数据对象分配到适当的 OSD 上。CRUSH 算法确保数据在不同的存储设备和故障域之间均匀分布,以提高数据的可靠性和集群的性能。
8. Failure Domain
Failure Domain 是 CRUSH Map 中的一个层次,用于定义数据副本的分布范围,以避免单点故障。常见的故障域包括 host、rack、datacenter 等。通过在不同故障域之间分布数据副本,可以提高集群的容错能力。
9. Tunables
Tunables 是一些可调整的参数,用于优化 CRUSH 算法的数据分布和性能。这些参数包括选择算法、散列函数、副本数量等。调整这些参数可以根据集群的具体需求和硬件配置,优化数据分布和访问性能。
10. 导出的规则示例
# 查看规则
ceph osd crush dump
{
"devices": [
{
"id": 0,
"name": "osd.0"
},
{
"id": 1,
"name": "osd.1"
},
......
],
"types": [
{
"type_id": 0,
"name": "osd"
},
{
"type_id": 1,
"name": "host"
},
......
],
"buckets": [
{
"id": -1,
"name": "HOST-01",
"type_id": 1,
"type_name": "host",
"weight": 3815178,
"alg": "straw",
"hash": "rjenkins1",
"items": [
{
"id": 38,
"weight": 1907589,
"pos": 0
},
{
"id": 39,
"weight": 1907589,
"pos": 1
}
]
},
{
"id": -2,
"name": "default",
"type_id": 10,
"type_name": "root",
"weight": 0,
"alg": "straw",
"hash": "rjenkins1",
"items": []
},
........
],
"rules": [
{
"rule_id": 0,
"rule_name": "ssd_ruleset",
"ruleset": 0,
"type": 1,
"min_size": 1,
"max_size": 10,
"steps": [
{
"op": "take",
"item": -20,
"item_name": "root-ssd"
},
{
"op": "chooseleaf_firstn",
"num": 0,
"type": "host"
},
{
"op": "emit"
}
]
},
......
],
"tunables": {
"choose_local_tries": 0,
"choose_local_fallback_tries": 0,
"choose_total_tries": 50,
......
},
"choose_args": {}
}
二、CRUSH 规则字段说明
1. 查看当前 crush
规则 ceph osd crush rule dump
ceph osd crush rule dump
[
{
"rule_id": 0,
"rule_name": "replicated_rule",
"ruleset": 0,
"type": 1,
"min_size": 1,
"max_size": 10,
"steps": [
{
"op": "take",
"item": -1,
"item_name": "default"
},
{
"op": "chooseleaf_firstn",
"num": 0,
"type": "host"
},
{
"op": "emit"
}
]
}
]
2. CRUSH 规则的字段解释
字段 | 说明 |
---|---|
rule_id |
规则的唯一标识符。 |
rule_name |
规则的名称。 |
ruleset |
规则集的标识符,用于关联存储池。 |
type |
规则的类型,一般为 1 表示 Replicated Rule 复制规则3 表示 Erasure Rule 纠删码规则 0 表示 Any 适用于不需要特定数据保护策略的场景 2 表示 Raw 适用于需要直接存储在 OSD 上的场景,而不应用任何数据保护策略 |
min_size |
该规则下的最小副本数量。 |
max_size |
该规则下的最大副本数量。 |
steps |
一个数组,包含一系列步骤,每个步骤定义了数据的分布操作 |
3. 常见的步骤 steps
-
take
: 指定从哪个 bucket 开始选择
item
: bucket 的 ID
item_name
(可选):bucket 的名称 -
chooseleaf_firstn
:选择一定数量的叶子节点
num
: 选择的节点数量,0 表示所有符合条件的节点
type
: 选择的节点类型(如 host、rack 等) -
emit
: 完成规则定义,确定数据位置
三、创建 CRUSH 规则
1. 创建 bucket
- 分别创建了
my-ssd
、my-hdd
参数说明ceph osd crush add-bucket <name> <type> [options]
参数 | 说明 |
---|---|
<name> |
bucket 的名称。 |
<type> |
bucket 的类型(如 root、datacenter、rack、host 等)。 |
[options] |
其他可选参数。--weight <weight> : 指定 bucket 的权重。--alg <algorithm> : 指定 bucket 的选择算法(如 straw、straw2、uniform)。--hash <hash> : 指定 bucket 的散列函数(如 rjenkins1、sha1)。 |
ceph osd crush add-bucket my-ssd root
ceph osd crush add-bucket my-hdd root
- 删除
bucket
。bucket
必须空
ceph osd crush rm my-hdd
2. 将子 bucket 添加到 root bucket 中
在创建 osd 时候 ceph 会自动生成一个 osd 宿主机的 bucket。
一般自己创建一个 root 的 bucket。然后将 ceph 生成的 bucket 放入自定义的 bucket 中
- 将对应的
bucket
移动到root bucket
参数说明ceph osd crush move <name> <bucket-type>=<parent-bucket-name>
参数 | 说明 |
---|---|
<name> |
要移动的 bucket 或 OSD 的名称。 |
<bucket-type> |
新的父 bucket 的类型(如 root、datacenter、rack、host)。 |
<parent-bucket-name> |
新的父 bucket 的名称。 |
ceph osd crush move HOST-01 root=my-ssd
ceph osd crush move HOST-03 root=my-hdd
- 查看
crush tree
root@HOST-01:~/ceph-crush# ceph osd crush tree
ID CLASS WEIGHT TYPE NAME
-11 80.05099 root my-hdd
-3 80.05099 host HOST-03
0 hdd 80.05099 osd.0
-10 0.21799 root my-ssd
-7 0.21799 host HOST-01
1 ssd 0.21799 osd.1
-1 0 root default
3. 也可以将指定的 osd 移动到 bucket 中
参数说明 ceph osd crush add <osd-id> <weight> <bucket-type>=<bucket-name> [<options>]
参数 | 说明 |
---|---|
<osd-id> |
OSD 的标识符(如 osd.0)。 |
<weight> |
OSD 的权重。权重通常与 OSD 的存储容量成正比。 |
<bucket-type> |
目标 bucket 的类型(如 host)。 |
<bucket-name> |
目标 bucket 的名称。 |
ceph osd crush add osd.1 1.0 root=my-ssd
4. 创建新的CRUSH规则
当然也可以省略上面3步,直接创建规则
- 创建规则
参数说明
ceph osd crush rule create-replicated <rule-name> <root> <choose-type> <choose-name>
参数 | 说明 |
---|---|
<rule-name> |
规则的名称,自定义 |
<root> |
规则应用的根 bucket
|
<choose-type> |
CRUSH 规则在选择存储设备时的层级类型 |
<choose-name> |
选择特定类型设备的名称(不传就是用什么盘都行) |
ceph osd crush rule create-replicated my-ssd-rule my-ssd host ssd
ceph osd crush rule create-replicated my-hdd-rule my-hdd host
- 查看 crush class
这个 class 一般是部署集群时根据 osd 类型自动创建的
ceph osd crush class ls
如果想添加一个新的
1. 先移除原来 osd 的 class
ceph osd crush rm-device-class 7
2. 在设置新的 class
ceph osd crush set-device-class ssd 7
3. 再次查看
ceph osd crush class ls
- 删除规则
ceph osd crush rule rm <rule-name>
5. 创建指定 CRUSH 的池
参数说明 ceph osd pool create <pool-name> <pg-num> [pgp-num] [<options>]
参数 | 说明 |
---|---|
<pool-name> |
新存储池的名称。 |
<pg-num> |
要为存储池创建的 PG 数量。 |
[pgp-num] |
要为存储池创建的 PGP 数量(可选,通常与 PG 数量相同)。 |
[<options>] |
其他可选参数和设置。replicated : 指定创建的存储池类型为复制池。erasure : 指定创建的存储池类型为纠删码池。erasure-code-profile : 用于指定纠删码配置文件的名称(如果池类型为纠删码池)。ruleset : 指定用于池的 CRUSH 规则集 ID。crush-rule : 指定用于池的 CRUSH 规则名称。--expected-num-objects : 用于指定预计存储池中对象的数量,以优化 PG 数量设置。 |
ceph osd pool create ssd-pool 128 128 replication my-ssd-rule
6. 将 CRUSH 规则应用到特定的池
ceph osd pool set hdd-pool crush_rule my-hdd-rule
7. 查看池的规则
ceph osd pool get <pool-name> crush_rule