优秀而惊艳的 raft

LinkinStar · · 456 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

定义

通过一个 Leader 来实现节点共识和日志一致

https://www.linkinstar.wiki/2019/06/12/golang/open-source-component/etcd-raft/

细节

通信

  • 投票 RPC:候选人发起,选举期间,通知各个节点进行投票

  • 日志 RPC:领导者发起,进行日志复制和提供心跳(没有日志的请求)

任期

  • 任期单调递增

  • 发现自己的任期小(收到任期大消息)会立即变成 follower

  • 收到任期小的消息,直接拒绝

选举

  1. Leader 定期心跳,保证自己的地位还在

  2. Follower 指定时间没有收到心跳,进行自举

  3. 选票数高者当选

  4. 在一个任期内除非自己意外离线,否则一直为 Leader

  5. 每次投票只能投一个

  6. 日志更多者优先

日志

  • 领导者不直接发送消息通知其他节点提交日志项,因为领导者的日志赋值 RPC 和心跳(没有日志的日志 PRC 请求)会包含当前最大的日志索引值。(这是一个优化,这样只要有半数以上的follower收到,那么本地提交就可以直接返回客户端结果了,不用再次所有再提交通知一次)

  • 在 Raft 中日志必须是连续的

与 Multi-Paxos 相比

  • 选举并不是一次 k-v 的共识,而是有了自己的方案,通过随机心跳和日志来完成

  • 通过任期、心跳、随机时间、先来先服务、日志数量多个维度保证选举的 Leader 唯一性,减少选举失败的可能性和多次重复进行选举的可能性

新添加节点

很多人觉得新添加节点是一个很容易的事情,但是其实这是一个很困难的事情。

并不是你直接添加节点到集群里面,作为一个 follower 就可以了,因为这会导致原来的所谓大多数不再是大多数。节点中的其他节点并不知道有新节点的加入。

  1. Leader 先向新节点同步数据

  2. Leader 将新节点配置作为一个日志,复制到每个节点中,包括新节点,然后本地提交

  3. 每次变更都是单个节点加入

这样就不会存在新旧配置的两个大多数,来保证集群中不会出现两个领导者。


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:LinkinStar

查看原文:优秀而惊艳的 raft

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

456 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传