Ceph 每个 osd 的 pg 太多:所有你需要知道的

Ceph too many pgs per osd: all you need to know

我同时收到 两个 这些错误。我无法减少 pg 计数,也无法添加更多存储空间。

这是一个新集群,当我向其上传大约 40GB 时收到这些警告。我猜是因为 radosgw 创建了一堆池。

ceph 为什么每个 osd 有太多的 pg,但每个 pg 的对象比平均值多,而 pgs 建议太少?

HEALTH_WARN too many PGs per OSD (352 > max 300); 
pool default.rgw.buckets.data has many more objects per pg than average (too few pgs?)

osds: 4 (2 per site 500GB per osd)
size: 2 (cross site replication)
pg:  64
pgp: 64
pools: 11

使用 rbd 和 radosgw,没什么特别的。

我将回答我自己的问题,希望它能阐明这个问题或对 ceph 内部结构的类似误解。

一劳永逸地修复 HEALTH_WARN 每个 OSD 过多的 PG(352 > 最大 300)

平衡 归置组时,您必须考虑:

我们需要的数据

  • pgs/osd
  • 每个池 pgs
  • 每个 osd 池
  • 美眉图
  • 合理的默认 pg 和 pgp num
  • 副本数

我将使用我的设置作为示例,您应该能够将其用作您自己的模板。

我们有数据

  • OSDS 数量:4
  • 网站数量:2
  • 每个 OSD 的 pgs:???
  • 每个池的 pgs:???
  • 每个 OSD 池:10
  • 合理的默认 pg 和 pgp num:64(...或者是?)
  • 副本数:2(跨站点复制)
  • 美眉图

ID WEIGHT TYPE NAME UP/DOWN REWEIGHT PRIMARY-AFFINITY root ourcompnay site a rack a-esx.0 host prdceph-strg01 osd.0 up 1.00000 1.00000 osd.1 up 1.00000 1.00000 site b rack a-esx.0 host prdceph-strg02 osd.2 up 1.00000 1.00000 osd.3 up 1.00000 1.00000

我们的目标是用 HEALTH OK 集群所需的内容填充上面的 '???'。我们的池由 rados 网关在初始化时创建。 我们有一个 default.rgw.buckets.data 存储所有数据的存储池,其余池是 cephs 元数据和簿记的管理和内部。

每个 osd 的 PG(什么是合理的默认值???)

文档会让我们使用此计算来确定每个 osd 的 pg 计数:

 (osd * 100)
----------- = pgs UP to nearest power of 2
 replica count

据说向上舍入是最优的。因此,根据我们当前的设置,它将是:

 (4 * 100)
----------- = (200 to the nearest power of 2) 256
    2
  • osd.1 ~= 256
  • osd.2 ~= 256
  • osd.3 ~= 256
  • osd.4 ~= 256

