分布式精华笔记!带你深入剖析一致性共识算法还不来看?

二、分布式一致性算法前奏之Quorum NWR算法

=========================

Quorum选举算法

在N个副本中,一次更新成功的如果有W个,那么在读取数据时是要从大于N-W个副本中读取,这样就能至少读到一个更新的数据了。

如:维护了10个副本,一次成功更新了三个,那么至少需要读取八个副本的数据,可以保证读到最新的数据。

WARO算法(Write All Read one)

只有当所有的副本都更新成功之后,这次写操作才算成功,否则视为失败。WARO 优先保证读服务,因为所有的副本更新成功,才能视为更新成功,从而保证了所有的副本一致,这样的话,只需要读任何一个副本上的数据即可。写服务的可用性较低,因为只要有一个副本更新失败,此次写操作就视为失败了。假设有 N 个副本,N-1 个都宕机了,剩下的那个副本仍能提供读服务;但是只要有一个副本宕机了,写服务就不会成功。WARO 牺牲了更新服务的可用性,最大程度地增强了读服务的可用性,而 Quorum 就是在更新服务和读服务之间进行的一个折衷。

Quorum的应用

Quorum机制无法保证强一致性,也就是无法实现任何时刻任何用户或节点都可以读到最近一次成功提交的副本数据。

Quorum机制的使用需要配合一个获取最新成功提交的版本号的metadata服务,这样可以确定最新已经成功提交的版本号,然后从已经读到的数据中就可以确认最新写入的数据。

Quorum是分布式系统中常用的一种机制,用来保证数据冗余和最终一致性的投票算法,在Paxos、Raft和ZooKeeper的Zab等算法中,都可以看到Quorum机制的应用。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

如上图所示,DATA-1有2个副本,DATA-2有3个副本,DATA-3 有1个副本,副本的数量即表示N;对DATA-2执行写操作时,完成了2个副本的更新(节点B、C),才完成写操作,即W此时为2;对DATA-2执行读操作,客户端读取DATA-2的数据时,需要读取2个副本中的数据,然后返回最新的那份数据,即读副本R为2。

无论客户端如何执行读操作,即使访问写操作未强制更新副本节点B,执行读操作时,因为要读2份数据副本,所以除了节点B上的DATA-2,还会读取节点C上的DATA-2,而节点C的DATA-2数据副本是强制更新成功的,这个时候返回给客户端肯定是最新的那份数据。

对于Quorum:

当W+R>N的时候,对于客户端来讲,整个系统能保证强一致性,一定能返回更新后的那份数据。

当W+R<=N的时候,对于客户端来讲,整个系统只能保证最终一致性,可能会返回旧数据。

三、paxos算法

=========

paxos算法由Proposer、Acceptor和Learner组成:

**提议者(Proposer):**提议一个值,用于投票表决。在绝大多数场景中,集群中收到客户端请求的节点,才是提议者。这样做的好处是,对业务代码没有入侵性,也就是说,我们不需要在业务代码中实现算法逻辑,就可以像使用数据库一样访问后端的数据。

**接受者(Acceptor):**对每个提议的值进行投票,并存储接受的值,比如A、B、C三个节点。 一般来说,集群中的所有节点都在扮演接受者的角色,参与共识协商,并接受和存储数据。

**学习者(Learner):**被告知投票的结果,接受达成共识的值,存储保存,不参与投票的过程。一般来说,学习者是数据备份节点,比如“Master-Slave”模型中的Slave,被动地接受数据,容灾备份。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

Basic Paxos

在Basic Paxos中,使用提案代表一个提议,在提案中除了提案编号,还包含了提议值。使用[n, v]表示一个提案,其中n为提案编号,v为提议值。

整个共识协商是分2个阶段进行的(二阶段提交)。假设客户端1的提案编号为1,客户端2的提案编号为5,节点A、B先收到来自客户端1的准备请求,节点C先收到来自客户端2的准备请求。

prepare阶段

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

客户端1、2作为提议者,分别向所有接受者发送包含提案编号的准备请求:

对于客户端1的提案,由于之前没有通过任何提案,所以节点A、B以后将不再响应提案编号小于等于1的prepare请求,即不会通过编号小于1的提案,节点C以后不再响应提案编号小于等于5的准备请求,即不会通过编号小于5的提案;

