「CEPH」- 概念术语:放置组(Placement Group,PG)

问题描述

Ceph 可通过副本或纠删码实现数据持久性,通过清洗或循环冗余校验保证数据完整,实现复制、重新平衡和故障恢复。

但是,在 EB 级存储集群中,存储池可能存储数百万个数据对象。数据的复制、移动,会存在性能问题。

解决方案

Ceph 通过将 Pool 划分为 PG(Placement Group,放置组)来解决性能瓶颈问题。PG 是一个非常重要的概念,对其进行合理设置可以提高集群的性能。有效地分配 PG,以提高集群性能;

原理简述

Pool, PG and Data

Pool 被分隔为 PG ,即 PG 是 Pool 的子集
PG 是数据对象的集合,即 PG 中包含数据对象。

例如,每个 Pool 分配 PG * 100,意味着每个 PG 大约包含 Pool 中 1% 的数据。

数据保存在 Pool 中,而 Pool 被分为多个 PG,而 PG 其中包含多个 Object;
最终 PG 将其中的数据存储在 OSD 中;
PG 是若干 Object 的逻辑集合;
PG 会被复制和分布到多个 OSD 上;
以 PG 为单位,Ceph 来进行数据的复制、副本;

CRUSH算法用于在Ceph中定位存储数据的位置,并计算放置组中的OSD目标集。CRUSH算法将每个对象放入一个放置组,然后将每个放置组存储在一组OSD中。

数据读写的大致过程

系统管理员在创建或修改 Pool 时,设置 PG 数。

Ceph将一个存储池划分为一系列放置组,每一个客户端对象都会分配给一个放置组,然后将该放置组分配给一个主OSD。由于Ceph通过设置副本数量或纠删码级别对数据进行保护,因此Ceph会根据副本数或者纠删码中校验盘的数量选择OSD,并将主OSD中的放置组复制到从OSD。如果主OSD发生故障或集群做了数据重新平衡,Ceph可以对集群中现有非主OSD上保存的放置组数据进行复制或移动。因为有了放置组,对象所在的OSD位置就清楚了。即便是OSD有损坏,你也不必为每个对象单独寻址。CRUSH算法会结合Cluster Map和集群的状态将放置组均匀、伪随机地分配给集群中的OSD(包括主OSD和从OSD)。

PG 在 OSD 间复制,保证集群数据安全的方法:
1)CRUSH 算法将 OBJ 00 分配给 PG 00,并且将 PG 00 分配给 OSD 01,让 OSD 1 作为 Primary OSD。
2)CRUSH 算法计算出 OSD 04 是 PG 00 的 Secondary OSD,则 Primary OSD 01 将 PG 00 内容数据复制到 OSD 01 和 OSD 04。

数量配置

集群 PG 总数

集群 PG 总数 = (OSD 总数)×(每个 OSD 的 PG 数量)/(副本数或纠删码 K+M)

例如,Ceph Cluster 有 OSD * 100,推荐每个 OSD 配置 100~200 个 PG。假设 PG 数取值 100,集群采用 3 副本进行数据冗余,那么集群放置组需配置 (100×100/3)=3333 个。注意,此值要取 2 的幂次方(要取大于3333的2的幂次方),距离3333最近的2的幂次方数为4096,因此集群最大的放 PG 为4096。

Ceph 提供参数 mon_target_pg_per_osd 对 OSD 上 PG 数量进行限制。
为了减少 OSD 节点上的资源消耗,建议每个 OSD 配置 50~100 个 PG,但是也有的资料上推荐每个 OSD 配置 100~200 个 PG;

单个 Pool 的 PG 数量

当系统管理员创建一个 Pool 时,通过 pg_num 指定 PG 数量,然后 CRUSH Algorithm 为该存储池创建用户定义数量的 PG。所以参数 pg_num 会影响每个 PG 内存放的对象数。

比如,有10000个对象要关联到存储池,此 Pool 的 pg_num=100 ,那么每个 PG 内平均有100个对象(通常不是平均分配的,这里只是举个例子)。如果调整 pg_num=200,那么平均每个 PG 内的对象数量就降到 50。因此,pg_num 可决定 PG 数,影响 PG 中存放对象的数量。

PG 的数量要设置得合理:
1)如果存储池中的 PG 太少,那么单个 PG 包含的数量较多,PG 移动时将占用较多的带宽;
2)如果存储池中的 PG 太多,那么单个 PG 包含的数量较少,PG 移动时将占用较多 CPU 和 RAM;

当知道集群的 PG 总数量后,那么 PG 如何分给 Pool 呢?可以按照集群中 Pool 的数量进行数据存储百分比规划。

例如,对于 100个OSD、3副本集群,最多配置 PG * 4096,假设规划 Pool * 2,其中 Pool A 预计存储量占整个集群存储量的 75%,那么 Pool A 的 PG 数为 3072。Pool B 预计存储量占整个集群存储量的25%,那么Pool B 的 PG 数为1024。通常,存储池的 PG 数要设置为2的幂次方,如果 Pool A 的 PG 数向上调整,那么集群总的 PG 数将大于之前计算的值。如果这样强制设置 PG ,集群会报告too many PGs per OSD,因此要向下调整 Pool A 的 PG 数,即调整为2048。

