Raft分布式一致性协议基本过程

        前言

        raft协议是分布式一致性协议的一种实现方案,那么什么是分布式一致性,这就还得需要了解其他的网络知识了

        为了向用户提供服务,就需要有对应的服务器提供,在早些年的时候,很多网络应用服务器节点都只有一个,这个时候并不会有分布式一致性的问题,因为一个客户端把数据写到服务器要么写成功,要么写失败,没有其他的情况,但是会引起一个单节点故障的问题,如果当前服务器节点挂掉以后,那么整个网址就无法提供服务了,因此随着时代的发展,必然需要多服务器节点来共同提供服务,在这种情况下,就会有新的问题引入,如下

        CAP理论

        CAP的意思如下

C: 数据一致性,

A: 服务可用性

P: 分区容错性

        首先,在一个分布式系统中,P是必须要保证的,P的意思是说在我们的集群中,由于网络存在很多不可控的因素,节点中有可能会失去联系,但是这种情况下我们不能直接让整个集群都无法服务,所以这个P是必须要考虑,那么剩下的就是说要实现A或者C的问题

        A是指服务可用性,它带来的好处就是说只要集群中还有一个节点存活,那么客户端就可以使用,这样一来系统的可用性就会提高,但是他同时带来的问题也是很明显的,如果客户端刚写完数据到某个节点1,然后就返回成功给客户端了,此时节点1刚要同步给其他节点的时候挂掉了,那么节点1的数据就会丢失了,而客户端明明收到了成功的响应,这就会带来数据不一致的问题

        P是指数据一致性,它带来的好处跟A其实就是反过来的,一般CP架构下都会有个leader节点,客户端所有的写操作都需要经过leader节点来操作,此时写数据是这样的,客户端写一个5的数据给CP架构的集群里,此时leader数据先写成功,然后leader会同步给其他的节点,当整个集群有半数以上的节点数据写成功以后,才会响应给客户端写入成功,这样一来,数据一致性就有了保证,很明显CP架构的缺点就是A的优点,由于需要同步数据给其他节点,那么性能肯定会比较低了

BASE原则

        base原则是对CAP理论进行补充的,因为一般情况下同时实现CAP是不存在的,但是可以尽可能的兼容三者,而BASE就是为了解决这个问题的

BA: 基本可用

S: 软状态

E: 最终一致性

        也就是说当集群某个节点挂掉以后,集群仍然要对外可用,如果是因为分区引起的网络不通,那么此时集群节点中的数据不是一致的,这种情况称为软状态,但是当节点重启后或者网络分区恢复后,数据落后的节点要自己主动拉取最新的数据进行同步,同步后的状态便称为最终一致性了

        为了提高性能,其实都是基于半数机制,而不是真正意义的等待所有节点同步后才返回的,因为那样就太耗性能了

        最后,对一个分布式系统来说,只能同时保证两个特性,比如我们Java开发常见的一些中间件架构,redis是AP架构,zookeeper是CP架构,nacos可以支持AP或者CP架构,而raft协议就是实现CP架构的一种协议,下面就来说说这个协议

Raft协议

        对于raft协议,国外有一个比较好的网站,也可以直接参考这个网站,个人对于raft协议的理解也是基于这个网站:Raft分布式一致性协议

        raft协议分为两个部分,集群选举和数据复制

集群选举

        在使用raft协议的分布式系统中节点有三种状态

Candidate :竞选者,当集群中没有leader节点时

Follower:追随者,追随leader的节点

Leader :集群中的领导者

        集群选择的大概过程,具体可以直接看网站,更清晰

1. 刚开始集群所有的节点状态都为Follower状态

2. 所有的节点会随机休眠一定时间,在150ms-300ms之间

3. 当某个节点苏醒后它会先投自己一篇,然后把投票信息发给其他的节点,其他节点假设还没有苏醒,那么就会响应这个投票,解设当前节点收到的票数超过集群节点的半数,那么当前节点就会变为Leader 状态,如果收不到,那么又会重新随机休眠

4. 当某个节点变为Leader状态时,Leader会发送请求给其他的Follower节点,Follower节点收到消息后会响应给Leader,此时Leader就会与所有的Follower保持心跳,Follower节点会先从Leader同步一次数据,后面就一直保持心跳了

        这个过程就是集群选举的流程,假设此时的Leader节点挂掉以后,那么就会进入重新选举的流程

1. 心跳得不到响应以后,也就是Leader挂掉了,那么其他的Follower节点就会发起重新的选举,选举的流程和上面都是一样的

2. 只是多了一步选取完Leader以后Follower会从Leader拉取一次同步数据

数据复制

        当集群选举出Leader以后,就进入到数据复制过程了,raft使用的是二阶段提交的方式,主要的过程如下

1. 客户端向集群中发送一个数据5到Leader中,如果接收到请求的不是Leader节点,那么会被自动转到Leader节点上

2.Leader节点收到数据5以后写入自己本地日志中,此时数据处于未提交状态

3. Leader写完本地日志以后便会通过下次心跳机制把数据传送给其他的节点

4. 其他节点收到数据以后也在自己的节点上写入数据,此时也还是未提交的数据,接着就会响应给Leader节点,Leader节点接收到半数的节点通知后就会把之前的数据设置为已提交,然后反馈给客户端写入成功

5. Leader接着再发送消息给其他节点,其他节点收到以后也会把自己本地日志写为提交状态

        至此,数据复制过程就结束了,值得一提的是raft是支持网络分区的

网络分区处理

        解设集群有5个节点A,B,C,D,E,如果在某个时刻下,A和B形成了一个小集群,C,D,E形成了一个小集群,两个小集群中节点互不相通,此时每个小集群都会有自己的Leader,也就是客户端可以往两个Leader写数据,但是raft协议的设计中,如果客户端往A,B集群写数据,由于raft协议存在着半数机制,客户端虽然可以写未提交的数据给A数据的Leader节点,但是整个小集群只有两个节点,达不到半数的要求,所以数据会一直停留在未提交的状态,而另一个集群是可以写数据

        当网络分区结束后,两个小集群就会合并为大集群,是数据也会同步一致,至此,便解决了这个问题

nacos CP架构部分设计核心点

        使用CountDownLatch来保证半数节点同步成功机制

        心跳是从Leader发送给其他节点的

        心跳发送的数据只包括key信息,并且对发送的信息进行了压缩处理

        从节点收到数据以后会再次整理需要更新的key,然后再根据key去主节点提供的接口拉取数据进行同步,这种设计就比较巧妙了,数据同步的过程不至于给Leader带来过大的压力,当然了也会这样做就会有数据稍微延时的情况存在,从节点还进行了优化,如果数据不到50就不去Leader节点拉取数据,这一步是为了减少网络的传输,也是一个可以参考的设计点

结语

        raft协议的基本过程并不复杂,而且参考这个网站基本也能看懂

Raft分布式一致性协议

        当然了这个协议可能还存在一些其他的细节问题,这里就暂时不讨论了,有空的可以再查查其他的资料

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值