【Ceph RADOS】PG 与 Peering:PrimaryLogPG、PG log 与状态机

💡 原文中文,约12100字,阅读约需29分钟。
📝

内容提要

PG是Ceph中对象与OSD间的一致性调度单元,通过PG log记录写操作版本链,支持peering状态机重建权威视图。本文解析PG log格式、last_epoch_started与last_epoch_clean语义差异,及peering关键阶段,强调PG作为哈希桶而非目录,peering非选主,并讨论min_size权衡与peering雪崩等开放问题。

🔎

延伸解读

PG log 与 last_epoch_started 的语义陷阱

文章强调 info.last_epoch_started 是本地视角的激活边界,而 history.last_epoch_started 是全集群“已接受写”的下界,两者不可混用。排障时若发现某个 OSD 的 LES 特别大却仍 incomplete,需注意 find_best_info 对 incomplete peer 的 LES 有例外规则,不能简单认为“LES 大者权威”。理解这些差异有助于避免误判 peering 状态。

peering 不是选主,而是重建权威视图

peering 的核心是让 acting set 内所有 OSD 对“哪些对象需要恢复”达成一致,而非仅选出 Primary。通过 past intervals 和 up_thru 机制,系统能构造包含所有已确认写的权威历史,防止幽灵提交。理解这一点,才能明白为何 peering 卡住时写操作会阻塞,以及为何 ceph pg query 比 ceph -s 更能定位问题。

min_size 权衡与 peering 雪崩的运维启示

min_size 的选取是数据安全与可用性的权衡:size=3, min_size=2 允许一个副本缺失时继续写,但 degraded 期间再失效可能丢数据;严格 min_size 则可能阻塞写。大规模 OSD 故障时,peering 雪崩可能拖死前台,需通过 osd_max_backfills 和 mClock 参数缓解。生产环境应根据负载容忍度谨慎配置。

Q&A

Ceph中PG的作用是什么?为什么需要PG而不是直接以对象为一致性单元?

PG(Placement Group)是Ceph中对象与OSD之间的一致性调度单元,它作为一组对象的一致性管理单元,同一PG内的对象由同一组OSD(acting set)服务,并共享同一个PG log。如果直接以对象为一致性单元,peering和recovery需要在对象总数规模上协商,导致规模爆炸。PG将协商压缩到PG数量规模(通常每个OSD上100-250个PG),从而控制复杂度和恢复时间。

PG log是什么?它有哪些关键字段和不变量?

PG log记录了该PG上所有写操作的版本链,以pg_log_entry_t为单元,包含version(epoch+version)、prior_version、reverting_to、reqid、soid、op等字段。关键不变量包括:last_update(最新条目的version)、last_complete(所有acting set OSD都已应用的最新version,且last_complete <= last_update)、log_tail(保留的最老条目version)。当两个OSD的PG log都不包含某个对象的差异区间时,peering会退化为backfill。

info.last_epoch_started和history.last_epoch_started有什么区别?

info.last_epoch_started是每个OSD本地视角的激活epoch,记录本OSD在某个peering interval中已提交的写都已反映在本地info/log中,晚于该epoch的写不会出现。history.last_epoch_started是PG作为整体最近一次进入Active并接受写的下界,也是本地PG log里出现过写的激活epoch的上界。info.last_epoch_started是本地边界,history.last_epoch_started是全集群下界,两者不能混为一谈。

Ceph中peering的Golden Rule是什么?它如何保证数据一致性?

Peering的Golden Rule是:任何写在向客户端确认前必须提交到当时acting set全体。因此,只要能联系到自上次成功peering以来每个past interval acting set中的至少一名成员,就能构造包含一切已确认写的权威历史。这保证了peering过程中不会丢失已确认的写操作。

PG进入Active状态后,如果副本数低于min_size会发生什么?

当存活副本数低于min_size(默认常为size-1)时,PG不能进入可写Active状态,客户端写操作会被阻塞。PG可以处于Active+Degraded状态,此时能服务读写,但对象副本未齐,写仍按当前acting set复制并满足min_size,读默认由Primary服务。

peering状态机的主要阶段有哪些?每个阶段的作用是什么?

Peering状态机的主要阶段包括:Initial、Reset、Started、GetInfo、GetLog、GetMissing、WaitUpThru、Active。GetInfo阶段Primary用MQuery收集pg_info_t;GetLog/GetMissing阶段合并权威log,识别divergent条目和missing对象;WaitUpThru阶段Primary在OSDMap中登记up_thru,证明存活并完成peering;Active阶段更新last_epoch_started并开始接受写。

ceph pg query命令在排障中有什么价值?

ceph pg query <pgid>命令可以打印PG的详细状态,包括acting set、up set、missing对象列表、当前状态机状态、last_epoch_started、last_epoch_clean以及peering历史。在peering卡住的排障场景中,这个命令的输出比ceph -s更有价值,因为它显示当前在哪个状态机节点,而ceph -s只显示聚合的PG状态计数。

关于peering速度与数据安全性,存在哪些权衡?

存在两种观点:A侧主张快速peering,容忍短暂degraded,通过增大pg_num、减少min_size或调大osd_recovery_sleep使系统尽快恢复可写,但若在degraded期间再有OSD失效可能丢数据;B侧主张严格min_size,宁可阻塞写直到副本足够,代价是故障期间写延迟大幅上升。生产中常见做法是size=3, min_size=2,并设置合适的osd_recovery_sleep。

🏷️

标签

➡️

继续阅读