选举算法入门

这一讲我们来聊聊如何在分布式数据库,乃至一般性的分布式系统内同步数据。

不知道你是否发现这样一种事实:同步数据是一种代价非常高昂的操作,如果同步过程中需要所有参与的节点互相进行操作,那么其通信开销会非常巨大

如下图所示,随着参与节点的增加,其通信成本逐步提高,最终一定会导致数据在集群内不一致。尤其在超大型和地理空间上分散的集群网络中,此现象会进一步被放大。
在这里插入图片描述
为了减少同步通信开销和参与节点的数量,一些算法引入了“领导者”(有时称为协调者),负责协调分布式系统内的数据同步。

领导选举

通常,分布式系统中所有节点都是平等的关系,任何节点都可以承担领导角色。节点一旦成为领导,一般在相当长的时间内会一直承担领导的角色,但这不是一个永久性的角色。原因也比较容易想到:节点会崩溃,从而不能履行领导职责。

现实生活中,如果你的领导由于个人变故无法履职,组织内会重新选择一个人来替代他。同样,在领导节点崩溃之后,任何其他节点都可以开始新一轮的选举。如果当选,就承担领导责任,并继续从前一个领导节点退出的位置开始工作。

领导节点起到协调整个集群的作用,其一般职责包括:

控制广播消息的总顺序;
收集并保存全局状态;
接收消息,并在节点之间传播和同步它们;
进行系统重置,一般是在发生故障后、初始化期间,或重要系统状态更新时操作。

集群并不会经常进行领导选举流程,一般会在如下两个场景中触发选举:

在初始化时触发选举,称为首次选举领导;
当前一位领导者崩溃或无法通信时。

选举算法中的关键属性

当集群进入选举流程后,其中的节点会应用选举算法来进行领导选举,而这些选举算法一般包含两个属性:“安全性”(Safety)和“活跃性”(Liveness)。它们是两个非常重要且比较基础的属性,最早由莱斯利·兰伯特( L.Lamport——分布式计算的开创者)提出。

在解释这两个属性的含义之前,我们先想象一下工作生活中是如何选举领导的?领导通常来源于一组候选人,选举规则需包含如下两点。

选举必须产生一个领导。如果有两个领导,那么下属应该听从他们中谁的指示呢?领导选举本来是解决协调问题的,而多个领导不仅没有解决这个问题,反而带来了更大问题。

选举必须有结果。较为理想的状态是:领导选举需要在大家可以接受的时间内有结果。如果领导长时间没有被选举出来,那么必然造成该组织无法开展正常的工作。因为没人来协调和安排工作,整个组织内部会变得混乱无序。

以上两个规则正好对应到算法的两个属性上。

其中第一个规则对应了算法的“安全性”(Safety),它保证一次最多只有一个领导者,同时完全消除“脑裂”(Split Brain)情况的可能性(集群被分成两个以上部分,并产生多个互相不知道对方存在的领导节点)。然而,在实践中,许多领导人选举算法违反了这个属性。下面在介绍“脑裂”的时候会详细讲解如何解决这个问题。

第二个规则代表了选举算法的“活跃性”(Liveness),它保证了在绝大多数时候,集群内都会有一个领导者,选举最终会完成并产生这个领导,即系统不应无限期地处于选举状态。

满足了以上两个属性的算法,我们才称其为有效的领导选举算法。

领导选举与分布式锁

领导选举和分布式锁在算法层面有很高的重合性,前者选择一个节点作为领导,而后者则是作为锁持有者,因此很多研发人员经常将二者混为一谈。那么现在,让我们比较一下领导者选举和分布式锁的区别。

分布式锁是保证在并发环境中,一些互斥的资源,比如事务、共享变量等,同一时间内只能有一个节点进行操作。它也需要满足上文提到的安全性和活跃性,即排他锁每次只能分配给一个节点,同时该节点不会无限期持有锁。

从理论上看,虽然它们有很多相似之处,但也有比较明显的区别。如果一个节点持有排他锁,那么对于其他节点来说,不需要知道谁现在持有这个锁,只要满足锁最终将被释放,允许其他人获得它,这就是前文所说的“活跃性”。

与此相反,选举过程完全不是这样,集群中的节点必须要知道目前系统中谁是领导节点,因为集群中其他节点需要感知领导节点的活性,从而判断是否需要进入到选举流程中。因此,新当选的领导人必须将自己的角色告知给它的下属。

另一个差异是:如果分布式锁算法对特定的节点或节点组有偏好,也就是非公平锁,它最终会导致一些非优先节点永远都获得不了共享资源,这与“活跃性”是矛盾的。但与其相反,我们一般希望领导节点尽可能长时间地担任领导角色,直到它停止或崩溃,因为“老”领导者更受大家的欢迎

解决单点问题

在分布式系统中,具有稳定性的领导者有助于减小远程节点的状态同步消耗,减少交换消息的数量;同时一些操作可以在单一的领导节点内部进行,避免在集群内进行同步操作。在采用领导机制的系统中,一个潜在的问题是由于领导者是单节点,故其可能成为性能瓶颈

为了克服这一点,许多系统将数据划分为不相交的独立副本集,每个副本集都有自己的领导者,而不是只有一个全局领导者,使用这种方法的系统代表是 Spanner。由于每个领导节点都有失败的可能,因此必须检测、报告,当发生此种情况时,一个系统必须选出另一个领导人来取代失败的领导人。

上面整体介绍了领导选举的使用场景和算法特点,那么领导选举是怎样操作的呢?

典型的算法包括:
Bully 算法、ZAB(Zookeeper Atomic Broadcast)、Multi-Paxos 和 RAFT 等。但是除了 Bully 算法外,其他算法都使用自己独特的方法来同时解决领导者选举、故障检测和解决竞争领导者节点之间的冲突。所以它们的内涵要远远大于领导选举这个范畴。

总结

  • 分布式系统中所有节点都是平等的关系,任何节点都可以承担领导角色
  • 许多系统将数据划分为不相交的独立副本集,每个副本集都有自己的领导者
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值