1.raft功能结构
raft将集群中的机器用三种状态进行标示,leader、follower、candidate。是不是和paxos的proposer、acceptor、learner模型很像?不过这两个还是有很大的区别的。
raft明确了集群的功能+集群的实现细节。所有角色都可以接收用户请求,但是leader对所有的读写请求负责,也就是说,只有leader对最终的读写有解释权。通过这可以了解到,raft承担的是强一致性场景,其读和写其实是差不多的过程,不会存在读比写快。那么follower如果接收到请求会会怎么办呢?会进行请求转发,这样会多增加一些rpc的请求。
raft集群将工作状态分成两种,一种是日志复制,另一种是领导选举。其中领导选举是一种不稳定的状态,在这种不稳定的状态中,会出现数据安全、成员状态变更等问题,这些问题最直接的会影响到集群一致性问题,其复杂性较高,下面会单独讲解。另外一种日志复制是一种稳定状态,在leader确定的情况下,leader指导所有机器按规定来完成数据的读写要求,其中规定包括如下
- 所有请求需要经过leader才能完成,包括读写
- 集群成员需要全部同意某个数据的写入后,才能完成数据的写入。
- 使用2PC模式进行数据写入。
上面的规定比较严格,集群读写压力就很慢,严重影响了集群的可用性。于是对于写入采用了半数约定,约定集群中超过一半的机器同意某个写入后,数据就可以写入。至于读的优化,稍微复杂一点,我们同样单独讲解。
2.raft重要数据结构
type raft struct {
id uint64
Term uint64
Vote uint64
readStates []ReadState
// the log
raftLog *raftLog
maxMsgSize uint64
maxUncommittedSize uint64
// TODO(tbg): rename to trk.
prs tracker.ProgressTracker
state StateType
// isLearner is true if the local raft node is a learner.
isLearner bool
msgs []pb.Message
// the leader id
lead uint64
// leadTransferee is id of the leader transfer target when its value is not zero.
// Follow the procedure defined in raft thesis 3.10.
leadTransferee