注意

本文档适用于 Ceph 的开发版本。

放置组

放置组(PG)是每个逻辑 Ceph 池的子集。放置组执行将对象(作为一个组)放置到 OSD 中的功能。Ceph 在内部以放置组粒度管理数据:这比管理单个 RADOS 对象具有更好的可扩展性。具有较多放置组(例如,每个 OSD 150 个)的集群比具有较少放置组的相同集群平衡得更好。

Ceph 的内部 RADOS 对象每个都映射到特定的放置组,并且每个放置组都只属于一个 Ceph 池。

有关放置组与池和对象之间关系的更多信息,请参阅 Sage Weil 的博客文章 Nautilus 新功能:PG 合并和自动调整

自动调整放置组大小

放置组(PG)是 Ceph 如何分发数据的内部实现细节。自动调整大小提供了一种管理 PG 的方法,尤其是管理不同池中存在的 PG 数量。当启用 *pg-autoscaling* 时,集群会根据观察到的和预期的池利用率,针对每个池的 PG 数量(pgp_num)提出建议或进行自动调整。

每个池都有一个 pg_autoscale_mode 属性,可以设置为 offonwarn

  • off:禁用此池的自动调整。由管理员为每个池选择适当的 pg_num。有关更多信息,请参阅 选择 PG 数量

  • on:为给定池启用 PG 计数的自动调整。

  • warn:当 PG 计数需要调整时,引发健康检查警告。

要为现有池设置自动调整模式,请运行以下形式的命令

ceph osd pool set <pool-name> pg_autoscale_mode <mode>

例如,要为池 foo 启用自动调整,请运行以下命令

ceph osd pool set foo pg_autoscale_mode on

还有一个中心配置 pg_autoscale_mode 选项,用于控制集群初始设置后创建的池的自动调整模式。要更改此设置,请运行以下形式的命令

ceph config set global osd_pool_default_pg_autoscale_mode <mode>

您可以使用 noautoscale 标志禁用或启用所有池的自动调整。默认情况下,此标志设置为 off,但您可以通过运行以下命令将其设置为 on

ceph osd pool set noautoscale

要将 noautoscale 标志设置为 off,请运行以下命令

ceph osd pool unset noautoscale

要获取该标志的当前值,请运行以下命令

ceph osd pool get noautoscale

查看 PG 缩放建议

要查看每个池、其相对利用率以及对 PG 计数的任何建议更改,请运行以下命令

ceph osd pool autoscale-status

输出将类似于以下内容

