我有一个使用ZooKeeper进行领导者选举的分布式应用程序。只有当选的领导者才能提交数据库。我最近发现,有一种潜在的情况可能导致多个领导者。当当选的领导人因长时间的GC而暂停时,就会出现这种情况,并且可能使ZooKeeper失去心跳,从而导致新领导人的选举。此时,两个节点都认为自己是领导者,并可能导致冲突。
对如何避免这种情况有何建议?
最佳答案
当您使用 ZooKeeper 进行领导者选举时,您无法保证领导者的唯一性。即使没有GC暂停,也有可能遇到这种情况。例如,当在网络分区过程中将领导者与ZooKeeper仲裁隔离时,或者当领导者发出长时间运行的查询时,死者和新领导者可以在当前 Activity 状态下发出新查询。
解决方法是在更新数据库时使用比较设置。选出新的领导者后,您应该获得增加的领导者ID(例如,通过更新ZooKeeper中的节点并使用其版本或mzxid),并使用它来保护该领导者发出的每笔交易。
例如,如果您想更改数据库的状态,则代替以下事务:
BEGIN TRANSACTION;
db.update($change);
END TRANSACTION;
你应该使用类似
BEGIN TRANSACTION;
if (db.leaderID <= $leaderID) {
db.leaderID = $leaderID;
db.update($change);
}
END TRANSACTION;
此技巧将保护您的系统免受并发领导者造成的不确定性的影响。当然,您的数据库应该是可线性化的,并支持比较设置。
关于java - Zookeeper多领导者选举问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/37478277/