Ceph 的存储架构设计旨在提供高可用性和可扩展性。其中,Pool(存储池)和 PG(放置组)是两个核心概念。下面详细介绍 Ceph 的 Pool 和 PG 架构以及它们之间的关系。
1. Pool池
概念:
- Pool(存储池)是Ceph中逻辑上的存储单元,是存储Object对象的逻辑分区,用于组织和管理数据。用户可以通过创建不同的Pool来为不同的应用程序或用途分配存储空间。
- Pool可以是replicated(复制型)或erasure-coded(纠删码型)。复制型Pool通过生成数据的多份拷贝来确保数据的高可靠性和可用性,而纠删码型Pool则通过将数据分割成多个数据块和校验块,利用校验块来恢复数据,从而在节省存储空间的同时提供数据保护。
主要参数
- size:每个对象的副本数。例如,
size=3
表示每个对象有 3 个副本。 - min_size:在某些 OSD 故障时,允许的最小副本数。例如,
min_size=2
表示即使只有 2 个副本可用,数据仍然被认为是安全的。 - pg_num:Pool 中的 PG 数量。这是一个关键参数,会影响性能和数据分布。
- pgp_num:用于计算对象到 PG 映射的 PG 数量。通常设置为与
pg_num
相同。 - crush_rule_set:CRUSH 规则集,用于确定数据如何在 OSD 之间分布。
2. PG(Placement Group)
概念:
- PG是Ceph中物理上的数据分布单位,用于将数据分散到不同的OSD(Object Storage Daemon)上。每个Pool由多个PG组成,每个PG负责一部分数据的管理和存储。
主要特点
- 数据分布:对象首先被映射到 PG,然后 PG 被分配到特定的 OSD。这种两层映射机制使得数据分布更加均匀。
- 复制:每个 PG 的副本会被分配到不同的 OSD,以确保高可用性。
- 数据恢复:当某个 OSD 故障时,Ceph 会从其他副本中恢复数据,并重新分配到新的 OSD。
3. 对象到 PG 的映射
对象到 PG 的映射是通过哈希函数实现的。具体步骤如下:
- 计算哈希值:使用对象的名称(或 ID)计算哈希值。
- 取模运算:将哈希值对
pg_num
取模,得到 PG 的 ID。 - 分配到 PG:将对象分配到对应的 PG。
公式如下:
pg_id = hash(object_name) % pg_num
4. PG 到 OSD 的映射
PG 到 OSD 的映射是通过 CRUSH 算法实现的。CRUSH 算法考虑了集群的物理拓扑结构(如机架、主机等),以确保数据的均匀分布和高可用性。
- CRUSH 地图:CRUSH 地图定义了集群的物理拓扑结构和规则集。
- 选择 OSD:根据 CRUSH 地图和规则集,将 PG 分配到特定的 OSD。
5. 配置建议
- pg_num 和 pgp_num:这两个参数应该设置为相同的值。通常情况下,
pg_num
应该是 OSD 数量的 100 倍左右,以确保数据分布均匀。 - CRUSH 规则集:根据实际的物理拓扑结构和需求,选择合适的 CRUSH 规则集。
- 性能调优:可以通过调整
pg_num
和pgp_num
来优化性能。增加 PG 数量可以提高并行度,但也会增加管理开销。
总结
- Pool 是 Ceph 中用于组织和管理数据的基本单位。
- PG 是 Ceph 中用于管理数据分布和复制的逻辑单元。
- 对象到 PG 的映射 通过哈希函数实现。
- PG 到 OSD 的映射 通过 CRUSH 算法实现。
- 配置建议 包括合理设置
pg_num
和pgp_num
,选择合适的 CRUSH 规则集,以及根据实际需求进行性能调优。
估算PG数量的一些方法
设置 Ceph 存储池的 PG(Placement Group)数量是一个重要的配置步骤,因为它直接影响到集群的性能和数据分布。以下是一些指导原则和步骤,帮助你合理设置 PG 数量。
1. 基本公式
一个常用的公式来计算 PG 数量是: pg_num=100×OSD 数量pg_num=100×OSD 数量
2. 考虑因素
- OSD 数量:PG 数量应与 OSD 数量成正比。更多的 OSD 需要更多的 PG 来确保数据均匀分布。
- 存储池大小:较大的存储池可能需要更多的 PG 来提高并行度和性能。
- 数据分布:合理的 PG 数量可以确保数据在 OSD 之间均匀分布,避免热点问题。
- 管理开销:过多的 PG 会增加管理开销,因此需要在性能和管理之间找到平衡。
3. 推荐范围
- 小型集群(10 个以下 OSD):建议
pg_num
为 100 到 500。 - 中型集群(10 到 100 个 OSD):建议
pg_num
为 500 到 2000。 - 大型集群(100 个以上 OSD):建议
pg_num
为 2000 到 10000。
4. 动态调整 PG 数量
Ceph 允许在创建存储池后动态调整 pg_num
和 pgp_num
。但是,建议在创建存储池时就设置合理的初始值,以避免后续调整带来的性能影响。
Pool管理操作及其对应的命令格式
操作 | 命令格式 | 描述 |
---|---|---|
创建Pool | ceph osd pool create {pool-name} {pg-num} [{pgp-num}] [replicated] [crush-ruleset-name] | 创建一个新的Pool,指定Pool名称、PG数量、PGP数量(可选)、副本类型(默认为replicated)、以及可选的Crush规则集。 |
查看所有Pool | ceph osd lspools 或 rados lspools | 列出集群中所有的Pool。 |
查看Pool详情 | ceph osd pool get {pool-name} {option} | 查看指定Pool的详细参数,如size、min_size、pg_num、pgp_num等。 |
修改Pool参数 | ceph osd pool set {pool-name} {option} {value} | 修改指定Pool的参数设置,如副本数、最小副本数、PG数、PGP数等。 |
删除Pool | ceph osd pool delete {pool-name} {pool-name} --yes-i-really-really-mean-it | 删除指定的Pool,需确认删除操作以避免误操作导致数据丢失。 |
重命名Pool | ceph osd pool rename {current-pool-name} {new-pool-name} | 将Pool的名称从旧名称更改为新名称。 |
查询Pool配额 | ceph osd pool get-quota {pool-name} | 查询指定Pool的容量和最大Object数目配额。 |
设置Pool配额 | ceph osd pool set-quota {pool-name} max_objects|max_bytes <val> | 设置指定Pool的容量和最大Object数目配额。 |
查询Pool属性 | ceph osd pool stats {pool-name} | 查询指定Pool的统计信息,如存储容量、对象数量等。 |
创建Pool快照 | ceph osd pool mksnap {pool-name} {snap-name} | 对指定Pool中的所有对象创建快照。 |
查询Pool快照 | rados lssnap --pool={pool-name} | 查询指定Pool的快照列表。 |
回滚Pool快照 | rados rollback {obj-name} {snap-name} --pool={pool-name} | 目前仅支持对Pool中的单个对象进行快照回滚,不支持整个Pool的回滚。 |
PG(Placement Group)相关的命令
命令 | 描述 |
---|---|
ceph pg stat | 显示集群中所有PG的简要状态概述,包括活跃(active)、降级(degraded)等状态的PG数量。 |
ceph pg dump | 打印所有PG的详细信息,包括PG ID、状态、主副本位置、数据量等。输出格式为JSON,包含丰富的信息用于深入分析和调试。 |
ceph pg map {pg-id} | 显示指定PG的映射信息,包括PG的主OSD和副本所在的OSD。 |
ceph pg {pg-id} query | 查询指定PG的详细信息,但请注意,这个命令的确切形式可能因Ceph版本而异,通常ceph pg {pg-id} 加上适当的参数或选项来查询详细信息。 |
ceph pg scrub {pg-id} | 对指定PG执行scrub操作,检查PG的数据一致性。这有助于发现潜在的数据损坏问题。 |
ceph pg deep-scrub {pg-id} | 对指定PG执行深度scrub操作,比普通的scrub更为彻底,用于更严格的数据一致性检查。 |
ceph pg repair {pg-id} | 修复指定PG中发现的不一致或损坏的数据。这个操作可能会影响集群性能,并且存在数据修复的风险,因此建议在有备份或清楚问题来源时使用。 |
ceph osd pool set {pool-name} pg_num {pg-count} | 设置指定Pool中的PG数量。这是调整Pool性能和数据分布的重要步骤。 |
ceph osd pool get {pool-name} pg_num | 获取指定Pool中的PG数量。这有助于了解Pool的当前配置。 |
ceph pg dump_stuck {state} | 显示处于特定stuck状态的PG信息。例如,ceph pg dump_stuck unclean 将显示所有处于unclean状态的stuck PG。 |
ceph pg mark_unfound_lost revert | 用于恢复一个丢失的PG,但请注意,这个命令的确切用法可能因Ceph版本而异,且通常用于特殊恢复场景。 |