POOL    SIZE  TARGET SIZE  RATE  RAW CAPACITY   RATIO  TARGET RATIO  EFFECTIVE RATIO BIAS PG_NUM  NEW PG_NUM  AUTOSCALE BULK
a     12900M                3.0        82431M  0.4695                                          8         128  warn      True
c         0                 3.0        82431M  0.0000        0.2000           0.9884  1.0      1          64  warn      True
b         0        953.6M   3.0        82431M  0.0347                                          8              warn      False
  • POOL 是池的名称。

  • SIZE 是池中存储的数据量。

  • TARGET SIZE(如果存在)是管理员指定的预期存储在池中的数据量。系统使用 SIZETARGET SIZE 中较大的一个进行计算。

  • RATE 是池的空间放大因子,表示对于给定量的用户数据,消耗了多少原始存储容量。例如,三副本池将显示值为 3.0,而 k=4 m=2 纠删码池将显示值为 1.5。

  • RAW CAPACITY 是特定 OSD 上可用于池的总原始存储容量。请注意,在许多情况下,此容量由多个池共享。

  • RATIO 是池消耗的存储量与总原始存储容量之比。换句话说,RATIO 定义为 (SIZE * RATE) / RAW CAPACITY,可以视为填充百分比。

  • TARGET RATIO(如果存在)是此池的预期存储量与设置了目标比例的所有其他池的预期存储量之比。如果同时指定了 target_size_bytestarget_size_ratio,则 target_size_ratio 优先。请注意,当 BIAS 值不为 1 时(特别是对于 CephFS 元数据和 RGW 索引池),最好不要调整目标比例,因为同时调整两者可能会导致通过双重计算得到不适当的 pg_num 值。

  • EFFECTIVE RATIO 是对目标比例进行两次调整后的结果

    1. 减去预期被设置了目标大小的池使用的任何容量。

    2. 对设置了目标比例的池之间的目标比例进行归一化,使其总共以集群容量为目标。例如,四个目标比例为 1.0 的池将各自具有 0.25 的有效比例。

    系统的计算使用这两个比例(即目标比例和有效比例)中较大的一个。

  • BIAS 用作乘数,用于根据关于特定池预期有多少 PG 的先验信息手动调整池的 PG。这对于主要将数据存储在 omaps 而非 RADOS 对象中的池非常重要,特别是 RGW 索引和 CephFS / RBD EC 元数据池。当池的偏差值设置为非 1.0 时,建议不要设置目标比例。

  • PG_NUM 是与池关联的当前 PG 数量,或者如果正在进行 pg_num 更改,则是目标值。

  • NEW PG_NUM(如果存在)是系统建议池的 pg_num 应该设置的值。它始终是二的幂,并且仅当建议值与当前值的差异超过缩放阈值时才存在。此阈值默认为配置的因子 3。虽然缩小时仅使用配置的因子,但在放大时会动态降低阈值:如果建议的 NEW PG_NUM 为 512 或 1024,则设置为 1.0,如果建议的 NEW PG_NUM 为 2048,则设置为 2.0。要调整此乘数(在以下示例中,将其更改为 2),请运行以下形式的命令

    ceph osd pool set threshold 2.0
    

    要获取当前 threshold 值,请运行以下命令

    ceph osd pool get threshold
    
  • AUTOSCALE 是池的 pg_autoscale_mode,设置为 onoffwarn

  • BULK 确定池是否为 bulk。其值为 TrueFalse。预期 bulk 池会很大,并且最初应具有大量的 PG,以免影响性能。另一方面,预期非 bulk 池会很小(例如 .mgr 池或元数据池)。

注意

如果 ceph osd pool autoscale-status 命令根本不返回输出,则可能至少有一个池跨越多个 CRUSH 根。这种“跨越池”问题可能发生在以下情况:当新部署自动在 default CRUSH 根上创建 .mgr 池时,后续创建的池的规则将其限制为特定的影子 CRUSH 树。例如,如果您创建了一个受 deviceclass = ssd 限制的 RBD 元数据池和一个受 deviceclass = hdd 限制的 RBD 数据池,您将遇到此问题。要解决此问题,请将跨越池限制为一个设备类。在上述情况下,可能存在一个 replicated-ssd CRUSH 规则,并且可以通过运行以下命令将 .mgr 池限制为 ssd 设备

ceph osd pool set .mgr crush_rule replicated-ssd

这种干预将导致少量回填,但这通常不会造成中断,并且会很快完成。

自动缩放

在自动缩放的最简单方法中,允许集群根据使用情况自动缩放每个池的 pg_num。Ceph 会考虑总可用存储空间、每个 OSD 的目标 PG 副本数以及每个池中存储的数据量,然后相应地分配 PG。系统采用保守的方法,仅当当前 PG 数量(pg_num)与建议数量的差异超过缩放阈值时才对池进行更改。缩小时,仅使用配置的因子。但是,在放大时,阈值会动态降低:当建议的 NEW PG_NUM 为 512 或 1024 时,它会自动设置为 1.0,当为 2048 时,设置为 2.0。

每个 OSD 的目标 PG 数量由 mon_target_pg_per_osd 参数(默认值:100)确定,可以通过运行以下命令进行调整

ceph config set global mon_target_pg_per_osd 100

除了最小的部署之外,建议值为 200。高于 500 的值可能会导致过度的对等流量和 RAM 使用。

自动缩放器按每个子树分析和调整池。因为每个池可能映射到不同的 CRUSH 规则,并且每个规则可能将数据分布到不同且可能重叠的设备集上,所以 Ceph 将独立考虑 CRUSH 层次结构中每个子树的利用率。例如,映射到 ssd 类别 OSD 的池和映射到 hdd 类别 OSD 的池将各自计算 PG 计数,该计数由这两种不同设备类型的 OSD 数量决定。