这是建议的 max 每个 osd 的 pg 数量。那么...你目前实际拥有什么?为什么它不起作用?如果你设置一个 'reasonable default' 并理解上面的内容为什么行不通!!! >=[

可能,几个原因。我们必须理解上面那些 'reasonable defaults' 的实际含义,ceph 如何应用它们以及应用到哪里。上面的内容可能会误解我可以像这样创建一个新池:

ceph osd pool create <pool> 256 256

或者我什至认为我可以谨慎行事并遵循说明 (128 pgs for < 5 osds) 可以使用的文档:

ceph osd pool create <pool> 128 128

这是错误的,直截了当。因为它无法解释 ceph 使用这些数字实际执行的操作之间的关系或平衡 从技术上讲,正确答案是:

ceph osd pool create <pool> 32 32

让我解释一下原因:

如果像我一样,当您尝试使用 rados 做任何事情时,您就使用 'reasonable defaults' (128 pgs for < 5 osds) 配置了您的集群,它会创建一大堆池,并且您的集群会崩溃。 原因是我误解了上面所说的一切之间的关系。

  • 池:10(由 rados 创建)
  • 每个池的 pgs:128(在文档中推荐)
  • osds:4(每个站点 2 个)

10 * 128 / 4 = 320 pgs per osd

~320 可能是我集群上每个 osd 的 pg 数量。但是 ceph 可能会以不同的方式分发这些。这正是正在发生的事情 远远超过上述每个 osd 的 256 最大值。我集群的 HEALTH WARNHEALTH_WARN too many PGs per OSD (368 > max 300).

使用this命令我们可以更好地看到数字之间的关系:

pool :17 18  19  20  21  22  14  23  15  24  16 | SUM
------------------------------------------------< - *total pgs per osd*
osd.0 35 36  35  29  31  27  30  36  32  27  28 | 361
osd.1 29 28  29  35  33  37  34  28  32  37  36 | 375
osd.2 27 33  31  27  33  35  35  34  36  32  36 | 376
osd.3 37 31  33  37  31  29  29  30  28  32  28 | 360
-------------------------------------------------< - *total pgs per pool*
SUM :128 128 128 128 128 128 128 128 128 128 128

您拥有的池数量与分配给它们的归置组数量之间存在直接相关性。 我在上面的代码片段中有 11 个池,每个池有 128 pg,这太多了!!我合理的默认值是 64!那到底发生了什么??

我误解了 'reasonable defaults' 的用法。当我将默认值设置为 64 时,您可以看到 ceph 已将我的 crush map 考虑在内 我在站点 a 和站点 b 之间有一个 故障域 。 Ceph 必须确保站点 a 上的所有内容至少可以在站点 b 上访问。

错误

site a
osd.0
osd.1 TOTAL of ~ 64pgs

site b
osd.2 
osd.3 TOTAL of ~ 64pgs

我们需要 总计 64 pgs 每个池 所以我们合理的默认值实际上应该从一开始就设置为 32 !

如果我们使用 ceph osd pool create <pool> 32 32 这相当于我们的 pgs per poolpgs per osd 之间的关系那些 'reasonable defaults' 和我们推荐的 max pgs per osd 开始变得有意义:


所以你的集群坏了^_^

别担心,我们会修复它。恐怕这里的程序在风险和时间上可能会有所不同,具体取决于您的集群有多大。但唯一的办法 解决这个问题的方法是添加更多存储空间,以便归置组可以在更大的表面积上重新分布。或者我们必须把所有东西都移到 新创建的池。

我将展示移动 default.rgw.buckets.data 池的示例:

old_pool=default.rgw.buckets.data
new_pool=new.default.rgw.buckets.data

使用正确的 pg 计数创建一个新池:

ceph osd pool create $new_pool 32

将旧池中的内容复制到新池中:

rados cppool $old_pool $new_pool

删除旧池:

ceph osd pool delete $old_pool $old_pool --yes-i-really-really-mean-it

将新池重命名为 'default.rgw.buckets.data'

ceph osd pool rename $new_pool $old_pool

现在重启 radosgws 可能是一个安全的选择。

终于更正了

site a
osd.0
osd.1 TOTAL of ~ 32pgs

site b
osd.2 
osd.3 TOTAL of ~ 32pgs

如您所见,我的池编号增加了,因为它们是按池 ID 添加的,并且是新副本。我们每个 osd 的 pg 总数低于 ~256,这为我们提供了在需要时添加自定义池的空间。

pool :  26 35 27 36 28 29 30 31 32 33 34 | SUM
-----------------------------------------------
osd.0   15 18 16 17 17 15 15 15 16 13 16 | 173
osd.1   17 14 16 15 15 17 17 17 16 19 16 | 179
osd.2   17 14 16 18 12 17 18 14 16 14 13 | 169
osd.3   15 18 16 14 20 15 14 18 16 18 19 | 183
-----------------------------------------------
SUM :   64 64 64 64 64 64 64 64 64 64 64 

现在您应该使用您可以使用的任何东西来测试您的 ceph 集群。就我个人而言,我在 boto 上写了一堆 python 来测试基础设施和 return 桶统计数据和元数据相当快。他们向我保证,集群已恢复正常工作,不会出现之前遇到的任何问题。祝你好运!


修复池 default.rgw.buckets.data 每个 pg 的对象数比平均值多很多(pgs 太少?)一劳永逸

字面上的意思是,您需要增加池的 pg 和 pgp 数量。所以……去做吧。考虑到上述所有内容。但是,当您执行此操作时,请注意集群将启动 backfilling,您可以在另一个终端 window 或屏幕上观看此过程 %: watch ceph -s

ceph osd pool set default.rgw.buckets.data pg_num 128
ceph osd pool set default.rgw.buckets.data pgp_num 128

有了上段提供的系统知识和信心,我们可以清楚地了解这种变化对集群的关系和影响。

pool :  35 26 27 36 28 29 30 31 32 33 34 | SUM
----------------------------------------------
osd.0   18 64 16 17 17 15 15 15 16 13 16 | 222
osd.1   14 64 16 15 15 17 17 17 16 19 16 | 226
osd.2   14 66 16 18 12 17 18 14 16 14 13 | 218
osd.3   18 62 16 14 20 15 14 18 16 18 19 | 230
-----------------------------------------------
SUM :   64 256 64 64 64 64 64 64 64 64 64 

你能猜出哪个池 ID 是 default.rgw.buckets.data 吗?哈哈^_^

在 Ceph Nautilus(v14 或更高版本)中,您可以开启 "PG Autotuning"。有关详细信息,请参阅 this documentation and this blog entry

我不小心创建了包含实时数据的池,我无法迁移这些数据来修复 PG。好几天才恢复过来,PG调到最佳,零问题