赞
踩
通过网络更新的概率性成功的,所以保证集群大多数达到一致就可以了。
一个节点可以有三种状态:
系统一启动,所有节点都是Follower节点。
如果一个Follower节点不能收到Leader的心跳信息,在election timeout
这么长的时间过后,就认为自己升级为Candidate节点。于是联系其他节点向他们拉票,节点收到拉票请求就会根据某些条件决定是否投给它。如果一个Candidate节点收到了系统内大多数节点的投票(2f+1中的f+1个),就晋升为集群leader。接下来的所有写请求都转发给Leader节点。这个过程称为选举过程(leader election)。
分布式系统有leader之后,所有的读写都通过leader节点进行。每次更改都会在leader节点日志(WAL , a.k.a Write-ahead log)中追加一项记录(entry)。现在这项记录是未提交的,还不能更新leader节点的值。为了提交,leader征得大家的同意,于是发出消息告诉大家自己要提交一项新的更改,当大多数节点投票同意,leader才将记录提交。
然后Leader通知其他节点一个事件,就是记录已提交。这个过程为日志复制过程(log replication)。
Raft里面有两个时间设置来控制leader选举过程。
第一个是election timeout(150-300 ms),这个变量是Follower(abbv F节点)节点变成Candidate节点的时长,一旦F节点收不到Leader信息,就设定一个定时器。如果这个时间内还没有收到leader的消息就自我提升为Candidate节点。
F节点在过了election timeout这么长时间后没有收到消息,就开始建立一个新的选举时期(term变量表示)。给自己拉票,收到拉票请求的节点查看自己所在的选举时期(自己所在的term<请求的term)比较老,如果在这个选举时期还没投票,就投它一票。投完后,收到拉票请求的节点知道新的Leader也早晚也会挂掉,于是重置自己的election timeout定时器。
C节点(Candidate节点)一旦其中一个收到了大多数票,就被选为Leader。Leader会周期性地(由heartbeat timeout设置)向全部节点发送心跳信息,这个信息被称为Append Entries
。其他节点收到心跳信息响应给Leader ACK。心跳信息包含一些更新(上一个周期到现在),同时心跳信息ACK会顺带把写成功确认发送回leader。
网络分区条件下,不包含Leader的区域A会重新开始一个新的选举时期,不包含Leader称为区域B。分两种情况:
此时,区域A是可以提交的,也就是可以继续往下执行。但是区域B,因为不能收到多数节点的确认导致事务无法提交。
待到网络恢复,区域B的所有节点观测到新的选举时期,自动回滚到上一个状态,接受新的更新。
区域A无法进行事务提交,一直停留在分区前的状态。区域B可以进行事务提交。
待到网络恢复,区域A可以像原来那样,接受新的更新(这里有可能落后多次更新,需要根据具体情况处理。比如set 的话,直接更新;递增的话,需要拉取更新记录)。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。