如果一个池使用两个或更多 CRUSH 根下的 OSD(例如,具有 ssdhdd 设备的影子树),自动缩放器会在管理器日志中向用户发出警告。警告说明了池的名称以及相互重叠的根集。自动缩放器不会缩放具有重叠根的任何池,因为这种情况可能会导致缩放过程出现问题。我们建议将每个池约束为仅属于一个根(即一个设备 OSD 类别),以消除警告并确保成功缩放。

管理标记为 bulk 的池

如果一个池被标记为 bulk,则自动缩放器会以完整的 PG 数量启动该池,然后仅当池中的使用比例不均匀时才缩减 PG 数量。但是,如果一个池没有被标记为 bulk,则自动缩放器会以最小的 PG 数量启动该池,并且仅当池中有更多使用时才创建额外的 PG。应谨慎使用此标志,因为它可能无法产生预期的结果。

要创建一个将标记为 bulk 的池,请运行以下命令

ceph osd pool create <pool-name> --bulk

要设置或取消设置现有池的 bulk 标志,请运行以下命令

ceph osd pool set <pool-name> bulk <true/false/1/0>

要获取现有池的 bulk 标志,请运行以下命令

ceph osd pool get <pool-name> bulk

指定预期的池大小

当集群或池首次创建时,它仅消耗总集群容量的一小部分,并且在系统看来似乎只需要少量的 PG。但是,在某些情况下,集群管理员知道哪些池最终可能会消耗大部分系统容量。当 Ceph 提供此信息时,可以从一开始就使用更适当的 PG 数量,从而避免后续更改 pg_num 以及随之而来的数据重新定位开销。这还有助于性能和数据均匀性,确保 PG 放置在所有可用的 OSD 上。

池的 *目标大小* 可以通过两种方式指定:要么相对于池的绝对大小(以字节为单位),要么作为相对于所有设置了 target_size_ratio 的其他池的权重。

例如,要告诉系统 mypool 预计将消耗 100 TB,请运行以下命令

ceph osd pool set mypool target_size_bytes 100T

或者,要告诉系统 mypool 预计将消耗相对于设置了 target_size_ratio 的其他池的比例为 1.0,请通过运行以下命令调整 my pooltarget_size_ratio 设置

ceph osd pool set mypool target_size_ratio 1.0

如果 mypool 是集群中唯一的池,则预计它将使用 100% 的总集群容量。但是,如果集群包含第二个设置了 target_size_ratio 为 1.0 的池,则这两个池都预计将使用 50% 的总集群容量。

ceph osd pool create 命令有两个命令行选项可用于在创建时设置池的目标大小:--target-size-bytes <bytes>--target-size-ratio <ratio>

请注意,如果指定的目标大小值是不可能的(例如,容量大于集群总容量),则会引发健康检查(POOL_TARGET_SIZE_BYTES_OVERCOMMITTED)。

如果同时为池指定了 target_size_ratiotarget_size_bytes,则后者将被忽略,前者将用于系统计算,并会引发健康检查(POOL_HAS_TARGET_SIZE_BYTES_AND_RATIO)。

请注意,在大多数情况下,建议不要在同一个池上同时设置非 1.0 的偏差值和目标比例。对元数据/omap-丰富池使用更高的偏差值,对 RADOS 数据密集型池使用目标比例。

指定池 PG 的界限

可以为池指定 PG 的最小数量和最大数量。

设置最小 PG 数量或最大 PG 数量

如果为池设置了最小值,则 Ceph 本身不会将该池的 pg_num 减少(也不会建议您减少)到低于配置值的值。设置最小值有助于为客户端在 I/O 期间享受的并行性建立下限,即使池大部分为空。

如果设置了最大值,则 Ceph 本身不会将 PG 数量增加(也不会建议您增加)到高于配置值的值。

要为池设置最小 PG 数量,请运行以下形式的命令

ceph osd pool set <pool-name> pg_num_min <num>

要为池设置最大 PG 数量,请运行以下形式的命令

ceph osd pool set <pool-name> pg_num_max <num>

此外,ceph osd pool create 命令有两个命令行选项可用于在创建时指定池的最小或最大 PG 计数:--pg-num-min <num>--pg-num-max <num>

预选 pg_num

