错误状况下怎么保证ceph IO的一致性
更新:HHH   时间:2023-1-7


这篇文章将为大家详细讲解有关错误状况下怎么保证ceph IO的一致性,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

最近研究了在出现错误的状况下,ceph IO 的一致性如何保证。代码基于hammer0.94.5版本。 构建一个集群,包括三个OSD, osd.0 osd.1 osd.2。

从客户端发送IO写操作A,osd.0 是primary, osd1/2是replica. 假设osd.2此时由于网络或者硬盘故障,或者软件bug挂了。 此时osd0 自己完成了本地写,收到了osd.1的副本写ack,还在等待osd.2的副本写ack. 在最长等待osd_heartbeat_grace,默认是20秒后,利用心跳机制,会向monitor汇报此osd挂掉。此时集群会进入peering,在peering的时候,受影响的pg,io 会被block住。这个时候详细来看作为primay的osd.0 如何处理写操作A。 在peering之前, osd0 会调用void ReplicatedPG::on_change(), 进一步调用apply_and_flush_repops()

apply_and_flush_repops()会将操作A requeue到op_wq里去。

等待pg peering完成后,A操作的对象所属的pg变成active状态, IO继续, do_op会继续处理IO队列,包括requeue的A操作。

do_op 会查询pglog,发现A操作其实已经落盘,是个dup的操作,可直接返回client.

对于两个osd ,如osd.1/osd.2都挂的情况,primary还是会requeue A操作,但假如pg min_size是2, 这个时候由于只有primay osd在线,小于min_size。

所以等peering完成,IO也会被block住,等待数据恢复至min_size以上,IO 才会继续。

同样的,如果挂的是primary osd.0, 分两种情况,一种是osd.0先挂,然后client 发送A操作,client端会等一会儿,等到peering完成,client拿到更新的osdmap后,重发请求,纳闷剩下的IO处理跟正常情况一样了。

第二种是client 已经将请求发送到primary osd.0, osd.0也把副本写操作发送到了osd.1 和osd.2上,然后osd.0挂了。 同样等到心跳检测到osd.0挂的情况,然后peering. osd.1也会有equeue的动作,等待peering完成后,假设osd.1变成了primary, 那接下来的逻辑跟之前primary osd.0的动作一样了。

关于“错误状况下怎么保证ceph IO的一致性”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

返回云计算教程...