关于pg恢复优先级的一些idea(记一次数据恢复)

20 篇文章 0 订阅
9 篇文章 0 订阅

概述

本文关于pg恢复场景下的一些想法、需求和可能得优化方向。

backfill

回顾backfill的逻辑

当Primary判断 ActingBackfill集合中,有副本需要通过backfill才能修复时,会向所有参与backfill的pg实例进行backfill的资源预留,当恢复线程不足,或者等待资源预留过程中,pg会进入backfill_wait状态。如果资源预留成功,可开始backfill也就是进入backfilling状态。如果一个backfill的pg实例,其所归属的osd空间不足,则会将当前backfill流程挂起,并释放之前申请预留的资源,同时pg进入backfill_toofull状态。primary会通过定时器中的回调函数,定期唤醒再次由primary发起资源预留申请,直到满足backfill所有条件。当pg backfill完成后,primary会发送backfilled事件,最终将状态机调整成active/clean状态,然后再删除这个pg不必要的副本。

简单来说,就是pg需要backfill,资源不够或者等待申请资源,进入backfill_wait状态,资源预留成功,osd空间足够,进入backfilling,空间不足,进入backfill_wait+toofull。主osd会定期进行重新申请,发现符合条件会再次backfill。backfill完成后,最终进入clean状态, 并回收不必要的空间

概念解释

这里重温一下之前提到的基础概念

  • osd_backfillfull_ratio:如上所说,osd进行pg backfill需要空间,为了避免osd直接full掉,一般先用此值限制osd 的pg backfill行为,避免osd空间达到full,造成集群error。
  • osd_full_ratio:允许单个osd所能达到的最高使用率,当达到这个值时,集群所有业务不可写入,变为只读。
  • osd_max_backfills:可以理解为上面所提到的资源,单个osd所允许同时执行 recovery或者backfill的pg个数,也就是常说的恢复线程数。
  • primary:pg主osd
  • temp pg:临时放置组,作为一个临时过渡状态,用户在数据迁移恢复过程中,存储对象和响应请求。数据恢复后,temp就会解散。
  • acting set:存有pg数据的当前osd的组合
  • up set:集群恢复完成时,预测承担pg数据的所有osd的组合。
  • min_size:pg响应io请求所需要的最小的存活副本数
  • 数据强一致性:作为商用存储,必须保持数据强一致性,也就是所有副本全部落下返回,写成功,才返回前端。(filesotre时代用ssd做journal加速,写日志即返回。bluestore用lvm裸盘和db、wal加速,避免双写和归并加速。这里能涉及细节太多了,鉴于没人想看,就不展开赘述了)

backfill过程中存在的问题

  • 恢复线程抢断,导致backfill thread 阻塞。
  • 无效迁移,部分场景remap会导致osd之间互迁
  • 临时pg占用大量额外空间和io
  • primary注册的回调函数唤醒队列,具有盲目性和随机性,导致无法优先恢复到我们想恢复的pg
  • 每个primary申请backfill时无法兼顾到全局使用率,导致在高容量集群中会出现卡在backfilltoofull

问题说明

关于pg backfill队列随机性、盲目性

为什么说pg backfill队列随机盲目问题很大。假如集群中有6个osd,以osd容灾的3副本 pool。

osd.0
osd.1
osd.2
osd.3
osd.4
osd.5

其中有三个以2为primary的pg,健康状况下,其up set 、acting set。如下

pg.idup setacting set
1.11c[2,0,1][2,0,1]
1.11d[2,3,5][2,3,5]
1.11f[2,4,5][2,4,5]

此时active+clean,up set和acting set一致。

假如此时发生硬件故障,osd.4和osd.5先后离线,那么基于原本离线的副本数不同,pg也会变成如下三种情况。

pg.idup setacting set状态
1.11c[2,0,1][2,0,1]不降级,但可能会remap,要进行backfill
1.11d[2,3,0][2,3]降级,active,仍存在两副本,要进行backfill
1.11f[2,1,3][2]降级为单副本,高危pg,期望最先进行backfill

此时1.11fpg显然危险级别最高,我们希望最优先让它进入backfilling状态。因为单副本,对ceph来说有致命的风险,无论是一致性还是安全性,都需要副本的支持。
然而如果此时由于remap,或者其余pg优先进入backfill状态抢占了恢复资源,1.11f则会长时间处于backfill_wait和单副本状态,无疑是存在丢数据风险。

优化方向:

  • 对恢复逻辑上来讲,应当让degarded pg的primary osd的申请,并优化pg wait队列,让降级pg处于最前端,优先恢复单副本pg
  • 从运维上来讲,有两种方法,第一种是调大资源,也就是放开backfill的线程,使用force backfill提高单个pg恢复的op优先级。第二种是使用upmap,先取消掉backfilling中的pg让其处于wait,待目标pg进入backfilling后,再upmap回来。

高容量backfill_full无法保证不突破osd_full_ratio

当集群使用率非常高时,我们非常担心osd容量会突然超出osd_full_ratio,从而导致pool full,业务error。因此我们往往会设置小一点的backfillfull参数,使pg不会因为在backfill过程中,超过osd full值。
例如:
osd_full_ratio 95%,osd_backfillfull_ratio 94%,预期是当pg backfill full达到94%时,不再进行任何backfill,更不会达到95%。

然而实际情况真的是这样么?

  • 业务写不可控,osd容量仍在上升
  • osdmap因为集群没有clean 保留过多版本epoch,并在逐渐累积
  • 在没有达到backfill_full之前申请了资源并进入backfilling状态,而单个pg过大,backfill完成前后,osd使用率上升较多。

也就是说即使设置了94%,osd仍有可能在backfill过程中,突破full的设定,从而使业务故障。

临时优化方向:
手动从高容量osd上upmap几个clean pg出去。

为什么要提前扩容

ceph利用率之所以一直给人感觉不高,正是为了满足存储一致性,安全性,健壮性等等,一个集群的最佳使用率可能只能达到物理容量的80%(集群避免full预留,和归并空洞的浪费,alloc size等等)。

假设我们等到集群所有osd使用率较高时,我们在进行扩容,我们期待的是,加入新osd时,旧osd的容量能立马下降。
然而

  • backfill要全量复制,pg active clean后,才会清除原pg上的数据,释放空间。
  • 为满足哈希,加入新节点后,不止是从老节点迁出pg到新节点,老节点之间的pg部分会remap。

比如osd.0 使用率最高,已达到94%,此时加入新osd扩容,可能osd.0上的pg会迁出40个,然后迁入10个。
我们当然希望的是优先先做迁出pg的backfilling,然后clean,尽快释放osd.0的空间,远离osd_full_ratio避免业务崩溃。
然而对别的primary 的osd,计算需要向osd.0迁移remap pg时,并不会关心osd.0是否有更优先级高的pg需要先迁出,直接进入backfilling,抢断了osd.0 迁出pg的机会。
也就是说,osd.0虽然因为扩容,整体负担的osd数量少了三十个,但短时间可能反而会先增加pg负担,使容量不会下降甚至还会上升、外加上条原因,会导致这种情况下集群的最高osd使用率更容易突破osd_full_ratio值。
所以,总之,要提前扩容,要给osd足够时间clean后释放,以及空间去做pg的remap。

  • 11
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值