对于客户端2的提案,当节点A、B收到提案编号为5的准备请求的时候,因为提案编号5大于它们之前响应的准备请求的提案编号1,而且两个节点都没有通过任何提案,所以它将返回一个 “尚无提案”的响应,所以节点A、B将不再响应提案编号小于等于5的准备请求,即不会通过编号小于5的提案, 当节点C收到提案编号为1的准备请求的时候,由于提案编号1小于它之前响应的准备请求的提案编号5,所以丢弃该准备请求不做响应;

Accept阶段

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

首先客户端1、2在收到大多数节点的准备响应之后,会分别发送接受请求:

当客户端1收到大多数的接受者(节点A、B)的准备响应后,根据响应中提案编号最大的提案的值设置接受请求中的值。因为节点A、B的准备响应中都为空,所以就把自己的提议值3作为提案的值,发送接受请求[1, 3];

当客户端2收到大多数的接受者的准备响应后(节点A、B和节点C),根据响应中提案编号最大的提案的值,来设置接受请求中的值。因为该值在来自节点A、B、C的准备响应中都为空,所以就把自己的提议值7作为提案的值,发送接受请求[5, 7];

当三个节点收到2个客户端的接受请求时:

当节点A、B、C收到接受请求[1, 3]的时候,由于提案的提案编号1小于三个节点承诺能通过的提案的最小提案编号5,所以提案[1, 3]将被拒绝;

当节点A、B、C收到接受请求[5, 7]的时候,由于提案的提案编号5不小于三个节点承诺能通过的提案的最小提案编号5,所以就通过提案[5, 7],也就是接受了值7,三个节点就X值为7达成了共识;

Multi-Paxos

Basic Paxos只能就单个值(Value)达成共识,Multi-Paxos是通过多个Basic Paxos实例实现一系列值的共识的算法。

Multi-Paxos通过引入Leader节点,将Leader节点作为唯一提议者,避免了多个提议者同时提交提案的情况,解决了提案冲突的问题, Leader节点是通过执行Basic Paxos算法,进行投票选举产生的。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

优化Basic Paxos执行可以采用“当领导者处于稳定状态时,省掉准备阶段,直接进入接受阶段”这个优化机制。在Leader节点上,序列中的命令是最新的,不再需要通过准备请求来发现之前被大多数节点通过的提案,Leader可以独立指定提案中的值。Leader节点在提交命令时,可以省掉准备阶段,直接进入到接受阶段:

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

和重复执行Basic Paxos相比,Multi-Paxos引入领导者节点之后,因为只有领导者节点一个提议者,所以就不存在提案冲突。另外,当主节点处于稳定状态时,就省掉准备阶段,直接进入接受阶段,所以在很大程度上减少了往返的消息数,提升了性能,降低了延迟。

四、一致hash算法

==========

使用哈希算法的问题?

通过哈希算法,每个key都可以寻址到对应的服务器,比如,查询key是key-01,计算公式为hash(key-01) %3 ,经过计算寻址到了编号为1的服务器节点A; 如果服务器数量发生变化,基于新的服务器数量来执行哈希算法的时候,就会出现路由寻址失败的情况,无法找到之前寻址到的那个服务器节点;假如增加了一个节点,节点的数量从3变化为4,那么之前的hash(key-01) %3 = 1,就变成了hash(key-01) %4 =X,因为取模运算发生了变化,所以这个X大概率不是1,这时再查询就会找不到数据了,因为key-01对应的数据并非存储在节点X。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

通过上图可以看出,当扩容增加一个节点时会出现hash寻址失败的情况;同理,如果需要下线1个服务器节点,也会存在类似的可能查询不到数据的问题。

一致哈希实现哈希寻址

一致哈希算法也用了取模运算,但与哈希算法不同的是,哈希算法是对节点的数量进行取模运算,而一致哈希算法是对2^32进行取模运算。在一致哈希中,可以通过执行哈希算法将节点映射到哈希环上,如选择节点的主机名作为参数执行hash(),那么每个节点就能确定其在哈希环上的位置了。

当需要对指定key的值进行读写的时候,可以通过下面2步进行寻址:

首先,将key作为参数执行hash()计算哈希值,并确定此key在环上的位置;

然后,从这个位置沿着哈希环顺时针“行走”,遇到的第一节点就是key对应的节点。

根据一致哈希算法,key-01将寻址到节点A,key-02将寻址到节点B,key-03将寻址到节点C。假设现在节点C故障了,key-01和key-02不会受到影响,只有key-03的寻址被重定位到A。在一致哈希算法中,如果某个节点宕机不可用了,那么受影响的数据仅仅是会寻址到此节点和前一节点之间的数据。比如当节点C宕机了,受影响的数据是会寻址到节点B和节点C之间的数据(例如key-03),寻址到其他哈希环空间的数据不会受到影响。同理,如果集群扩容一个节点,在一致哈希算法中,如果增加一个节点,受影响的数据仅仅是会寻址到新节点和前一节点之间的数据,其它数据也不会受到影响。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