状态类型

Ceph 将 PG 的副本存储在多个 Ceph OSD 上,PG 的每个副本都有一个状态,即 PG 状态。

PG 的状态可能有很多种,甚至可能处于某种混合的状态。

集群的总体健康状态主要依赖于 PG;
只有当所有的 PG 都处于 active+clean 状态,集群状态才能保持 HEALTH_OK;
如果 Ceph 集群处于非健康状态,那么非常可能是因为集群中的某个 PG 不是处于 active + clean 状态;

常见状态

Creating(创建中):表示 PG 正在被创建;
当创建 Pool;或 增加 Pool 的 PG 数量时;

Active(活动的): 当 Peering 操作完成之后,PG 会被标记为 Active 状态。如果 PG 处于 Active 状态,那么在其主 PG 和其副本中存储的数据在 IO 操作中都是可用的;

Clean(清洁的): 该状态表示主 OSD 和从 OSD 之间已经 Peering 成功,并且都处于正确的位置。同时,这个状态的 PG 还表示他们的副本个数是正确的;

Backfilling(回填中): 当一个新的 OSD 被加到集群时,Ceph 会把其他 OSD 上的一些 PG 移动到新加入的 OSD 上,来对数据进行重新平衡,这个过程就被称为 Backfilling。完成了 PG 的 Backfilling 之后,新的 OSD 就可以参与客户端 IO 操作了;

Backfill-wait(回填-等待):PG 正待等待开始回填操作;

Peering(对等互联中): 让 存储某个 PG 的全部 OSD 关于 该 PG 内的所有对象(和他们的元数据) 达成一致状态的过程;
注意,一致状态并不等同于它们具有最新的数据。
Peering 完成后,Primary OSD 就能接收 Client 的写入请求。

Replay(重做):某 OSD 崩溃后,PG 正在等待客户端重新发起操作;

Splitting(分割中):PG 正在被分割为多个 PG;当增加 Pool 的 PG 数量,则会出现该状态;

Scrubbing(清理中):PG 正在做不一致性校验;

Down(失效的): 该状态表示包含 PG 必要数据的一个副本不可用,因此该 PG 处于离线状;

Degraded(降级的): 一旦 OSD 处于 DOWN 状态,Ceph 就会把此 OSD 上的所有 PG 改为 Degraded 状态。当 OSD 回到 UP 状态,就要重新进行 Peering 操作,以使 PG 从 Degraded 回到 Clean 状态。如果 OSD 处于 DOWN 状态超过 300 秒,Ceph 会从 被 Degraded 的 PG 的副本 中对其进行恢复,以维持副本数量。即便是 PG 处于 Degraded 状态,客户端也可以进行 IO 操作;

Recovering(恢复中): 当 OSD 变为 DOWN 状态时,该 OSD 上的 PG 中的内容就会滞后于其他 PG 副本中的内容。当 OSD 变为 UP 状态时,Ceph 会激活对 PG 的 Recovery 操作,以使其与其他 OSD 上的 PG 副本保持一致;

Repair(修复):PG 正在被检查。发现任何不一致,都将尽可能地被修复。

Remapped(重映射):如果 PG 的 Acting-Set 有所变动,数据就要从 Old Acting-Set OSD 迁移到 New Acting-Set OSD。该操作会需要花费一些时间,有具体耗时取决于要迁移到新 OSD 的数据量。在这段时间中,旧 Acting-Set 的主 OSD 负责为客户端的请求提供服务。一旦数据迁移操作完成,Ceph 就会使用新 Acting-Set 的 Primary OSD;

Stale(陈旧的): Ceph OSD 每隔 0.5s 向 Ceph MON 报告一次状态统计数据。无论如何,只要 PG Acting-Set 的 Primary OSD 没有向 MON 报告状态统计数据,或者其他 OSD 向 MON 报告 Primary-OSD 已经处于 DOWN 状态,那么 MON 就会将这些 PG 设置为 Stale 状态;
启用新集群后,常常会看到在 Peering 结束前 PG 处于该状态;

Inconsistent(不一致的):PG 的副本出现了不一致。例如,对象大小不正确,或者 Recovery 结束后,某副本出现对象丢失的情形;

查看状态

# ceph pg stat
113 pgs: 113 active+clean; 107 MiB data, 20 GiB used, 160 GiB / 180 GiB avail

// 107 MiB data: 原始数据量;
// 20 GiB used:包含副本在内的总数据量;

# ceph pg dump -f json-pretty

# ceph pg <PG_ID> query

# ceph pg dump_stuck <unclean | inactive | stale>

数量设置

现在我们应该意识到,随着 OSD 数量的增加,选择一个合适的 PG 值将变得更加重要,因为该值将会显著地影响集群的运行行为。

在一个大型集群中增加 PG 值是个昂贵的操作。建议阅读 CHOOSING THE NUMBER OF PLACEMENT GROUPS 文档,以了解 PG 的最新信息。