当前位置: 代码迷 >> 综合 >> Ceph N的新功能:PG合并和自动调整
  详细解决方案

Ceph N的新功能:PG合并和自动调整

热度:70   发布时间:2023-12-08 12:07:21.0

从一开始,在Ceph中选择和调整PG数量一直是管理Ceph集群中最令人沮丧的部分之一。 选择适当资源池的指南令人困惑,来源之间不一致,并且经常被警告和例外所包围。 最重要的是,如果选择了错误的值,獭并不总是可以进行纠正,并且性能和/或稳定性会受到影响。 Nautilus之前的Ceph版本中的关键限制是,如果pg_num值太小,则总是可以增加它,但是如果它太高,则不能减小它。

不再!。在Nautilus中,池的pg_num值可以降低。更重要的是,可以启用pg autotuner,该组件允许系统自动进行任何适当的调整,以便用户可以完全忽略pg_num调整的前期技巧。

PG是什么?

RADOS(Ceph的底层存储层)中存储的数据对象被分组到逻辑池中。 池具有复制因子,纠删码方案之类的属性,并且可能具有仅将数据放置在HDD或SSD上的规则。 在内部,根据存储在池中对象名称的哈希值将池分为pg_num placement groups或PG。 因此,每个placement group都是整个池的伪随机slice(切片),shard(分段)或fragment (片段),并且特定PG中的所有对象都被分组并一起存储在同一组存储设备(OSD)上。

对象很少的小池只需要几个PG。大型池(例如,包含集群中存储的大部分数据的池)需要大量PG,以确保数据分布在多个设备上,从而平衡所有OSD上的空间利用率,并在系统负载时提供良好的并行性。
PG太少会对少数存储设备的性能造成瓶颈,而PG过多会使Cave的行为效率低下-在极端情况下甚至不稳定-这是因为管理每个PG需要进行内部跟踪。

标准的经验法则是,我们希望每个OSD大约有100个PG,但要计算出系统中每个池的PG数量-同时考虑复制和纠删码等因素-可能是一项挑战。

PG分裂和合并

自2012年以来,Ceph就一直支持PG“分裂”,使现有PG可以将其内容“拆分”为许多较小的PG,从而增加了池中PG的总数。 这使集群开始时很小,然后随时间增长而扩展。 从Nautilus开始,我们现在还可以将两个现有PG“合并”到一个更大的PG中,从而减少PG的总数。 如果池中的相对数据量随着时间的推移而减少,从而需要或适当地减少了PG,或者整个集群都缩小了,或者所选的PG的初始数量太大,则这很有用。

传统上,当PG数量增加时,PG分裂是一气呵成的。例如,要将池的pg_num值从16调整为64,只需

$ ceph osd pool set foo pg_num 64

集群将16个PG中的每个PG一次性分割成4个片段。 以前,还需要第二步来调整这些新PG的位置,以便将它们存储在新设备上:

$ ceph osd pool set foo pgp_num 64

这是移动实际数据的开销最大的部分。从Nautilus开始,第二步不再是必需的:只要pgp_num和pg_num当前匹配,pgp_num就会自动跟踪任何pg_num更改。更重要的是,根据新的target_max_misplace_rate配置选项(默认为0.05或5%),逐步调整pgp_num以迁移数据并(最终)收敛到pg_num,以限制系统上的数据迁移负载。也就是说,默认情况下,Ceph会尝试让不超过5%的数据处于“错位”状态,并排队等待迁移,从而限制对客户端工作负载的影响。

PG合并的工作方式与分裂类似,不同之处在于内部pg_num值总是每次一次减少一个PG。 合并是一个更为复杂和精细的过程,需要将PG的IO暂停几秒钟,并且一次合并一个PG可使系统将影响最小化并简化整个过程。 当使用以下命令减少foo池的pg_num时,将设置一个内部pg_num_target值,该值指示pg_num的所需值,并且集群会慢慢收敛于该值。 例如,要将pool foo的PG从64降低到4,

$ ceph osd pool set foo pg_num 4
$ ceph osd pool ls detail | grep foo
pool 1 'foo' replicated size 3 min_size 2 crush_rule 0 object_hash rjenkins pg_num 63 pgp_num 62 pg_num_target 4 pgp_num_target 4 autoscale_mode warn last_change 391 lfor 0/391/389 flags hashpspool stripe_width 0

PG auto-scaler

调整pg_num值的能力是向前迈出的关键一步,但它并未解决PG调整问题,对于大多数用户而言,这似乎是不可思议的事情。 Nautilus包括一个称为pg_autoscaler的新管理器模块,该模块允许集群考虑每个池中实际存储(或预期要存储)的数据量,并自动选择适当的pg_num值。

由于为pg_autoscaler是新的,因此需要在Nautilus中显式启用它:

$ ceph mgr module enable pg_autoscaler