使用以下命令创建池时,您可以选择预选 pg_num 参数的值

ceph osd pool create {pool-name} [pg_num]

如果您选择在此命令中不指定 pg_num,则集群会使用 PG 自动缩放器根据池中存储的数据量自动配置该参数(请参阅上面的 自动调整放置组大小)。

但是,您在创建时是否指定 pg_num 的决定对该参数之后是否会自动由集群调整大小没有影响。如上所述,通过运行以下形式的命令来启用或禁用 PG 的自动缩放

ceph osd pool set {pool-name} pg_autoscale_mode (on|off|warn)

如果没有平衡器,大多数集群的建议(但非默认)目标是每个 OSD 200 个 PG 副本。启用平衡器并使用默认值时,预期初始结果是每个 OSD 大约 50-70 个 PG 副本。这是在 ceph df 输出的 PGS 列下报告的值,值得注意的是,它不是集群 PG 总数除以 OSD 数量的值。

自动缩放器尝试满足以下条件

  • 每个 OSD 的 PG 副本数量应与池中的数据量成比例。

  • 默认情况下,每个池应有 50-100 个 PG,同时考虑到每个 PG 副本在 OSD 上的复制开销或纠删码扇出。

放置组的使用

放置组聚合池中的对象。按对象跟踪 RADOS 对象的放置和对象元数据在计算上是昂贵的。对于具有数百万 RADOS 对象的系统来说,按对象高效跟踪放置是不可行的。

Ceph 客户端计算 RADOS 对象应该位于哪个 PG 中。作为此计算的一部分,客户端对对象 ID 进行哈希处理,并执行涉及指定池中的 PG 数量和池 ID 的操作。有关详细信息,请参阅 将 PG 映射到 OSD

属于 PG 的 RADOS 对象的内容存储在一组 OSD 中。例如,在大小为二的复制池中,每个 PG 将在两个 OSD 上存储对象,如下所示

如果 OSD #2 发生故障,另一个 OSD 将被分配给放置组 #1,然后填充 OSD #1 中所有对象的副本。如果池大小从二更改为三,则将为 PG 分配额外的 OSD,并将接收 PG 中所有对象的副本。

分配给 PG 的 OSD 并非由该 PG 独占;相反,OSD 与来自同一池或其他池的其他 PG 共享。在我们的示例中,OSD #2 由放置组 #1 和放置组 #2 共享。如果 OSD #2 发生故障,则放置组 #2 必须恢复对象的副本(通过使用 OSD #3)。

当 PG 数量增加时,会产生几个后果。新 PG 被分配 OSD。CRUSH 函数的结果发生变化,这意味着来自现有 PG 的某些对象被复制到新 PG 并从旧 PG 中移除。

指定 pg_num 的相关因素

性能和 OSD 上的均匀数据分布有利于更高的 PG 数量。节省 CPU 资源和最小化内存使用有利于更低的 PG 数量。后者在 Filestore OSD 被弃用之前更受关注,因此大多数具有 BlueStore OSD 的现代集群可以通过为 mon_target_pg_per_osd 配置 200-250 的值和为 mon_max_pg_per_osd 配置 500 的值来倾向于前者。请注意,后者仅作为故障保护,本身不影响 pg_num 计算。

数据持久性

当 OSD 发生故障时,数据丢失的风险会增加,直到它所托管的数据的复制恢复到配置的级别。为了说明这一点,让我们想象一个导致单个 PG 永久数据丢失的场景

  1. OSD 发生故障,其中包含的所有对象副本都丢失了。对于 PG 中的每个对象,其副本数突然从三降到二。

  2. Ceph 开始为此 PG 进行恢复,方法是选择一个新的 OSD 来重新创建每个对象的第三个副本。

  3. 同一 PG 中的另一个 OSD 在新 OSD 完全填充第三个副本之前发生故障。此时某些对象将只剩下一个幸存副本。

  4. Ceph 选择另一个 OSD 并继续复制对象以恢复所需的副本数。

  5. 同一 PG 中的第三个 OSD 在恢复完成之前发生故障。如果此 OSD 恰好包含对象的唯一剩余副本,则对象将永久丢失。

这是具有 size=2 的复制池和具有 m=1 的 EC 池存在风险且通常不推荐使用的微妙原因之一。

