Ceph存储系统使用的 CRUSH算法在一致性 Hash 算法的基础上充分考虑了多副本、故障域隔离等约束,尽量减少集群在故障场景下的数据迁移量,实现这一目标的关键举措 即为 PG逻辑概念的引入。
前文提到 Ceph可以理解为对 RADOS 对象存储系统的二次封装,Ceph中所有的用户数据都被抽象成多个Object,如果 Ceph存储系统以 Object 为追踪目标,那么要追踪的单元个体数量就太多了,不仅会消耗大量的计算资源,而且在一个有数以亿计对象(EB级存储集群)的系统中直接追踪对象的位置及其元数据信息也是完全不现实的。Ceph引进 PG逻辑概念,将一系列的Object聚合到 PG里,并将 PG 映射到一系列的OSD 上去。系统中PG数量远远小于 Object 数量,存储系统以PG 为存储单元个体,直接追踪PG 状态,比较好地处理了性能和可扩展性的界限。
PG的引入也会增加一些系统资源开销,如 PG 逻辑的处理会直接消耗存储节点的部分CPU和内存,增大 PG的数量会增加存储系统 Peering状态处理的数量。
2.3.1 PG数量的选择
上述分析可以看出,PG 是用户数据切片(Object)与真实提供存储空间的存储介质
(OSD守护进程)之间的纽带。Ceph存储系统需要设置较为合理的 PG数量,过少的PG数量会导致集群 peer过程太慢,数据迁移效率过低;过多的PG 数量则会增加集群存储节点的计算资源负担。PG的数量在 Ceph的存储池(Pool)创建时指定,通常推荐每个OSD守护进程承载 100个 PG较为合适,考虑到集群数据的副本策略,对于单存储池的简单场景,可以通过如下公式进行PG数量确定。
TotalPGs=(OSDs×100)/Replicas
在上述数据寻址计算中,可以看到要对Hash计算结果进行取模运算,存储池的 PG数量建议取值为 2的n次方,这样可以加速数据寻址的计算过程,即对上述公式计算结果,向上或向下靠近2的n次方数值进行存储池的PG总数选取。
对于多存储池的复杂场景,可以参考 Ceph官方推荐的计算器。
2.3.2 PG的状态机
PG状态的迁移通过状态机来驱动,我们先看一下PG状态机的主要事件定义,见表2-2。
表2-2 PG状态机
Activating |
Peering 已经完成,PG 正在等待所有 PG 实例同步并固化 Peering 的结果(Info、log等) |
Active |
活跃态。PG 可以正常处理来自客户端的读写请求 |
Backfilling |
正在后台填充态。Backfill是 Recovery的一种特殊场景,指 peering 完成后,如果基于当前权威日志无法对 UpSet 当中的某些 PG 实例实施增量同步(例如承载这些 PG 实例的 OSD 离线太久, 或者是新的 OSD 加入集群导致的 PG 实例整体迁移), 则通过完全复制当前Primary所有对象的方式进行全量同步 |
Backfill-toofull |
某个需要被 Backfill 的 PG实例,其所在的 OSD 可用空间不足,Backfill流程当前被挂起 |
Backfill-wait |
等待 Backfill 资源预留 |
Clean |
干净态。PG 当前不存在待修复的对象,Acting Set 和Up Set 内容一致,并且大小等于存储池的副本数 |
Creating |
PG 正在被创建 |
Deep |
PG 正在或者即将进行对象一致性扫描清洗 |
Degraded |
降级状态,Peering 完成后,PG 检测到任意一个PG实例存在不一致(需要被同步/修复)的对象,或者当前Acting Set 小于存储池副本数 |
Down |
Peering 过程中,PG 检测到某个不能被跳过的 Interval 中(例如该 Interval 期间,PG 完成了 Peering,并且成功切换至 Active 状态,从而有可能正常处理了来自客户端的读写请求),当前剩余在线的 OSD 不足以完成数据修复 |
Incomplete |
Peering 过程中,由于 a. 无法选出权威日志;b. 通过 choose_acting 选出的 ActingSet 后续不足以完成数据修复,导致 Peering 无法正常完成 |
Inconsistent |
不一致态,集群清理和深度清理后检测到PG 中的对象副本存在不一致,例如对象的文件大小不一致或Recovery结束后一个对象的副本丢失 |
Peered |
Peering 已经完成,但是 PG当前Acting Set规模小于存储池规定的最小副本数(min_size) |
Peering |
正在同步态。PG 正在执行同步处理 |
Recovering |
正在恢复态。集群正在执行迁移或同步对象和它们的副本 |
Recovering-wait |
等待Recovery资源预留 |
续表
Remapped |
重新映射态。PG 活动集任何的一个改变,数据发生从老活动集到新活动集的迁移。在迁移期间还是用老的活动集中的主OSD 处理客户端请求,一旦迁移完成,新活动集中的主 OSD开始处理 |
Repair |
PG 在执行Scrub 过程中,如果发现存在不一致的对象,并且能够修复,则自动进入修复状态 |
Scrubbing |
PG 正在或者即将进行对象一致性扫描 |
Inactive |
非活跃态。PG不能处理读写请求 |
Unclean |
非干净态。PG不能从上一个失败中恢复 |
Stale |
未刷新态。PG状态没有被任何 OSD 更新,这说明所有存储这个PG 的 OSD 可能挂掉,或者Mon没有检测到 Primary统计信息(网络抖动) |
Undersized |
PG 当前的ActingSet 小于存储池副本数 |
需要注意的是,这些状态并不是互斥的,某些时刻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当前的 ActingSet与 UpSet 不一致就会出现 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就能增量恢复数