网站首页 > 文章精选 正文
简介
在分布式系统中,通常需要维护多个副本进行容错,多个副本就需要处理维护多个副本数据的一致性. 这类的一致性问题是分布式领域的基础问题.
为解决这个问题,Lamport 提出 Paxos 算法,它主要基于 Proposer、Acceptor、Learner 三个角色通过 Prepare、Accept 两个阶段达成分布式系统中的数据一致性. 尽管 Paxos 几乎是一致性算法的代名词,在学术理论上也很有影响力. 但它的论文相对难以理解,在工程实践中存在困难.
基于理解困难的问题,出现了简化版的一致性协议 raft (《In Search of an Understandable Consensus Algorithm》论文中通过实验验证了 raft 较 Paxos 更易理解),它通过 Leader、Follower、Candidate 三个角色,通过解决 Leader Election、Log Replication 和 Safety 三个问题确保数据在分布式系统中的一致性.
raft 协议介绍
Raft 采用的是 Leader 管理所有备份,一个 raft 集群中,只有一个合法的 Leader,所有客户端的 Log 操作,都需要通过 Leader 决定是否 commit.
由于 Leader 角色的重要性, raft 集群中需要确保集群中的 Leader 可用,当有 Leader 节点出现不可用时,能够自动切换 Leader.
Raft 协议通过 Leader Election 自动进行 Leader 选举. 同时在 Leader 切换之后,还需要确保新 Leader 一定包含先前 Commited Log.
raft 协议将这些问题的处理分成三个子问题,即Log Replication、 Leader Election、Safety. 后面将主要介绍这几个核心的机制.
leader 选举过程(leader Election)
raft 协议中,各个节点有三种角色状态,Leader、Candidate 和 Follower.
Leader: 负责处理所有客户端的请求. 并且会定期向集群中的 Follower 节点发送心跳信息,从而刷新 Follower 节点的选举计时器避免新一轮选举.
Candidate: 当 Follower 节点的选举计时器超时过期,就会将自身状态转化成 Candidate,并发起新一轮选举.
Follower: 只是响应来自 Leader 和 Candidate 的请求, 备份副本数据.
在 Leader 的选举过程中,为了增加选举的成果率,raft 增加了一个 election timeout 随机时间,进行投票选举. 各个阶段的规则如下:
election timer: 每个 follower 或 candidate 都有一个选举计时器,当 election timeout,follower 会变成 candidate 开始选举.
开启选举: 当在 election timer 时间内没有收到 leader 的 heartbeat 或者 candidate 发起的选举投票 requestVote RPC 时, 等待
投票规则: 节点收到 requestVote RPC 后,将按照先来先服务的原则进行投票,并且每个节点最多给一个 candidate 投票.
赢得选举: 当 candidate 接收到集群中同一 term 的多数票,则 candidate 赢得选举. 赢得选举的节点状态切换成 Leader,并向其它节点发送声明. 其它 candidate 收到 leader 声明且 term 比之前的都大后,接受新的 leader ,状态返回成 follower.
分裂投票: 当存在多个候选人时候,可能投票的结果是没有任何一个候选人取得大多数. 这时候,需要开启下一轮选举. raft 通过一个随机选举超时机制确保几乎不出现分裂投票.
选举过程如下面的动图所示,S1 ~ S5 在不同随机大小的 election timer 时间中,S1 率先结束发起选举,并成为 Leader. 并在随后不断的发起 heartbeat 刷新其它节点的计时器.
日志复制(Log Replication)
AppendEntries RPC: raft 服务器节点之间的通信主要基于各种 rpc,其中 appendEntries RPC 用于复制条目,同时也用来发送心跳.
日志格式: 日志由日志编号、任期、操作组成.
日志复制: 客户端向 etcd 发起修改请求. leader 收到请求后将负责指令的执行,首先 leader 将新的日志条目添加到日志中,然后并行的发起 AppendEntries RPC 请求给其他服务器,让它们复制这条信息. 当大多数服务器复制了这条日志,这条日志将会进行 commited 操作.
日志压缩: 随着日志的不断增多,占用的空间越来越多,并且需要花更长的时间重放,这将会带来可用性的问题. 所以需要日志压缩技术,比如快照技术, 它被用在了 zookeeper、chubby 中,raft 中也应用了快照技术.
安全机制(Safety)
安全性是用于保证每个节点都执行相同序列的安全机制,避免新 Leader 产生后存在 Log 覆盖问题的机制. Safety 用于保证选举出来的 Leader 一定包含先前 Committed Log 的机制.
- 选举安全性: 每个 term 周期最多只有一个 Leader 被选举出来.
- Leader 完整性: Log 在 commited 后,后续 term 的 Leader 都必须包含该 log.
开源库实现
至今,raft 以及有许多实现的版本,论文中提到工程代码大致 2000+ cpp 即可实现. 目前比较著名的raft 工程实现有 etcd ,其中就包含了 go 版本的 raft package. 下面地址是 raft 可以参考的实现代码 github 地址:
- etcd raft [https://github.com/coreos/etcd/raft]
- hashicorp raft [https://github.com/hashicorp/raft]
- logcabin raft 的实现[https://github.con/logcabin/logcabin]
此外,可以在 raft.github.io 上查阅所有关于 raft 的实现以及开发邮件讨论、论文以及 raft 可视化的动画.
参考资料
- Etcd 架构与实现解析 [http://jolestar.com/etcd-architecture/]
- etcd raft lib使用示例分析 [https://xiking.win/2019/09/22/etcd-raft-example-analysis/]
- raft 协议动画演示[http://thesecretlivesofdata.com/raft/]
- In Search of an Understandable Consensus Algorithm [Diego Ongaro and John Ousterhout Stanford University]
- 分布式一致性算法: Raft 算法(论文翻译)[https://www.cnblogs.com/linbingdong/p/6442673.html]
- 分布式系统一致性协议 Raft 的理解 [https://blog.wangjunfeng.com/post/raft/]
- raft github.io [https://raft.github.io/#implementations]
- 上一篇: 超融合介绍-SmartX
- 下一篇: 分布式事务:SpringCloud 项目中的一致性密码解锁
猜你喜欢
- 2025-08-02 分布式事务:SpringCloud 项目中的一致性密码解锁
- 2025-08-02 超融合介绍-SmartX
- 2025-08-02 分布式事务:如何保证多个系统间的数据一致性
- 2025-08-02 分布式事务详解、理论分析、及强一致性(2PC、3PC)剖析
- 2025-08-02 分布式事务
- 2025-08-02 什么是分布式文件存储系统 ?
- 2025-08-02 Paxos 协议
- 2025-08-02 elasticsearch--分布式原理
- 2025-08-02 分布式事务之三阶段提交,你了解多少?
- 2025-08-02 6 张图带你彻底搞懂分布式事务 XA 模式
- 08-02分布式事务:SpringCloud 项目中的一致性密码解锁
- 08-02raft 协议简介
- 08-02超融合介绍-SmartX
- 08-02分布式事务:如何保证多个系统间的数据一致性
- 08-02分布式事务详解、理论分析、及强一致性(2PC、3PC)剖析
- 08-02分布式事务
- 08-02什么是分布式文件存储系统 ?
- 08-02Paxos 协议
- 最近发表
- 标签列表
-
- newcoder (56)
- 字符串的长度是指 (45)
- drawcontours()参数说明 (60)
- unsignedshortint (59)
- postman并发请求 (47)
- python列表删除 (50)
- 左程云什么水平 (56)
- 编程题 (64)
- postgresql默认端口 (66)
- 数据库的概念模型独立于 (48)
- 产生系统死锁的原因可能是由于 (51)
- 数据库中只存放视图的 (62)
- 在vi中退出不保存的命令是 (53)
- 哪个命令可以将普通用户转换成超级用户 (49)
- noscript标签的作用 (48)
- 联合利华网申 (49)
- swagger和postman (46)
- 结构化程序设计主要强调 (53)
- 172.1 (57)
- apipostwebsocket (47)
- 唯品会后台 (61)
- 简历助手 (56)
- offshow (61)
- mysql数据库面试题 (57)
- fmt.println (52)