文章目录

一、分布式一致性算法

分布式一致性算法,用于解决分布式系统的数据一致性和集群共识问题。

  • 数据一致性是指,分布式系统对外提供的数据读写表现是一致的。当然可以细分为线性一致性、最终一致性等。
  • 集群共识是指,能够对集群达成某种状态产生一致意见。

1、比特币PoW等共识算法主要用于“节点间无法协商”的场景,相当于无限个节点在进行共识,因此借助概率来单机计算。

2、Paxos属于理论基础,实际应用通常都是基于它改造过的算法。

3、Zookeeper的ZAB算法(Zookeeper Atomic Broadcast),它其实不算是一个通用的算法,而是专门为ZK做的分布式一致性算法。它有两个印象深刻的点:

(1)每轮选主的投票会更新多次,每次收到投票都会进行选票PK,然后广播更新。优点是简单,但缺点是收敛可能会很慢。对比一下Raft,Raft采用多轮投票的形式,虽然每轮可能投不出一个主,但由于失败存在时间差,可以在多轮投票中快速收敛。

(2)选出新Leader之后,在进行Follower副本数据同步之前,需要先从Follower获取信息。这是因为虽然Leader的zxid是最大的,但是它可能包含一些未commit的数据,因此收集一下所有Follower的min/max_zxid,看是否已经分发给了大多数,如果没有,则需要删除该数据,这个阶段称之为Recovery Phase。对比Raft,Raft的同步总是从Leader流向Follower,它对于未commit的数据不会主动提交。

4、Raft算法。这是如今最为普遍应用的算法,如etcd、RocketMQ(dledger)、MongoDB、Kafka。注意,MongoDB之前使用的是简单选主算法Bully,新版本才开始使用Raft。kafka2.8开始,kafka可以不依赖于Zookeeper而是独立使用Raft进行部署(称为KRaft,KRaft (aka KIP-500) mode Early Access Release)。之前要用zookeeper来进行选主等操作,是因为Raft协议出现于Zookeeper之后。使用ZK的好处是,不用管分布式一致性问题,都交给ZAB;同时kafka的台数即使只剩1台,如果副本完全,也可以对外提供服务,不会受限于Raft的多数仲裁。坏处一大把,如分区问题、性能问题等,所以这个改动是合理的。

5、Gossip

流言协议是一个最容易理解的协议,目前Redis-Cluster、Cassandra、Akka、Jgroup等常见分布式选主都采用Gossip维护集群状态。它的缺点很明显,当节点数目过多,会造成控制协议的报文占据大量带宽、CPU等,浪费资源。它通常用于“集群共识”,特点是广播状态、节点对等,常见P2P应用。

Gossip比较有意思的是判断集群节点异常,有很多实现,比如“多数节点标记Fail”、或者Cassandra的“动态阈值”。

二、如何实践分布式一致性算法

了解了这么多协议,我们学习一下这些作者解决问题的思路,以及如何应用。

1、提问:如果要让你设计一套分布式一致性算法,你会如何设计?

很明显这个问题的本质是理解分布式一致性算法的基本功能点。在我看来,就两点:如何处理崩溃恢复、如何处理共识消息同步。

举例说明:

例如JQMTT项目,zze设计的思路和Gossip类似,定时广播更新,节点对等,根据更新时间设置阈值判断下线,他主要用来做集群共识。

类似的,HiveMQ使用了Jgroup来做集群共识,底层也是Gossip。

有的业务可能需要“选主”,通过主节点做一些清理工作,这个时候可以考虑使用Zookeeper来做,参考Kafka,共识消息通过Zookeeper的临时节点Watch进行广播,主节点崩溃时,能够自动选出新的主节点。

这些做的都是集群共识,如果还有数据一致性要求,比如“自建KV数据库”等需求,要求所有节点数据同步,可以使用类似Raft的思路。

如果跳脱出已有算法,完全可以根据需求,从“如何处理崩溃恢复”、“如何处理共识消息同步”入手设计新算法。

2、算法的数学证明很重要

比如ElasticSearch也有自己的分布式一致性协议,但它并没有类似Raft给出数学证明,因此只能靠修修补补来避免bug,也不能得到广泛应用。如果能够对这类算法进行数学证明,比如依概率收敛、极限情况等,算法的价值将会大大提升。

3、Raft协议将会是近期分布式系统的优化趋势

可以看到很多中间件都在往Raft协议上面靠,即使是ES,它也使用了“仲裁”的经典思路选主,而且越来越趋近于Raft协议。那么一方面说明它的生产稳定性,另一方面可能是个机会,例如给陈旧经典项目提Raft重构的PR,或者在设计自己的复杂系统时考虑采用类Raft算法。

4、纪元概念的使用

在分布式组件中,系统的的本地时钟通常都是不可靠的,因此总是采用“纪元Epoch”、“版本Version”、“轮次Term”等概念去进行状态同步。

转载请注明出处http://www.bewindoweb.com/305.html | 三颗豆子
分享许可方式知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议
重大发现:转载注明原文网址的同学刚买了彩票就中奖,刚写完代码就跑通,刚转身就遇到了真爱。
你可能还会喜欢
具体问题具体杠