分布式一致性协议的背景
我们讲分布式系统的一致性,一般来说,有如下几个分类:
-
强一致性。对一致性要求最高的,是强一致的,保证写操作完成后,任何后续访问都能读到更新后的值。但是性能较弱,在互联网系统里面用的较少,但是在金融领域使用的较多。因为是同步的,因此性能会比较低。
-
弱一致性。写操作完成后,系统不能保证后续的访问都能读到更新后的值。
-
最终一致性。是弱一致性的一个特定形式,如果对某个对象没有新的写操作了,最终所有后续访问都能读到相同的最近更新的值,但是是在最终某个时间点才能保证。弱一致性(最终一致性)都是异步的,因此性能会比较好。
如何理解分布式一致性
设计分布式系统的两大初衷:横向扩展(scalability)和高可用性(availability),横向扩展的目的也是为了解决单点问题从而保障可用性,因此分布式系统的核心诉求也就是可用性,为了保证可用性,一个分布式系统通常由多个节点组成,而这些节点各自维护一份数据,因此我们需要能够保证每个节点上的数据都是相同的,也就是要保证一致性,这就是我们所说的分布式一致性,他通过给定的一系列操作,在协议(共识算法)的保障下,试图使得它们对处理结果达成某种程度的一致。
共识性 vs 一致性
共识算法解决的是对某个提案(Proposal)让大家都达成一致意见的过程,而这个提案可以认为任何需要达成一致的信息都是一个提案,如多个事件发生的顺序、某个键对应的值等等。
一致性是指写操作完成后,能否从各节点上读到最新写入的数据,如果立即能读到,就是强一致性,如果最终能读到,就是最终一致性。
提到共识算法,Paxos 是一个必须要提及的话题,而且 ZAB 协议、Raft 算法都可以看作是 Paxos 变种,Paxos 和 Raft 是共识算法。所以,你需要了解 Paxos 算法。但因为 Paxos 算法的可理解性和可编程性痛点突出,所以在实际场景中,最常见的共识算法是 Raft,我们可以基于 Raft 实现强一致性系统,Raft 是需要彻底掌握的。(Redis集群的哨兵选举、主从集群中从节点选举都是基于Raft)。
一般而言,在可信环境(比如企业内网)中,系统具有故障容错能力就可以了,常见的算法有二阶段提交协议(2PC)、TCC(Try-Confirm-Cancel)、Paxos 算法、ZAB 协议、Raft 算法、Gossip 协议、Quorum NWR 算法。 而在不可信的环境(比如有人做恶)中,这时系统需要具备拜占庭容错能力,常见的拜占庭容错算法有 POW 算法、PBFT 算法。
采用 Gossip 协议实现的最终一致性系统的可用性是最高的,因为哪怕只有一个节点,集群还能在运行并提供服务。其次是 Paxos 算法、ZAB 协议、Raft 算法、Quorum NWR 算法、PBFT 算法、POW 算法,它们能容忍一定数节点故障。最后是二阶段提交协议、TCC,只有当所有节点都在运行时,才能工作,可用性最低。
采用 Gossip 协议的 AP 型分布式系统,具备水平扩展能力,读写性能是最高的。其次是 Paxos 算法、ZAB 协议、Raft 算法,因为它们都是领导者模型,写性能受限于领导者,读性能取决于一致性实现。最后是二阶段提交协议和 TCC,因为在实现事务时,需要预留和锁定资源,性能相对低。