autoscaler是按每个池配置的,可以在以下几种模式下运行:

  • 警告(warn) 模式:如果建议的pg_num值与当前值相差太大,则会发出健康警告。 这是新池和现有池的默认设置。
  • 启用(on) 模式:无需任何管理员交互即可自动调整池pg_num。
  • 禁用(off) 模式:还可以为任何给定池关闭autoscaler,让管理员像以前一样手动管理pg_num。

要为特定池启用autoscale,

$ ceph osd pool set foo pg_autoscale_mode on

启用后,可以通过CLI查询所有池的当前状态和建议的调整。 例如,在我们的实验集群上,我们有:

$ ceph osd pool autoscale-statusPOOL                          SIZE  TARGET SIZE  RATE  RAW CAPACITY   RATIO  TARGET RATIO  PG_NUM  NEW PG_NUM  AUTOSCALE device_health_metrics       18331k                3.0        431.3T  0.0000                     1              warn      default.rgw.buckets.non-ec      0                 3.0        431.3T  0.0000                     8              warn      default.rgw.meta             2410                 3.0        431.3T  0.0000                     8              warn      default.rgw.buckets.index   38637k                3.0        431.3T  0.0000                     8              warn      default.rgw.control             0                 3.0        431.3T  0.0000                     8              warn      default.rgw.buckets.data    743.5G                3.0        431.3T  0.0050                    32              on        .rgw.root                    1113                 3.0        431.3T  0.0000                     8              warn      djf_tmp                      1169G                3.0        431.3T  0.0079                  4096          32  off       libvirt-pool                 2048M                3.0        431.3T  0.0000                  3000           4  off       data                        66692G                3.0        431.3T  0.4529                  4096              warn      default.rgw.log              8146k                3.0        431.3T  0.0000                     8              warn      metadata                    54050M                4.0        431.3T  0.0005       

您会注意到,大部分数据位于存储所有QA结果的CephFS的“元数据”和“数据”池中。大多数其他池是各种测试遗留下来的,(大部分)是空的。

让我们看一下每一列:

  • SIZE列仅报告存储在池中的数据总量(以字节为单位)。 这包括对象数据和omap键/值数据。
  • TARGET SIZE报告有关池的预期大小的任何管理员输入。如果池刚刚创建,则最初不会存储任何数据,但管理员通常对最终将存储多少数据有所了解。如果提供,则使用此值或实际大小中的较大者来计算池的理想PG数。
  • RATE值是原始存储占用与存储的用户数据的比率,对于复本桶(bucket)来说,它只是一个复制因子,对于纠删码池来说,它是一个(通常)较小的比率。
  • RAW CAPACITY是池由CRUSH映射到的存储设备上的原始存储容量。
  • RATIO是池占用的总存储空间的比率。
  • TARGET RATIO是管理员提供的值,类似于TARGET SIZE,它表示用户预计池将占用集群总存储的多大部分。
  • 最后,PG_NUM是池的当前PG数量,而NEW PG_NUM(如果存在)是建议值。
  • AUTOSCALE列指示池的模式,可以是禁用、警告或启用。

建议的值考虑了几个输入,包括池占用(或预期占用)的整体群集的比例、池分布在哪些OSD上,以及每个OSD的目标PG数(由mon_target_pg_per_osd配置选项定义,默认为100)。autoscaler将始终选择一个2的幂的pg_num值,因为这对于Ceph而言效率更高(这意味着同一池中的所有PG的大小都大致相同),并且只有当建议的值大于实际值的三倍时,autoscaler才会建议更改pg_num。这意味着,在大多数情况下,不断增长的池的pg_num值在每次更改时都会跃升4倍,并且除非其大小有非常显著的变化,否则将倾向于保持相同的值。

首次设置集群时,通常设置池的target ratio很有帮助,以便autoscaler可以做出良好的初始决策。 例如,如果集群的主要用途是用于块存储,则可以将rbd池的target ratio设置为.8并启用PG auto-scaling:

$ ceph osd pool create foo 1
$ rbd pool init foo
$ ceph osd pool set foo target_size_ratio .8
$ ceph osd pool set foo pg_autoscale_mode on

此时,集群将自行选择一个pg_num并将其应用于后台。

您可以使用以下命令控制将pg_autoscale_mode用于新创建的池

$ ceph config set global osd_pool_default_autoscale_mode <mode> 

我可以完全放手吗?

是。如果您为新池启用自动扩展,并在现有池上启用它,则随着数据存储在集群中,系统将向上扩展PG。

这种方法的唯一问题是在存储数据后调整PG计数会在集群中移动数据,这很昂贵。 根据经验,如果创建了一个空池,然后将其填充以占用集群的所有可用空间,那么写入的所有数据将在写入后大约移动一次。 这不是理想的选择-最好在创建池时提供target ratiotarget bytes值,以便选择适当的初始PG计数-但无知的开销至少是有限且合理的。