关于ZooKeeper的两点思考

群首节点commit消息分两步:1. 发送proposal 2. 收到超半数ack再发送commit广播。

思考1: 场景如下,一个客户端依次执行了两条命令 W1 R1(使用异步),先写后读。是否存在这种情况:W1请求在上述的 proposal和ack未完成或者已完成但客户端连接的服务器未commit,此时读的可能仍然是老数据?

答:是的,ZooKeeper不能保证读的强一致性。

思考2:群首节点依次广播两条proposal P1 P2。假如跟随节点对这两个proposal皆ACK但是由于网络原因导致P2 先一步 到达群首(考虑极端情况,所有P1的ACK都晚到),那么是否使得ZooKeeper不能按照提交顺序P1->P2执行事务了呢?而会是P2->P1?

答:不能。

先看Follower 对proposal的处理 

FollowerZooKeeperServer

follower会使用阻塞队列依次存储P1->P2。

再来看群首收到P2的ACK消息处理方法。

Leader

1.先有一个zxid的校验,如果P2先到,不影响这个校验

2. 向follower发送commit消息

我们再回来看follower的commit方法

FollowerZooKeeperServer

这里会取出刚才阻塞队列中的第一个节点 即P1,commit的zxid属于P2,显然不一致,系统重启,重新同步数据。

但是再从群首对于ACK消息的处理方法看,因为

commit P2的时候

lastCommitted=P2.zxid了,所以会导致

P1消息的ACK被拒绝。

那么问题来了,这种情形是不是就表示P1被跳过了呢?

有请楼下大神解答。。。

 
 

猜你喜欢

转载自www.cnblogs.com/liuyuchong/p/10858931.html