在包含 10 个 OSD 和一个三副本池中的 512 个 PG 的集群中,CRUSH 会将每个 PG 放置在三个 OSD 上。最终,每个 OSD 托管 \(\frac{(512 \times 3)}{10} = \approx 150\) 个 PG。因此,当上述场景中一个 OSD 发生故障时,将触发放置在该 OSD 上的所有约 150 个 PG 的恢复。

要恢复的 150 个 PG 很可能均匀分布在剩下的 9 个 OSD 上。因此,每个剩余的 OSD 都可能将对象副本发送给所有其他 OSD,并且还可能接收一些要存储的新对象,因为它已成为新 PG 的一部分。

完成此恢复所需的时间取决于 Ceph 集群的架构。比较两种设置:(1)每个 OSD 由一台机器上的 1 TB SSD 托管,所有 OSD 连接到 10 Gb/s 交换机,单个 OSD 的恢复在几分钟内完成。(2)每台机器有两个 OSD,使用没有 SSD WAL+DB 的 HDD 和 1 Gb/s 交换机。在第二种设置中,恢复将至少慢一个数量级。

在此类集群中,PG 数量对数据持久性几乎没有影响。无论每个 OSD 有 128 个 PG 还是 8192 个 PG,恢复都不会更慢或更快。

然而,增加 OSD 数量可以提高恢复速度。假设我们的 Ceph 集群从 10 个 OSD 扩展到 20 个 OSD。现在每个 OSD 只参与约 75 个 PG,而不是约 150 个 PG。所有 19 个剩余 OSD 仍然需要复制相同数量的对象才能恢复。但是,现在不是只有 10 个 OSD 必须复制每个约 100 GB 的数据,而是有 20 个 OSD 必须复制每个约 50 GB 的数据。如果以前网络是瓶颈,那么现在恢复速度会快一倍,因为每个 OSD 并行恢复操作的数量限制更大。

同样,假设我们的集群增长到 40 个 OSD。每个 OSD 将只托管约 38 个 PG。如果一个 OSD 死亡,恢复速度将比以前更快,除非被另一个瓶颈阻止。然而,现在假设我们的集群增长到 200 个 OSD。每个 OSD 将只托管约 7 个 PG。如果一个 OSD 死亡,恢复将最多发生在与这些 PG 相关的 \(\approx 21 = (7 \times 3)\) 个 OSD 上。这意味着恢复将比只有 40 个 OSD 时花费更长的时间。因此,应该增加 PG 数量。

无论恢复时间多么短暂,总是有可能在恢复进行时有额外的 OSD 发生故障。考虑上面描述的具有 10 个 OSD 的集群:如果任何一个 OSD 发生故障,则 \(\approx 17\)(大约 150 除以 9)个 PG 将只剩下一个副本。如果剩下的 8 个 OSD 中的任何一个发生故障,则 2 个(大约 17 除以 8)PG 可能会丢失其剩余对象。这是设置 size=2 有风险的一个原因。

当集群中的 OSD 数量增加到 20 个时,因丢失三个 OSD 而受损的 PG 数量显着减少。丢失第二个 OSD 只会降级大约 \(4\) 个(\(\frac{75}{19}\))PG,而不是 \(\approx 17\) 个 PG,并且丢失第三个 OSD 只有在它是包含剩余副本的 4 个 OSD 之一时才会导致数据丢失。这意味着——假设在恢复期间丢失一个 OSD 的概率为 0.0001%——在具有 10 个 OSD 的集群中,丢失三个 OSD 导致数据丢失的概率约为 \(\approx 17 \times 10 \times 0.0001%\),而在具有 20 个 OSD 的集群中仅为 \(\approx 4 \times 20 \times 0.0001%\)

总而言之,OSD 数量越多,恢复越快,因级联故障导致永久丢失 PG 的风险越低。就数据持久性而言,在少于 50 个 OSD 的集群中,PG 数量是 512 还是 4096 并不重要。

注意

将最近添加到集群的 OSD 填充分配给它的 PG 可能需要很长时间。但是,由于 Ceph 在从旧 PG 中移除数据之前将数据填充到新 PG 中,因此此过程的缓慢不会导致对象降级或影响数据持久性。

