前言

一个小而精致的Raft算法演示网站:Raft (thesecretlivesofdata.com)

Raft概念

Raft是工程上使用较为广泛的强一致性、去中心化、高可用的分布式协议。遵从此协议的分布式集群会对某个事情达成一致的看法,即使是在部分节点故障、网络延时、网络分割的情况下。

Raft基础

  • 一个Raft集群一般包含奇数个服务器node,通常是五个,这代表着整个系统容忍2个节点失效(2 * n + 1)代表总node数的话,n就代表能够容忍的最大宕机node数。
  • Raft是基于Paxos算法的,Raft拥有Paxos相同的功能,却拥有简单的理解难度和实用程度,Raft在同一个term当中只会存在一个leader,而Paxos可能存在多个leader。
  • Raft的过程都是在寻求集群中大多数服务器的同意,比如Leader Election,只要有半数以上的服务器同意一个服务器成为Leader,那么这个服务器就会晋升为Leader。再比如一个更新请求进入集群,只有当集群中半数及以上的服务器都能完成这个更新操作的时候才会返回操作成功。这也说明了为什么Raft集群总是要保持奇数个
  • election timeout:选举超时时间,表示到达改时间时,若还没有收到leader的消息,则可以晋升为candidate,准备开始进行leader election

Raft选举过程(Leader Election)

  1. Raft当中的角色:Follower、Candidate、Leader
  2. Leader选举过程:
    • 初始状态下,所有node都是follower,所有的follower都有一个election timeout,这个时间是一个介于150ms和300ms之间的一个随机数(默认时间是如此,可根据需求自行配置时间长短)。由于是随机数,大多数情况下,只会有一个follower最先达到election timeout,这时follower晋升为candidate,term也会递增(步数为1)
    • 晋升为candidate的node(该node会默认投给自己)会要求集群之中的其他node给自己投票以便成为leader,当该node的支持票数达到集群中node 的半数以上,该node就会从candidate晋升为leader
  3. Leader Election的一些细节:
    • 在同一个term之中,一个follower只会进行一次投票
    • 当follower收到了candidate的投票RPC时,会重置自己的election timeout
    • 即使没有数据交互,由于有heartbeat timeout的存在(即心跳检测机制,主要用于确认follwer是否存活),heartbeat timeout要比election timeout的时间间隔小得多,一个election timeout中可能存在多个heartbeat timeout
  4. 一些故障说明:
    • 当该term中的leader因为某些原因宕机时会发生什么?:集群中会有一个follower先达到 election timeout,晋升为candidate,重复上述leader election的过程。
    • 当有多个follower同时到达election timeout,并且他们的票数都一样会发生什么?:由于他们的票数都相同,肯定没有一个candidate的票数超过半数以上,因此他们都不能成为leader,只能等某一个node达到election timeout重新进行leader election。

Raft当中的Log replication

  1. log replication是WAL(Write-Ahead Logging)的一种体现,为了避免宕机带来的分布式状态丢失,Raft当中的所有更新操作都会先写进leader的log之后再进行操作,便于宕机之后的状态恢复。
  2. Raft当中的更新流程:
    • client将更新消息发送给leader,leader将该操作写进log
    • 尝试将该操作append集群中所有follower的log当中
    • 如果半数以上的follower都append成功,则会响应client,并commit该更新
    • 告诉所有follower,该更新请求已被提交,要求他们也同步log当中的修改
  3. 更新当中经典故障(network partition):
    • network partition状况简述:由于网络问题,将一个集群(总数为5个node)分为了A(3个node)、B(2个node)两个partition
    • 肯定会有一个部分没有leader,这时该部分会进行leader election,该集群中就存在了两个partition,A、B,他们拥有各自的leader、term(条件:原leader在B中,如果原leader在A中,则只有A中会有leader,B中由于node少于半数,leader election永远不会产生leader)
    • 不过这种情况并不用担心,因为在B中的更新请求永远不会commit,因为B中的主机数没有超过半数,不符合Raft当中所有操作都要有半数以上node同意的规定
    • 当网络重新恢复稳定时,由于A、B中都存在leader,不过A中term肯定比B中的term更高,B中的leader会自行降级为follower并同步A中leader的log