2.3.2 PG 的状态机
PG状态的迁移通过状态机来驱动,我们先看一下PG状态机的主要事件定义,见表2-2。
需要注意的是,这些状态并不是互斥的,某些时刻 PG 可能处于多个状态的叠加中,例如 Active + Clean 表示一切正常,Active + Degraded + Recovering 表明 PG 存在降级对象并且正在执行修复等。集群拓扑或者状态的变化,例如 OSD 加入和删除、OSD 宕掉或恢复、存储池创建和删除等,最终都会转化为状态机中的事件,这些事件会驱动状态机在不同状态之间进行跳转。
以下几个状态在集群日常运行及运维中较为常见,简要介绍一下。
◆ Peering
Peering 指的是 PG 包含的冗余组中的所有对象达到一致性的过程,Peering 时间的长短并不可控,主要是在于请求的 OSD 是否能够及时响应;如果这个阶段某个 OSD 宕掉,很可能导致部分 PG 一直处在 Peering 状态,即所有分布到这个 PG 上的 I/O 都会阻塞。
◆ Degraded
降级状态,如在副本模式下(size 参数配置为 3),每个 PG 有 3 个副本,分别保存在不同的 OSD 守护进程中。在非故障情况下,这个 PG 是 Active+clean 状态,一旦出现OSD 守护进程离线,PG 的副本数就会小于 3,PG 就转变为了 Degraded 降级状态。
◆ Peered
Peering 已经完成,PG 等待其他副本(OSD 守护进程)上线状态,此状态下 PG 不可对外提供服务。
结合上述 Degraded 状态,PG 当前存活副本数大于或等于存储池规定的最小副本数(min_size, 通 常 设 置 为 2),PG 为 Active+Undersized+Degraded 状 态, 仍 可 对 外提供 I/O 服务;PG 当前存活副本数小于存储池规定的最小副本数(min_size),PG 为Undersized+Degraded+Peered 状态,不可对外提供 I/O 服务。
◆ Remapped
Peering 已经完成,PG 当前的 Acting Set 与 Up Set 不一致就会出现 Remapped 状态,此状态下的 PG 正在进行数据的自我修复。该状态下,PG 可以进行正常的 I/O 读写。
上述讨论 Peered 状态时,如果 PG 内的另外两个 OSD 守护进程对应的存储介质损坏,将其移出存储集群后,Ceph 会将 PG 内的数据从仅存的 OSD 上向集群内其他的 OSD 进行迁移(PG 的重映射),丢失的数据是要从仅存的 OSD 上回填到新的 OSD 上的,处于回填状态的 PG 就会被标记为 Backfilling。
◆ Recovery
Ceph 基于 PG 级别的日志保证副本之间的数据一致性,Recovery 指对应副本能够通过日志(PGLog1)进行恢复,即只需要修复该副本上与权威日志不同步的那部分对象,即可完成存储系统内数据的整体恢复。
Recovery 有两种恢复方式。
(1)
Pull :指 Primary 自身存在降级的对象,由 Primary 按照 missing_loc 选择合适的副本去拉取降级对象的权威日志到本地,然后完成修复。
(2)
Push :指 Primary 感知到一个或者多个副本当前存在降级对象,主动推送每个降级对象的权威版本至相应的副本,然后再由副本本地完成修复。
为了修复副本,Primary 必须先完成自我修复,即通常情况下,总是先执行 Pull 操作,再执行 Push 的操作(但是如果客户端正好需要改写某个只在从副本上处于降级状态的对象,那么此时 PG 会强制通过 Push 的方式优先修复对象,以避免长时间阻塞客户端的相关请求)。另一个必须这样处理的原因在于,客户端的请求,都是由 Primary 统一处理的,为了及时响应客户端的请求,也必须优先恢复 Primary 的本地数据。完成自我修复后,Primary 可以着手修复各个副本中的降级对象。因为在此前的 Peering 过程中,Primary 已经为每个副本生成了完整的 missing 列表,可以据此逐个副本完成修复。
客户端发起读请求,待访问的对象在一个或者多个副本上处于降级状态,对应的读请求可以直接在 Primary 上完成,对象仅仅在副本上降级,无任何影响。如果 Primary 上也处于降级状态,需要等 Primary 完成修复,才能继续。
1 记录的 PGLog 在 osd_max_pg_log_entries=10000 条以内,这个时候通过 PGLog 就能增量恢复数据。
客户端发起写请求,待访问的对象在一个或者多个副本上处于降级状态,必须修复该对象上所有的降级副本之后才能继续处理写请求。最坏情况,需要进行两次修复才能完成写请求(先修复 Primary,再由 Primary 修复其他降级副本)。
◆ Backfill
结合上述 Recovery 分析,Ceph 通常基于 PG 级别的日志(PGLog)保证副本之间的数据一致性。Backfill 指副本已经无法通过 PGLog 进行恢复,需要进行全量数据同步,即以 PG 为目标进行整体的数据迁移的过程。
因此,PG 的 Backfill 过程比 Recovery 过程时间要长。
◆ Stale
Monitor 服务检测到当前 PG 的 Primary OSD 离线,则 PG 处于 Stale 状态。Ceph 存储系统会自动选取 Up Set 中的第一个 OSD 作为 Primary OSD,由此,若一个 PG 长期处于 stale 状态,表征了它的所有副本所在的 OSD 守护进程均出现了问题。
结合上文 Degraded 及 Peered 状态描述,三副本场景下,PG 丢失三副本后,状态为Stale+Undersized+Degraded+Peered,该状态下的 PG 不能对外提供 I/O 服务。部分故障场景,如网络阻塞或者网络亚健康情况下,Primary OSD 超时未向 Monitor进程上报 PG 相关的信息,PG 也会出现 stale 状态,故障消除后,PG 状态会恢复正常。
◆ Inconsistent
PG 通过 OSD 守护进程发起的数据检查(Scrub)、深度数据检查(Deep Scrub)检测到某个或者某些对象在 PG 间出现了不一致,则 PG 处于 inconsistent 状态。这种不一致可能为数据单副本之内与其自身元数据不一致(如数据真实长度与元数据记录信息不同),也可能为数据副本之间不一致(不同副本之间保存的数据内容不同)。数据不一致可以通过数据清洗命令进行修复。副本模式下,数据清洗命令只能手工触发;纠删码模式下,数据清洗命令可以配置为自动触发。数据清洗命令执行后,Ceph 会从其他的副本中将丢失的文件复制过来进行修复数据,修复的过程中,PG 的状态变化为 inconsistent → recover → clean,最终恢复正常。
◆ Down
当前剩余在线的 OSD 守护进程中的数据不足以完成 PG 数据修复,例如 PG 内某个OSD 离线,新数据写入了剩余的两个 OSD 中,随后剩余的两个 OSD 离线,最早离线的OSD 启动,这时,PG 内没有数据能够支撑这个 OSD 进行数据恢复,客户端 I/O 会夯住,只能通过拉起后两个 OSD 守护进程才能修复该问题。
2.4 小结
本章从分布式存储系统的数据寻址方案变迁角度切入,对比了存储系统元数据查表型寻址方式与计算型寻址方式两种实现方案的优劣;随后,对 Ceph 分布式存储系统采用的寻址方案进行了详细介绍,通过对 Ceph 寻址流程、CRUSH 算法因子、Bucket 随机选择算法的介绍,为读者展示了 Ceph 存储系统架构的核心内容;最后,对于 CRUSH 算法中引入的 PG 概念,从日常集群运行、运维角度,介绍了 PG 常见的状态机及其表征的含义。