池中的对象分布

在理想条件下,对象均匀分布在 PG 中。由于 CRUSH 计算每个对象的 PG,但不知道与 PG 关联的每个 OSD 中存储了多少数据,因此 PG 数量与 OSD 数量之间的比例对数据分布有显着影响。

例如,假设在三副本池中,10 个 OSD 只有一个 PG。在这种情况下,只会使用三个 OSD,因为 CRUSH 没有其他选择。但是,如果有更多 PG 可用,RADOS 对象更有可能均匀分布在 OSD 上。CRUSH 会尽力将 OSD 均匀分布到所有现有 PG 上。

只要 PG 数量比 OSD 数量多一到两个数量级,分布就可能均匀。例如:3 个 OSD 对应 256 个 PG,10 个 OSD 对应 512 个 PG,或者 10 个 OSD 对应 1024 个 PG。

然而,除了 PG 与 OSD 的比例之外,其他因素也可能导致数据分布不均。例如,由于 CRUSH 不考虑 RADOS 对象的大小,因此少数非常大的 RADOS 对象可能会造成不平衡。假设一百万个 4 KB 的 RADOS 对象总计 4 GB,均匀分布在 10 个 OSD 上的 1024 个 PG 中。这些 RADOS 对象将占用每个 OSD 4 GB / 10 = 400 MB。如果随后向池中添加一个 400 MB 的 RADOS 对象,则支持放置该 RADOS 对象的 PG 的三个 OSD 将各自填充 400 MB + 400 MB = 800 MB,而其他七个 OSD 仍将只包含 400 MB。

内存、CPU 和网络使用

集群中的每个 PG 都会对 OSD 和监视器施加内存、网络和 CPU 需求。这些需求必须始终得到满足,并且在恢复期间会增加。事实上,PG 开发的主要原因之一是通过将 RADOS 对象聚合到可管理大小的集合中来减少这种开销。

因此,限制 PG 数量可以节省大量资源。

选择 PG 数量

如果您有超过 50 个 OSD,我们建议每个 OSD 大约 100-250 个 PG 副本,以平衡资源使用、数据持久性和数据分布。如果您有少于 50 个 OSD,请遵循 preselection 部分中的指导。对于单个池,使用以下公式获取基线值

PG 总数 = \(\frac{OSDs \times 100}{pool \: size}\)

这里的 pool size 是复制池的副本数或纠删码池的 K+M 总和。要检索此总和,请运行命令 ceph osd erasure-code-profile get

接下来,检查生成的基线值是否与您设计 Ceph 集群以最大化 数据持久性对象分布 并最小化 资源使用 的方式一致。

此值应向上舍入到最接近的二的幂

每个池的 pg_num 应为二的幂。其他值可能会导致数据在 OSD 上的分布不均。最好仅在可行且希望设置下一个更高的二的幂时增加池的 pg_num。请注意,此二的幂规则是针对每个池的;没有必要也不容易将所有池的 pg_num 总和对齐为二的幂。

例如,如果您有一个包含 200 个 OSD 和一个大小为 3 个副本的单个池的集群,请按如下方式估算 PG 数量

\(\frac{200 \times 100}{3} = 6667\)。向上舍入到最接近的二的幂:8192。

当使用多个数据池来存储对象时,请确保平衡每个池的 PG 数量与每个 OSD 的 PG 数量,以便得出合理的 PG 总数。重要的是找到一个在不占用系统资源或使对等过程太慢的情况下,提供每个 OSD 合理低方差的数字。

例如,假设您有一个包含 10 个池的集群,每个池在 10 个 OSD 上有 512 个 PG。这相当于 5,120 个 PG 分布在 10 个 OSD 上,或每个 OSD 512 个 PG。此集群不会使用太多资源。但是,在一个包含 1,000 个池的集群中,每个池在 10 个 OSD 上有 512 个 PG,则每个 OSD 将不得不处理约 50,000 个 PG。此集群将需要显着更多的资源和显着更多的时间进行对等。

设置 PG 数量

放置组链接

在创建池时隐式或显式设置池中的初始 PG 数量。有关详细信息,请参阅 创建池

