前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Raft算法导读

Raft算法导读

作者头像
哒呵呵
发布2018-10-18 11:18:27
9280
发布2018-10-18 11:18:27
举报
文章被收录于专栏:鸿的学习笔记鸿的学习笔记
导论

Raft算法是管理复制日志的一致性算法。

一致性的算法是让分布式系统表现的像单机系统一样,即使系统中有一些机器损坏了,也一样可以正常运行。

Raft设计出来是为了实现工程上的可用,避免Paxos算法的复杂性,从In Search of an Understandable Consensus Algorithm (Extended Version)这篇论文也可以看出,Raft部分原因也是为教学设计。论文很长,并且也已经有中译版,权且把这篇文章当作一篇导读。

复制状态机(Replicated State Machine)

在Raft算法中,集群像HDFS一样是主从架构,每一台机器的状态都唯一依赖于日志,而日志只来源于Master节点。日志中包含中一系列的命令,命令都包含着唯一编号,编号只会递增,不会减少或发生变更,而机器会根据命令不断地执行下去,所以只要日志保持一致,每台机器最终都会保证在统一状态。这也就是复制状态机。

问题分解

Raft算法将一致性问题拆分成了领导选取(leader election)、日志复制(log replication)、安全(safety)和成员变化(membership changes)四个小问题,分别给出了解答。

领导选取

如上文所述,Raft算法必须要有一个Master节点,那么Master节点必须要有一个选取地过程,以保证Master宕机后,也能在其它节点运行。Raft算法将集群中机器地角色分为了三种:

  • 领导人(Leader)
  • 候选人(Candidate)
  • 追随者(Follower)

三者地状态变化如下图:

简单来说,Follower会只会接收请求,当Follower接受不到请求时,会变成一个Candidate发起一次Election,获得绝大数票的Candidate会成为Leader。在Election的过程中会遵循下面几条原则:

  • 只有当一个Candidate得到过半的选票时才能赢得选举,每一个节点按照先到先得的方式,最多投票给一位Candidate。
  • 在等待投票结果的过程中,如果Candidate收到其他节点发送的心跳信息(AppendEntries RPC),并检查心跳信息中的任期不比自己小,则自己变为Follower,听从新上任的Leader的指挥。
  • 当未获得结果时,会重新发起一次Election,Raft为了避免wait时间过长,Leader不可用的超时时长随机获得,以避免同一时间宕机,同样的Candidate的拉票也是随机发送请求。
日志复制

Leader把每一条请求作为新的日志条目加入到它的日志中去,然后并行的向其他服务器发起 AppendEntries RPC ,要求其它服务器复制这个条目。当这个条目被安全的复制之后,Leader会将这个条目应用到它的状态机中并且会向客户端返回执行结果。如果Follower发生意外(崩溃、运行缓慢、网络丢包等),领导人会无限的重试 AppendEntries RPC(甚至在它向客户端响应之后)以保证所有的Follower最终存储了所有的日志条目。

日志的结构中不仅包含具体的操作,还包含本次插入的前一个位置的index和Term(任期),从而保证:

  • 如果在不同日志中的两个条目有着相同的index和Term,则它们所存储的命令是相同的。
  • 如果在不同日志中的两个条目有着相同的index和Term,则它们之间的所有条目都是完全一样的。

简而言之一句话:Leader负责一致性检查,同时让所有的Follower都和自己保持一致。

安全

有了上面所述,继而引发安全问题,如何保证日志是可靠的:

  1. 日志在传输过程中可能会因为种种原因导致日志发生缺失,所以并不是任何一个Follower都有资格成为Leader,因为如果一个Follower缺少了上任Leader已经commit的日志,那它是无论如何也不能做新的Leader的,因为这会导致数据的不一致。

安全性第一条限制 Candidate在拉票时需要携带自己本地已经持久化的最新的日志信息,等待投票的节点如果发现自己本地的日志信息比竞选的Candidate更新,则拒绝给他投票。

  1. 有可能即使多个超过半数的节点已经提交了日志,然后被其他新选的Leader覆盖日志。

安全性第二条限制 只允许Leader提交(commit)当前Term的日志。

成员变化

Raft将节点的增删抽象成配置的变更,当Leader收到配置变更的消息之后,它就将新的配置Cnew作为一个特殊的Raft Entry发送到其他的Follower上面,任何节点只要收到了这个Entry,就开始直接使用Cnew。当Cnew这个Log被 committed,那么这次配置变更就结束了。 值得注意的是:

  • 当Log里面有一个配置变更还没有被committed时,不允许接受新的配置变更请求,以防止脑裂情况的出现
  • 如果只有两个节点,需要移除一个节点,在Leader在发起命令之后,另一个节点挂了,这时候系统没法恢复了。
日志压缩

为了避免日志一直不断地增长,Raft使用了Snapshot机制,Snapshot之前地日志都可以丢弃。 Raft算法为了解决Snapshot地性能问题,给出了三个解决方案:

  1. 不要做太频繁,否则消耗磁盘带宽。
  2. 不要做的太不频繁,否则一旦节点重启需要回放大量日志,影响可用性。系统推荐当日志达到某个固定的大小做一次snapshot。
  3. 做一次snapshot可能耗时过长,会影响正常log entry的replicate。这个可以通过使用copy-on-write的技术来避免snapshot过程影响正常log entry的replicate。
简短地结束

这篇导读简单地概括了Raft算法,但是在Raft论文中更加详细地提到了性能优化、Raft正确性证明和选举地详细过程,甚至给出伪代码等等,同时TiDB、MongoDB等分布式数据库都采用了Raft算法,并且在此之上做了大量地优化,同样Raft算法也拥有了大量地开源实现库,具体地可以参考官网继续学习。

参考文章

https://raft.github.io/raft.pdf http://www.infoq.com/cn/articles/raft-paper https://www.jianshu.com/p/138b4d267084 https://www.jianshu.com/p/99562bfec5c2 https://zhuanlan.zhihu.com/p/27910576

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-09-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 鸿的学习笔记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 导论
  • 复制状态机(Replicated State Machine)
  • 问题分解
    • 领导选取
      • 日志复制
        • 安全
          • 成员变化
          • 日志压缩
          • 简短地结束
          • 参考文章
          相关产品与服务
          云数据库 MongoDB
          腾讯云数据库 MongoDB(TencentDB for MongoDB)是腾讯云基于全球广受欢迎的 MongoDB 打造的高性能 NoSQL 数据库,100%完全兼容 MongoDB 协议,支持跨文档事务,提供稳定丰富的监控管理,弹性可扩展、自动容灾,适用于文档型数据库场景,您无需自建灾备体系及控制管理系统。
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档