>>分享孙卫琴的Java技术专稿和著作 书籍支持  卫琴直播  品书摘要  在线测试  资源下载  联系我们
发表一个新主题 开启一个新投票 回复文章 您是本文章第 8372 个阅读者 刷新本主题
 * 贴子主题:  【Spring Cloud Alibaba专题】Nacos集群的Raft算法 回复文章 点赞(0)  收藏  
作者:sunweiqin    发表时间:2022-08-25 09:14:18     消息  查看  搜索  好友  邮件  复制  引用

本文参考孙卫琴,杜聚宾所创作的<<Spring Cloud Alibaba微服务开发宝典>>一书,即将出版

问题:在Nacos集群中,每个节点都持有微服务列表以及微服务的配置单元信息,如何保证各个节点的数据的一致性呢?
答案:Nacos集群采用Raft算法来保证各个节点的数据的一致性。由于Raft算法规定了节点之间的通信过程,因此也把它称为Raft协议。

Raft算法要求集群中节点的数目为奇数,并且至少有三个节点。每个节点处于以下三种角色之一:
(1)Leader(领导):协调各个节点的数据同步,定时向Follower发送心跳,表明自己活着。任何时候,集群中只有一个Leader。
(2)Follower(随从):负责响应Leader和Candidate的请求。
(3)Candidate(竞选人):这是过渡角色。当集群中Leader宕机后,Follower就有可能变成Candidate,发起新一届的选举。

1. 节点之间数据的同步

假定有三个Nacos节点:节点A、节点B和节点C。节点A为Leader,节点B和节点C为Follower。节点之间数据的同步分两种情况:
(1)如果节点A上的配置单元发生了更新,节点A作为Leader,会直接通知节点B和节点C同步更新配置单元,参见图1。

点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
图1  当节点A的配置单元发生更新后各个节点的同步过程
(2)如果节点B上的配置单元发生更新,节点B作为Follower,先向节点A汇报配置单元发生更新,节点A再通知所有的Follower同步更新配置单元。参见图2。
点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
图2  当节点B的配置单元发生更新后各个节点的同步过程

2.  节点的选举机制

在民主社会中,每一届的领导通过选举产生。同样,Raft算法也通过选举产生领导。

变量term表示当前是第几届选举。假定在节点A、节点B、节点C、节点D和节点E构成的集群中,一开始变量term为1,表示当前为第一届选举,产生的Leader为节点A,其余节点都是Follower。
如图3所示,集群发生Leader换届的过程如下。
(1)一开始,节点A定时向其他节点发送心跳,表明自己一直活着。其他节点收到节点A的心跳后,知道现在群龙有主,就老老实实地做Follower。
(2)节点A宕机。节点B等待接收节点A的心跳,最后超时。
(3)节点B认为节点A已经下线,群龙无主,就跃跃欲试,想自己当领导。节点B由Follower变为Candidate,把变量term改为2,发起新一届选举。
(4)节点B首先给自己投一票,又向节点C、D和E发送票据,希望它们也给自己投票。于是其余节点都给节点B投了一票,节点B就成了新的Leader。


点击在新窗口中浏览原图
CTRL+鼠标滚轮放大或缩小
图3  节点B竞选成为Leader的过程

问题:假如节点A宕机后,节点B和节点C都变成Candidate,想当Leader,都向节点D和节点E发送票据拉选票,会怎么样呢?
答案:Raft算法规定,在每一届选举中,每个节点只能投1票。这意味着节点D和节点E只能在节点B和节点C中选择一个投票。对于节点B和节点C,收到过半投票数的节点成为Leader。

为了保证选举顺利举行,Raft算法做了以下限定:
(1)收到过半票数的Candidate成为Leader。
(2)当一个Candidate被告知其他节点已经成为Leader,则自己切换为Follower。
(3)一个Candidate在一段时间内没有收到过半的投票数,并且集群内尚未出现Leader,那么该Candidate会重新发起新一届的选举。




程序猿的技术大观园:www.javathinker.net
  Java面向对象编程-->面向对象开发方法概述之开发思想(上)
  JavaWeb开发-->自定义JSP标签(Ⅰ)
  JSP与Hibernate开发-->Java对象持久化技术概述
  Java网络编程-->Socket用法详解
  精通Spring-->组合(Composition)API
  Vue3开发-->绑定CSS样式
  【Vue.js技术专题】路由导航中抓取数据
  【Vue.js技术专题】CSS中DOM元素的过渡模式
  【Java基础编程专题】使用和创建JavaDoc文档
  【Spring专题】服务器端推送
  【Spring专题】通过JPA API实现Repository接口
  【持久化专题】JPA的事件处理API的用法
  【持久化专题】Spring与Hibernate与JPA的整合
  【Java网络编程专题】用Apache HttpClients下载网上的图片等...
  【Java网络编程专题】创建基于SSL的安全服务器和安全客户的范...
  【Java网络编程专题】异步通道和异步运算结果
  IT技术书写作技巧分享:慎用概念和术语
  【Java基础编程专题】Java集合的批量操作
  【Java基础编程专题】Java集合与数组的互换
  【Java基础编程专题】Java继承的利弊和使用原则
  【Java基础编程专题】为什么说:继承关系最大的弱点就是打破...
  更多...
 IPIP: 已设置保密
树形列表:   
1页 0条记录 当前第1
发表一个新主题 开启一个新投票 回复文章


中文版权所有: JavaThinker技术网站 Copyright 2016-2026 沪ICP备16029593号-2
荟萃Java程序员智慧的结晶,分享交流Java前沿技术。  联系我们
如有技术文章涉及侵权,请与本站管理员联系。