但是,在创建池之后,如果未使用 pg_autoscaler 来管理 pg_num 值,则可以通过运行以下形式的命令更改 PG 数量

ceph osd pool set {pool-name} pg_num {pg_num}

自 Nautilus 版本以来,每当 pg_num 更改时,无论是通过 PG 自动缩放器还是手动更改,Ceph 都会自动逐步调整池的 pgp_num。管理员通常不需要直接接触 pgp_num,但可以通过 watch ceph osd pool ls detail 监视进度。当 pg_num 更改时,pgp_num 的值会缓慢逐步调整,以便将拆分或合并 PG 的成本分摊到一段时间内,从而最大限度地减少性能影响。

增加池的 pg_num 会拆分该池中的一些 PG,但在池的 pgp_num 增加之前,数据不会通过回填操作迁移到新的 PG。

手动设置 pgp_num 参数是可能的,但很少合适。pgp_num 参数应等于 pg_num 参数。要增加用于放置的 PG 数量,请运行以下形式的命令

ceph osd pool set {pool-name} pgp_num {pgp_num}

如果您减少或增加池的 pg_num,则 pgp_num 会自动调整。在 Nautilus 开始的 Ceph 版本中,当不使用 pg_autoscaler 时,pgp_num 会自动逐步调整以匹配 pg_num。此过程表现为 PG 重新映射和回填期间,这是预期的行为。

获取 PG 数量

要获取池中的 PG 数量,请运行以下形式的命令

ceph osd pool get {pool-name} pg_num

获取集群的 PG 统计信息

要查看集群中 PG 的详细信息,请运行以下形式的命令

ceph pg dump [--format {format}]

有效的格式是 plain(默认)和 json

获取卡住 PG 的统计信息

要查看卡在指定状态的所有 PG 的统计信息,请运行以下形式的命令

ceph pg dump_stuck inactive|unclean|stale|undersized|degraded [--format <format>] [-t|--threshold <seconds>]
  • Inactive PG 无法处理读取或写入,因为它们正在等待足够多的具有最新数据的 OSD 变为 upin

  • Undersized PG 包含未按所需次数复制的对象。在正常情况下,可以假定这些 PG 正在恢复中。

  • Stale PG 处于未知状态——托管它们的 OSD 在一段时间内(由 mon_osd_report_timeout 确定)没有向监视器集群报告。

有效的格式是 plain(默认)和 json。阈值定义了 PG 卡住的最短秒数,超过此时间后才将其包含在返回的统计信息中(默认值:300)。

获取 PG 映射

要获取特定 PG 的 PG 映射,请运行以下形式的命令

ceph pg map {pg-id}

例如

ceph pg map 1.6c

Ceph 将返回 PG 映射、PG 和 OSD 状态。输出类似于以下内容

osdmap e13 pg 1.6c (1.6c) -> up [1,0] acting [1,0]

获取 PG 的统计信息

要查看特定 PG 的统计信息,请运行以下形式的命令

ceph pg {pg-id} query

擦洗 PG

要强制立即擦洗 PG,请运行以下形式的命令

ceph tell {pg-id} scrub

ceph tell {pg-id} deep-scrub

Ceph 检查主 OSD 和副本 OSD,并生成 PG 中所有对象的目录。对于每个对象,Ceph 比较对象的所有实例(在主 OSD 和副本 OSD 中),以确保它们一致。对于浅层擦洗(由第一种命令格式启动),仅比较对象元数据。深度擦洗(由第二种命令格式启动)也比较对象的内容。如果所有副本都匹配,则会进行最终的语义扫描,以确保所有与快照相关的对象元数据一致。错误将在日志中报告。

使用上述命令格式启动的擦洗被视为高优先级,并立即执行。此类擦洗不受适用于常规定期擦洗的任何星期几或时间限制的约束。它们不受“osd_max_scrubs”的限制,也不需要等待其副本的擦洗资源。

存在第二种命令格式,用于启动擦洗,就像它是常规擦洗一样。此命令格式如下所示

ceph tell {pg-id} schedule-scrub

ceph tell {pg-id} schedule-deep-scrub

要擦洗特定池中的所有 PG,请运行以下形式的命令

ceph osd pool scrub {pool-name}

优先回填/恢复 PG

