聊聊raft的一个实现(3)--commit

版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 前言 我在 聊聊raft的一个实现(2) 中的文末曾提到 只要client等到leader完成Commit动作。即使后续leader发生变更或部分节点崩溃,raft协议可以保证,client所提交的改动依然有效。 本文将举个例子,来说明一下。 2. 示例 如下图,假定cluster中有S1、S2、S3、S4、S5共5个节点,每个方格表示一条日志,方格中的数字是日志对应的term, 当前的leader是S1 commitIndex表示当前已经提交的日志,也就是成功同步到majority的日志位置(LogIndex)的最大值。 至少有3个node包含了LogIndex1、2、3,因此commitIndex的值是3 参看raft/server.go的processAppendEntriesResponse 函数了解commitIndex的计算方法 // Determine the committed index that a majority has. var indices []uint64 indices = append(indices, s.log.currentIndex()) for _, peer := range s.peers { indices = append(indices, peer.getPrevLogIndex()) } sort.Sort(sort.Reverse(uint64Slice(indices))) // We can commit up to the index which the majority of the members have appended. commitIndex := indices[s.QuorumSize()-1] committedIndex := s.log.commitIndex if commitIndex > committedIndex { // leader needs to do a fsync before committing log entries s.log.sync() s.log.setCommitIndex(commitIndex) s.debugln("commit index ", commitIndex) } 想象一个最糟糕的场景S1、S2,因为某种原因同时崩溃了。在goraft中,节点即使崩溃,也不会从peers中删除,也就是说cluster中节点的数目没有发生变化,要想保证剩下的节点能够正常选出leader,节点的数量不能少于3(集群节点总数/2 + 1)。 ...

December 1, 2018 · 1 min