赞
踩
熟悉或了解分布性系统的开发者都知道一致性算法的重要性,Paxos一致性算法从90年提出到现在已经有二十几年了,而Paxos流程太过于繁杂,实现起来也比较复杂,可能也是以为过于复杂,现在我听说过比较出名使用到Paxos的也就只是Chubby、libpaxos,搜了下发现Keyspace、BerkeleyDB数据库中也使用了该算法作为数据的一致性同步,虽然现在很广泛使用的Zookeeper也是基于Paxos算法来实现,但是Zookeeper使用的ZAB(Zookeeper Atomic Broadcast)协议对Paxos进行了很多的改进与优化,算法复杂我想会是制约他发展的一个重要原因;说了这么多只是为了要引出本篇文章的主角Raft一致性算法,没错Raft就是在这个背景下诞生的,文章开头也说到了Paxos最大的问题就是复杂,Raft一致性算法就是比Paxos简单又能实现Paxos所解决的问题的一致性算法。
Raft是斯坦福的Diego Ongaro、John Ousterhout两个人以易懂(Understandability)为目标设计的一致性算法,在2013年发布了论文:《In Search of an Understandable Consensus Algorithm》。从2013年发布到现在不过只有两年,到现在已经有了十多种语言的Raft算法实现框架,较为出名的有etcd,Google的Kubernetes也是用了etcd作为它的服务发现框架;由此可见易懂性是多么的重要。
Raft概述
与Paxos不同,Raft强调的是易懂(Understandability),Raft和Paxos一样只要保证n/2+1节点正常就能够提供服务;众所周知但问题较为复杂时可以把问题分解为几个小问题来处理,Raft也使用了分而治之的思想把算法流程分为三个子问题:选举(Leader election)、日志复制(Log replication)、安全性(Safety)三个子问题;这里先简单介绍下Raft的流程。
Raft开始时在集群中选举出Leader负责日志复制的管理,Leader接受来自客户端的事务请求(日志),并将它们复制给集群的其他节点,然后负责通知集群中其他节点提交日志,Leader负责保证其他节点与他的日志同步,当Leader宕掉后集群其他节点会发起选举选出新的Leader。
Raft详解
1、角色
Raft把集群中的节点分为三种状态:Leader、Follower 、Candidate,理所当然每种状态负责的任务也是不一样的,Raft运行时提供服务的时候只存在Leader与Follower两种状态;
Leader(领导者):负责日志的同步管理,处理来自客户端的请求,与Follower保持着heartBeat的联系;
Follower(追随者):刚启动时所有节点为Follower状态,响应Leader的日志同步请求,响应Candidate的请求,把请求到Follower的事务转发给Leader;
Candidate(候选者):负责选举投票,Raft刚启动时由一个节点从Follower转为Candidate发起选举,选举出Leader后从Candidate转为Leader状态;
2、Term
在Raft中使用了一个可以理解为周期(第几届、任期)的概念,用Term作为一个周期,每个Term都是一个连续递增的编号,每一轮选举都是一个Term周期,在一个Term中只能产生一个Leader;先简单描述下Term的变化流程: Raft开始时所有Follower的Term为1,其中一个Follower逻辑时钟到期后转换为Candidate,Term加1,这时Term为2(任期),然后开始选举,这时候有几种情况会使Term发生改变:
1:如果当前Term为2的任期内没有选举出Leader或出现异常,则Term递增,开始新一任期选举
2:当这轮Term为2的周期选举出Leader后,过后Leader宕掉了,然后其他Follower转为Candidate,Term递增,开始新一任期选举
3:当Leader或Candidate发现自己的Term比别的Follower小时,Leader或Candidate将转为Follower,Term递增
4:当Follower的Term比别的Term小时,Follower也将更新Term保持与其他Follower一致;
可以说每次Term的递增都将发生新一轮的选举,Raft保证一个Term只有一个Leader,在Raft正常运转中所有的节点的Term都是一致的,如果节点不发生故障一个Term(任期)会一直保持下去,当某节点收到的请求中Term比当前Term小时则拒绝该请求;
3、选举(Election)
Raft的选举由定时器来触发,每个节点的选举定时器时间都是不一样的,开始时状态都为Follower,某个节点定时器触发选举后Term递增,状态由Follower转为Candidate,向其他节点发起RequestVote RPC请求,这时候有三种可能的情况发生:
1:该RequestVote请求接收到n/2+1(过半数)个节点的投票,从Candidate转为Leader,向其他节点发送heartBeat以保持Leader的正常运转
2:在此期间如果收到其他节点发送过来的AppendEntries RPC请求,如该节点的Term大则当前节点转为Follower,否则保持Candidate拒绝该请求
3:Election timeout发生则Term递增,重新发起选举
在一个Term期间每个节点只能投票一次,所以当有多个Candidate存在时就会出现每个Candidate发起的选举都存在接收到的投票数都不过半的问题,这时每个Candidate都将Term递增、重启定时器并重新发起选举,由于每个节点中定时器的时间都是随机的,所以就不会多次存在有多个Candidate同时发起投票的问题。
有这么几种情况会发起选举,1:Raft初次启动,不存在Leader,发起选举;2:Leader宕机或Follower没有接收到Leader的heartBeat,发生election timeout从而发起选举;
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。