您可能会遇到需要恢复或回填多个 PG 的情况,但某些 PG 中的数据比其他 PG 中的数据更重要(例如,某些 PG 包含正在运行的机器使用的镜像数据,而其他 PG 用于不活动的机器并包含不那么相关的数据)。在这种情况下,您可能希望优先恢复或回填具有特别重要数据的 PG,以便更快地恢复集群性能和数据可用性。要将特定 PG 指定为恢复期间的优先事项,请运行以下形式的命令

ceph pg force-recovery {pg-id} [{pg-id #2}] [{pg-id #3} ...]

要在回填期间将特定 PG 标记为优先,请运行以下形式的命令

ceph pg force-backfill {pg-id} [{pg-id #2}] [{pg-id #3} ...]

这些命令指示 Ceph 在处理其他 PG 之前对指定的 PG 执行恢复或回填。优先级不会中断当前的回填或恢复,但会将指定的 PG 放在队列顶部,以便接下来对其进行操作。如果您改变主意或意识到您优先考虑了错误的 PG,请运行以下一个或两个命令

ceph pg cancel-force-recovery {pg-id} [{pg-id #2}] [{pg-id #3} ...]
ceph pg cancel-force-backfill {pg-id} [{pg-id #2}] [{pg-id #3} ...]

这些命令会从指定的 PG 中移除 force 标志,以便 PG 将按其常规顺序处理。与添加 force 标志的情况一样,这只会影响仍在队列中的 PG,而不会影响当前正在恢复的 PG。

PG 恢复或回填完成后,force 标志会自动清除。

同样,要指示 Ceph 优先处理指定池中的所有 PG(即,首先对这些 PG 执行恢复或回填),请运行以下一个或两个命令

ceph osd pool force-recovery {pool-name}
ceph osd pool force-backfill {pool-name}

这些命令也可以取消。要恢复为默认顺序,请运行以下一个或两个命令

ceph osd pool cancel-force-recovery {pool-name}
ceph osd pool cancel-force-backfill {pool-name}

警告

这些命令可能会破坏 Ceph 内部优先级计算的顺序,因此请谨慎使用!如果您有多个池当前共享相同的底层 OSD,并且某些池中的数据比其他池中的数据更重要,那么我们建议您运行以下形式的命令来安排所有池的自定义恢复/回填优先级

ceph osd pool set {pool-name} recovery_priority {value}

例如,如果您有二十个池,您可以将最重要的池优先级设置为 20,将次重要的池优先级设置为 19,依此类推。

另一种选择是仅为池的适当子集设置恢复/回填优先级。在这种情况下,三个重要的池可能(全部)被分配优先级 1,而所有其他池将保持未分配恢复/回填优先级。另一种可能性是选择三个重要的池并将它们的恢复/回填优先级分别设置为 321

重要

使用 ceph osd pool set {pool-name} recovery_priority {value} 设置恢复/回填优先级时,值越大的数字具有越高的优先级。例如,恢复/回填优先级为 30 的池比恢复/回填优先级为 15 的池具有更高的优先级。

恢复丢失的 RADOS 对象

如果集群丢失了一个或多个 RADOS 对象,并且您已决定放弃寻找丢失的数据,则必须将未找到的对象标记为 lost

如果已查询所有可能的位置,并且所有 OSD 都处于 upin 状态,但某些 RADOS 对象仍然丢失,您可能不得不放弃这些对象。当罕见且不寻常的故障组合允许集群了解在写入本身恢复之前执行的写入时,可能会发生这种情况。

用于将 RADOS 对象标记为 lost 的命令只有一个受支持的选项:revertrevert 选项将回滚到 RADOS 对象的先前版本(如果它足够旧以具有先前版本)或完全忘记它(如果它太新而没有先前版本)。要将“unfound”对象标记为 lost,请运行以下形式的命令

ceph pg {pg-id} mark_unfound_lost revert|delete

重要

请谨慎使用此功能。它可能会使期望对象存在的应用程序感到困惑。

由 Ceph 基金会为您呈现

Ceph 文档是由非营利性 Ceph 基金会 资助和托管的社区资源。如果您希望支持这项工作和我们的其他努力,请考虑 立即加入