1、raft协议是什么? 分布式系统之于单机系统,优势之一就是有更好的容错性。
这是如何做到的?比较容易的一个想法就是备份(backup)。一个系统的工作模是:接受客户端的command,系统进行处理,将处理的结果返回给客户端。由此可见,系统里的数据可能会因为command而变化。 实现备份的做法之一就是复制状态机(Repilcated State Machine,RSM),它有一个很重要的性质——确定性(deterministic):
也就是说,如果我们能按顺序将command作用于状态机,它就可以产生相同的状态和相同的输出 那么一个状态机如何实现呢?如下图所示(来自raft协议):
上图中,每个RSM都有一个replicated log,存储的是来自客户端的commands。每个RSM中replicate log中commads的顺序都是相同的,状态机按顺序处理replicate log中的command,并将处理的结果返回给客户端。由于状态机具有确定性,因此每个状态机的输出和状态都是相同的。 上图中有一个模块——Consensus Module刚刚没有提及。这个模块用于保证每个server上Log的一致性!
因此,raft是一致性协议,是用来保障servers上副本一致性的一种算法。
2、raft协议原理 下面将看论文时我认为的重要点进行记录。 raft协议遵循的性质
2.1 如何保证Election Safty raft中,只要candidate获得多数投票,就可以成为领导人。follower在投票的时候遵循两个条件:
对于选举结果:
这里重要的一点是:如何保证在有限的时间内确定出一个候选人,而不会总是出现票被瓜分的情况?raft使用了一个比较优雅的实现方式,随机选举超时(randomize election timeouts)。这就使得每个server的timeout不一样,发起新一轮选举的时候,有些server还不是voter;或者一些符合条件的candidate还没有参加下一轮。这种做法使得单个leader会很快被选举出来。
2.2 如何保证Log Matching Leader在进行AppendEntry RPCs的时候,这个消息中会携带preLogIndex和preLogTerm这两个信息,follower收到消息的时候,首先判断它最新日志条目的index和term是否和rpc中的一样,如果一样,才会append. 这就保证了新加日志和其前一条日志一定是一样的。从第一条日志起就开始遵循这个原理,很自然地可以作出这样的推断。
2.3 如何保证Leader Completeness 这个在raft协议中是有完整证明的,这个证明比较简短,用反正法,我在看的时候加了一些标注。 假设leaderU是第一个没有包含leaderT中commitT点(T<U)
2.4 raft协议中有一个约定,不能提交之前任期内log entry作为commit点。这是为什么? 这个问题主要是raft协议中commiting entries from previous term部分看的时候有点困惑,开始误解成了这个约定是用来保证之前任期内已经被复制到大多数server却没有被提交的日志在新的仍期内不会被覆盖。 实际上,论文中的figrure8的过程是一个正确的过程。 在(c)中,index=2并没有被提交,在(d)中被复制了是一个正确的做法。论文想阐述的是:如果在(c)中,leader提交了这个之前任期内的entry,在(d)中依然会被覆盖,也就是说被commit的entry覆盖了,这是一个错误!因此约定“can not commit entries from previous term”
2.5 cluster membership changes 如果集群的配置发生了变化,例如,新加入几台server,挂掉几台server。这是会影响选举的。
raft的解决方法就是two phase approch,引入一个过度配置,称为共同一致状态。具体的做法和图示:
考虑上述过程:
2.6 log过长或日志回放时间过长怎么办? 此时就需要做log compaction raft采用的方法是写时复制的snapshot(写是复制在linux中可以通过fork来完成)
|
|
来自: comeon_000 > 《待分类》