共识算法-raft

共识算法

Consensus algorithms allow a collection of machines to work as a coherent group that can survive the failures of some of its members.

  • 私链:传统分布式系统里的共识算法(相较于区块链这个概念),比如 zookeeper 的 zab 协议,paxos, raft。私链是不考虑集群中存在作恶节点,只考虑因为系统或者网络原因导致的故障节点。
  • 联盟链:需要考虑集群中存在故障节点,还需要考虑集群中存在作恶节点。对于联盟链,每个新加入的节点都是需要验证和审核的。比如 pbft 算法
  • 公链:需要考虑网络中存在故障节点,还需要考虑作恶节点,这一点和联盟链是类似的。和联盟链最大的区别就是,公链中的节点可以很自由的加入或者退出,不需要严格的验证和审核。比如pow.pos,dpos,ripple

raft和paxos

  • paxos是一类协议的统称
    • basic paxos
    • multi-paxos 强化了leader
  • raft 会有点像multi-paxos

raft 算法

两个paper

一些实现的开源项目,etcd, tidb/tikv, consul

算法概述

一个简单的raft算法的流程

Raft算法由leader节点来处理一致性问题。leader节点接收来自客户端的请求日志数据,然后同步到集群中其它节点进行复制,当日志已经同步到超过半数以上节点的时候,leader节点再通知集群中其它节点哪些日志已经被复制成功,可以提交到raft状态机中执行。

通过以上方式,Raft算法将要解决的一致性问题分为了以下几个子问题。

  • leader选举:集群中必须存在一个leader节点。
  • 日志复制:leader节点接收来自客户端的请求然后将这些请求序列化成日志数据再同步到集群中其它节点。
  • 安全性:如果某个节点已经将一条提交过的数据输入raft状态机执行了,那么其它节点不可能再将相同索引 的另一条日志数据输入到raft状态机中执行。
  • 成员变化(membership changes)

leader选举

节点刚启动,进入follower状态,同时创建一个超时时间在150-300毫秒之间的选举超时定时器。
follower状态节点主循环:
  如果收到leader节点心跳:
    心跳标志位置1
  如果选举超时到期:
    没有收到leader节点心跳:
      任期号term+1,换到candidate状态。
    如果收到leader节点心跳:
      心跳标志位置空
  如果收到选举消息:
    如果当前没有给任何节点投票过 或者 消息的任期号大于当前任期号:
      投票给该节点
    否则:
      拒绝投票给该节点
candidate状态节点主循环:
  向集群中其他节点发送RequestVote请求,请求中带上当前任期号term
  收到AppendEntries消息:
    如果该消息的任期号 >= 本节点任期号term:
      说明已经有leader,切换到follower状态
    否则:
      拒绝该消息
  收到其他节点应答RequestVote消息:
    如果数量超过集群半数以上,切换到leader状态
    
  如果选举超时到期:
    term+1,进行下一次的选举
复制代码

发起选举时,follower将递增它的任期号然后切换到candidate状态。然后通过向集群中其它节点发送RequestVote RPC请求来发起一次新的选举。一个节点将保持在该任期内的candidate状态下,直到以下情况之一发生。

该candidate节点赢得选举,即收到超过半数以上集群中其它节点的投票。 另一个节点成为了leader。 选举超时到来时没有任何一个节点成为leader。

日志复制

日志复制的流程大体如下:

每个客户端的请求都会被重定向发送给leader,这些请求最后都会被输入到raft算法状态机中去执行。
leader在收到这些请求之后,会首先在自己的日志中添加一条新的日志条目。
在本地添加完日志之后,leader将向集群中其他节点发送AppendEntries RPC请求同步这个日志条目,当这个日志条目被成功复制之后(什么是成功复制,下面会谈到),leader节点将会将这条日志输入到raft状态机中,然后应答客户端。

 committedIndex >= appliedIndex
复制代码

Raft算法保持着以下两个属性,这两个属性共同作用满足前面提到的日志匹配(LogMatch)属性:

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

安全性

  • 领导人完全原则:如果一个日志条目在一个给定任期内被提交,那么这个条目一定会出现在所有任期号更大的领导人中
  • broadcastTime << electionTimeout << MTBF

猜你喜欢

转载自blog.csdn.net/weixin_33725722/article/details/91384083