概述
在某次故障回溯中,发现引发集群故障,slow io,pg stuck的罪魁祸首竟是做了一次ceph pg repair $pgid。然而ceph pg repair作为使用频率极高的,用来修复pg不一致的常用手段,平时可能很少注意其使用规范和可能带来的影响,更不会想到会引起业务阻塞。
产生原因
一般我们在集群中出现,active+inconsistent等状态的pg时,会想到用ceph pg repair方式根据pg log进行权威的pg 选择然后进行副本恢复。包括正常在社区搜索处理不一致,不完整的pg修复攻略,都会出现类似"先 repair试试看"等类似方法。然而作为在线业务的运维保障人员,我们需要知道一个操作的各个阶段的运行机制以及潜在风险。
当集群出现不一致时,往往pg是由deep-scrub与scrub扫描出来
deep-scrub
deep scrub本身是一种扫描检测机制,其过程会遍历目标osd上所有的object,并进行校验和匹配。因为ceph同时为了满足强一致性(所有副本写完再返回),又为了提高性能(写日志),因此可能会存在最终实际object出现写错和不一致的情况,这种情况下,deep scrub可以帮助发现潜在数据风险,提高数据可靠性。但其动作本身有会消耗大量的计算和io资源,会导致集群的性能大打折扣,在某些对性能有要求的集群中,会set nodeep-scrub flag(不关闭普通的scrub,也就是依然存在元数据校验,并不意味着关闭后集群数据没有任何校验,只是可靠性下降)。
ceph本身的op队列中,deep-scrub的op priority 只有5,即队列中,不会占据大量client op。
总得来说就是两点:1.开启deep-scrub会占用存储io,增加硬盘io压力,降低存储性能 2.ceph本身deep-scrub的op priority并不高。
ceph pg repair
查看ceph pg repair源码,其本质是,会对指定的pg先进行一次deep scrub,然而由ceph pg repair发起的deep scrub与ceph本身osd发起的deep-scrub并不同,其op priority会被设置成120,也就是说,在deep scrub本身影响集群性能的但没有引起阻塞的情况下,这次特殊的deep scrub很有可能会导致放大对集群性能,osd io的影响。
实际故障情况是,集群存在某个慢盘,写入时出现不一致,然后进行pg repair时,该硬盘直接利用率达到100%,延迟达到秒级,从而使该osd上的pg io全部阻塞卡死,最终引起业务故障。
规范
虽然pg repair有导致osd io阻塞的风险,但我们依然非常依赖其进行pg 不一致问题的修复,只要正确理解上述问题后,规范操作即可。即:
需要先用kvstore tool判断排除掉rocksdb问题,以及检查集群本身的慢盘,必须在将问题osd停止并out出集群后,再进行repair,而不是盲目直接进行repair。