在哈希寻址中常出现这样的问题:客户端访问请求集中在少数的节点上,出现了有些机器高负载,有些机器低负载的情况,在一致哈希中可以使用虚拟节点让数据访问分布的比较均匀。

使用虚拟节点解决冷热不均的问题:

对每一个服务器节点计算多个哈希值,在每个计算结果位置上,都放置一个虚拟节点,并将虚拟节点映射到实际节点。

比如,可以在主机名的后面增加编号,分别计算 “Node-A-01”“Node-A-02”“Node-B-01”“Node-B-02”“Node-C-01”“Node-C-02”的哈希值,于是形成6个虚拟节点;增加了节点后,节点在哈希环上的分布就相对均匀了。如果有访问请求寻址到“Node-A-01”这个虚拟节点,将被重定位到节点A。

因此,当节点数越多的时候,使用哈希算法时,需要迁移的数据就越多,使用一致哈希时,需要迁移的数据就越少。所以相比hash算法, 一致哈希算法具有较好的容错性和可扩展性。

五、zab协议

Multi-Paxos解决的是一系列值如何达成共识的问题,不关心最终达成共识的值是什么,不关心各值的顺序,即它不关心操作的顺序性。

ZAB协议基于主备模式的原子广播,最终实现了操作的顺序性。Master-Slave的主备模型,主节点采用二阶段提交,向备份节点同步数据,如果主节点发生故障,数据最完备的节点将当选主节点;原子广播协议,广播一组消息,消息的顺序是固定的。

ZAB支持3种成员身份(领导者、跟随者、观察者)。

领导者(Leader): 作为主节点,在同一时间集群只会有一个领导者,所有的写请求都必须在领导者节点上执行。

**跟随者(Follower):**作为备份节点, 集群可以有多个跟随者,它们会响应领导者的心跳,并参与领导者选举和提案提交的投票,跟随者可以直接处理并响应来自客户端的读请求,但对于写请求,跟随者需要将它转发给领导者处理。

**观察者(Observer):**作为备份节点,类似跟随者,但是没有投票权,观察者不参与领导者选举和提案提交的投票。

ZAB在Multi-Paxos的基础上做了优化,为了实现分区容错能力,将数据复制到大多数节点后,领导者就会进入提交执行阶段,通知备份节点执行提交操作。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

ZAB定义了4种成员状态:

**LOOKING:**选举状态,该状态下的节点认为当前集群中没有领导者,会发起领导者选举。

**FOLLOWING :**跟随者状态,意味着当前节点是跟随者。

**LEADING :**领导者状态,意味着当前节点是领导者。

**OBSERVING:**观察者状态,意味着当前节点是观察者。

如上图所示, 首先,当跟随者检测到连接领导者节点的读操作等待超时了,跟随者会变更节点状态,将自己的节点状态变更成LOOKING,然后发起领导者选举; 接着,每个节点会创建一张选票,这张选票是投给自己的,然后各自将选票发送给集群中所有节点, 一般而言,节点会先接收到自己发送给自己的选票(因为不需要跨节点通讯,传输更快); 集群的各节点收到选票后,为了选举出数据最完整的节点,对于每一张接收到选票,节点都需要进行领导者PK,也就将选票提议的领导者和自己提议的领导者进行比较,找出更适合作为领导者的节点,约定的规则如下:

  • 优先检查任期编号(Epoch),任期编号大的节点作为领导者;

  • 如果任期编号相同,比较事务标识符的最大值,值大的节点作为领导者;

  • 如果事务标识符的最大值相同,比较集群ID,集群ID大的节点作为领导者。

如果选票提议的领导者,比自己提议的领导者,更适合作为领导者,那么节点将调整选票内容,推荐选票提议的领导者作为领导者。

zab故障恢复是由成员发现和数据同步两个阶段完成的,成员发现是通过跟随者和领导者交互来完成的,目标是确保大多数节点对领导者的领导关系没有异议,也就是确立领导者的领导地位:

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

成员发现,是为了建立跟随者和领导者之间的领导者关系,并通过任期编号来确认这个领导者是否为最合适的领导者。 当跟随者和领导者设置ZAB状态为数据同步,它们也就是进入了数据同步阶段,数据同步也是通过跟随者和领导者交互来完成的,目标是确保跟随者节点上的数据与领导者节点上数据是一致的。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

