共计 1183 个字符,预计需要花费 3 分钟才能阅读完成。
这篇文章将为大家详细讲解有关错误状况下怎么保证 ceph IO 的一致性,丸趣 TV 小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。
最近研究了在出现错误的状况下,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 的一致性”这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。