[9][lecture] Lecture 5: Raft (1)

6.824 2017 Lecture 5: Raft (1)

第一部分,介绍raft选举和log复制技术,相关的lab是lab2A 2B;第二部分设计,raft持久化,client行为以及快照技术,涉及lab 2C和lab 3

  • 目前为止,讨论的技术主要是使用RSM技术做容错,比如configure server,gfs master或者mapreduce主节点,要达到的效果就是复制集对于client的表现和单点server一致,且具备容错性,挂少数的server依旧可用,策略就是复制,复制log同样的顺序执行,gfs和vmft都是这个套路
  • 如何避免脑裂?集群分裂为AB,client连接到A,那么B挂了,A一定要可用;B没挂,那么要么A可用要么B可用,不能都可用
  • 主要问题是无法区别crash或者网络不可达
  • 我们需要RSM具备以下特性:第一,少数挂掉依旧可用;第二,处理网络分区问题避免脑裂;第三,多数挂掉,修复后依旧可用
  • 多数投票制度可以避免分区,防止脑裂,1990s主要技术就是paxos和view-timestamped replication技术,两者都在工业系统中得到实践;raft提出的比较晚

raft overview

lab 3 system,multi-clients,3 replicas,k/v layer,raft layer,logs

  • server’s raft layer选主
  • client发送rpc请求到主节点,put,get,append
  • k/v layer将请求转发到raft layer,此时不返回client,raft复制log到复制集节点,多数完成复制后,主节点commit,确保这个command已经持久化且达到了一致性要求,此时server apply这个command到到k/v state machine,其他节点通过心跳得到commit信息,本地执行,主节点在commit之后返回到KV layer,KV layer执行命令到db,返回给client
  • 为何选取log技术?命令单身不够吗,要加入term信息,index信息,保证复制集之间达成一致,同时做写前日志使用,未完成commit时,持久化供后续commit

lab 2A 选主

leader简化了复制过程;raft中使用term代表逻辑时间序列,每个term一个主或者没有主,不会有2个主;每次选举有一个唯一的term,term帮助区分哪些节点比较新

  • 发起选举的时机?followers timeout没收到心跳信息,发起选举;候选者 timeout发起新一轮选举
  • 成为候选人后的具体操作?首先,获取多数票,成为leader,本地统计投票(对拜占庭问题无法解决);然后,对于没有得到多数票的场景,如果其他选主成功,成功追随者;如果没有选出主来,等待timeout继续下一轮选举,选举过程中要保证主节点日志最新,保证了不丢失数据
  • 如何保证只有一个主?多数票决定,且每个term每个节点只能一次投票
  • 成为新主后的操作?发送心跳,防止下一轮选举发生
  • 选举失败可能的原因?没有足够的节点,分票
  • 选举失败后面?继续选,直到成功为止
  • 如何设计超时时间?随机超时设计,防止分票,不能太大防止长时间无主,不能太小,会造成分票选举失败;最少需要几倍的rpc执行时间,允许几次重试

lab 2B log复制

区别replicated log vs commited log,提交的log保证永远不会丢失,复制的但是没提交的log可能被覆盖。

  • commit机制保证了,server只会执行稳定的log entry,即commit过的,commit过的意味着在当前term保证了多数节点复制成功
  • leader无法复制上一任期的log entry,如果它没有commit,依旧会丢失
  • 主节点覆盖log的时机?log务必是没有提交过的;过世的log会被主节点发来的消息覆盖掉

接口rf.Start(command) (index, term, isleader)

  • kv service中put和get请求执行start,来就一个log entry达成共识,start立即返回,此时kv应等待commit返回的isLeader告诉是否要请求其他节点,term帮助确认当前主节点是否过期,index帮助确定是否已提交

接口ApplyMsg, with Index and Command

  • Raft发送消息到applychannel,对于每条commit过的entry,此时等待的kv会开始真正执行command

raft FAQ

Q: raft为了简单牺牲了什么?

A: 主要牺牲了性能;比如每个op需要单独落盘保证一致性,如果可以batch会提升性能;第二,appendentry只能从主到从,且in-order,out-order就需要反复重试,可以流水线最好;第三,快照机制对于小的状态可以,对于大的状态不可用;第四,恢复回放对于大的状态也比较慢,完整的发送快照;第五,多核利用性不好,每次只能执行一个操作按照in log order TODO why;上述都可以通过修改基本协议来改进

Q: paxos?

A: paxos基本协议解决的问题是多个角色就一个值达成一致,因此需要额外的补充实现,持久化等等,已经基于paxos实践的系统,chubby,zookeeper,paxos made live,具体的实现都很复杂,不容易理解。raft容易理解,但是要实际使用还需要一些改进,来达到理想的性能。paxos 1980s,raft 2012,raft和view timestamp类似,后者在1988s提出。基于raft的系统变得多了起来,包括etcd,tikv,rethinkDB,CockroachDB等等

Q: raft性能如何?

A: paxos变种zab很快,不过最新的改进版本raft在etcd3中显示已经优化的更快了

Q: 少数节点存在下,是否可以保证可用性?

A: 取决于一致性要求,raft是强一致性的系统,因此不行。如果放宽一致性要求,可以实现,比如最终一致性。主要解决的问题是脑裂,主要方案有两种。第一,明确少数节点活着,多数节点挂掉了,需要人为介入,因为机器无法区别挂了还是网络中断了;第二,允许双写,稍后来处理冲突,一些nosql场景下可以大幅度提高性能,保障最终一致性。

Q: 选举过程中服务是halt住的?

A: 是的,不过实际中选举很短,发生频率也很低,影响较小

Q: 是否介意不通过选举完成一致性?

A: 可以,paxos就是如此,但是需要更多的通信达成共识

Q: raft vs vmft

A: vmft更广泛,raft只能对那些基于此协议的软件生效,但是raft会更加高效

Q: fake 消息?

A: 一般来说,raft相信节点都是可靠度的,可以部署在内网环境;如果要公网部署,则可以每个节点配置公私钥对,加密所有rpc请求完成认证操作。

Q: 如何使用raft接口?

A: 比如lab3,get put请求首先调用Start,然后读applychann得知是否commit,完成后续操作返回client

Q: 超时时间设置多少合适?

A: 太短,还没选举完成就超时了,频繁超时有负担;太长,浪费了不可用时间

Q: 主节点不挂也会切主吗?

A: 可能的,网络分区也会导致切主

Q: 主节点发送rpc后应该阻塞等待吗?

A: 绝不,发起新的go完成发送,同时原子更新返回的个数,达到多数时可以commit

reference

  • paxos-simple
  • docker-raft
  • etcd-raft
  • proof-raft1
  • proof-raft2

你可能感兴趣的:(分布式)