错误的状况下,ceph IO 的一致性如何保证

来源:互联网 发布:兄弟连php强化就业 编辑:程序博客网 时间:2024/04/28 04:49

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

0 0
原创粉丝点击