数据同步,是通过以领导者的数据为准的方式,来实现各节点数据副本的一致,需要你注意的是,基于“大多数”的提交原则和选举原则,能确保被复制到大多数节点并提交的提案,就不再改变。

对于zab处理写请求:

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

由于写请求只能在领导者节点上处理,所以ZooKeeper集群写性能约等于单机。而读请求是可以在所有的节点上处理的,所以读性能是能水平扩展的。可以通过分集群的方式来突破写性能的限制, 并通过增加更多节点,来扩展集群的读性能。

首先,ZAB实现了主备模式,也就是所有的数据都以主节点为准;

其次,ZAB实现了FIFO队列,保证消息处理的顺序性。

另外,ZAB还实现了当主节点崩溃后,只有日志最完备的节点才能当选主节点,因为日志最完备的节点包含了所有已经提交的日志,所以这样就能保证提交的日志不会再改变。

六、raft算法

========

Raft算法是分布式系统开发首选的共识算法 ,从本质上说,Raft算法是通过一切以领导者为准的方式,实现一系列值的共识和各节点日志的一致。

Raft算法支持领导者(Leader)、跟随者(Follower)和候选人(Candidate)3种状态:

**跟随者:**就相当于普通群众,默默地接收和处理来自领导者的消息,当等待领导者心跳信息超时的时候,就主动站出来,推荐自己当候选人。

**候选人:**候选人将向其他节点发送请求投票(RequestVote)RPC消息,通知其他节点来投票,如果赢得了大多数选票,就晋升当领导者。

**领导者:**主要工作内容就是3部分,处理写请求、管理日志复制和不断地发送心跳信息。

选举领导者的过程:

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

首先,在初始状态下,集群中所有的节点都是跟随者的状态,每个节点等待领导者节点心跳信息的超时时间间隔是随机的。集群中没有领导者,而节点A的等待超时时间最小(150ms),它会最先因为没有等到领导者的心跳信息而发生超时。节点A就增加自己的任期编号,并推举自己为候选人,先给自己投上一张选票,然后向其他节点发送请求投票RPC消息,请求它们选举自己为领导者。当候选人节点A在选举超时时间内赢得了大多数的选票,那么它就会成为本届任期内新的领导者。

搞了这么久分布式,深入剖析一致性共识算法,你了解多少?

节点A当选领导者后,将周期性地发送心跳消息,通知其他服务器以阻止跟随者发起新的选举。

Raft算法中约定的选举规则:

  1. 领导者周期性地向所有跟随者发送心跳消息,阻止跟随者发起新的选举。

  2. 如果在指定时间内,跟随者没有接收到来自领导者的消息,那么它就认为当前没有领导者,推举自己为候选人,发起领导者选举。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!

如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)

img

最后

一次偶然,从朋友那里得到一份“java高分面试指南”,里面涵盖了25个分类的面试题以及详细的解析:JavaOOP、Java集合/泛型、Java中的IO与NIO、Java反射、Java序列化、Java注解、多线程&并发、JVM、Mysql、Redis、Memcached、MongoDB、Spring、Spring Boot、Spring Cloud、RabbitMQ、Dubbo 、MyBatis 、ZooKeeper 、数据结构、算法、Elasticsearch 、Kafka 、微服务、Linux。

这不,马上就要到招聘季了,很多朋友又开始准备“金三银四”的春招啦,那我想这份“java高分面试指南”应该起到不小的作用,所以今天想给大家分享一下。

image

请注意:关于这份“java高分面试指南”,每一个方向专题(25个)的题目这里几乎都会列举,在不看答案的情况下,大家可以自行测试一下水平 且由于篇幅原因,这边无法展示所有完整的答案解析
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
d、MongoDB、Spring、Spring Boot、Spring Cloud、RabbitMQ、Dubbo 、MyBatis 、ZooKeeper 、数据结构、算法、Elasticsearch 、Kafka 、微服务、Linux。

这不,马上就要到招聘季了,很多朋友又开始准备“金三银四”的春招啦,那我想这份“java高分面试指南”应该起到不小的作用,所以今天想给大家分享一下。

[外链图片转存中…(img-Q739py3f-1713538325678)]

请注意:关于这份“java高分面试指南”,每一个方向专题(25个)的题目这里几乎都会列举,在不看答案的情况下,大家可以自行测试一下水平 且由于篇幅原因,这边无法展示所有完整的答案解析
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值