10

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

 4 years ago
source link: http://vearne.cc/archives/1510
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

版权声明 本站原创文章 由 萌叔 发表
转载请注明 萌叔 | http://vearne.cc

我在 聊聊raft的一个实现(2) 中的文末曾提到

只要client等到leader完成Commit动作。即使后续leader发生变更或部分节点崩溃,raft协议可以保证,client所提交的改动依然有效。

本文将举个例子,来说明一下。

如下图,假定cluster中有S1、S2、S3、S4、S5共5个节点,每个方格表示一条日志,方格中的数字是日志对应的term, 当前的leader是S1

image_1ctkv3tmtpi2jghjbf1uspjbp9.png-25.8kB

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)。

image_1ctkv3tmtpi2jghjbf1uspjbp9.png-25.8kB

这个时候,谁可能被选为leader, 注意:raft协议中这样的要求

candidate’s log is at least as up-to-date as receiver’s log then vote

解释起来,就是必须同时满足以下2个条件,才会给candidate投票

  • candidate.LastLogTerm >= receiver.LastLogTerm
  • candidate.LastLogIndex >= receiver.LastLogIndex

参看 raft/server.go processRequestVoteRequest 函数

    // If the candidate's log is not at least as up-to-date as our last log then don't vote.
    lastIndex, lastTerm := s.log.lastInfo()
    if lastIndex > req.LastLogIndex || lastTerm > req.LastLogTerm {
        s.debugln("server.deny.vote: cause out of date log: ", req.CandidateName,
            "Index :[", lastIndex, "]", " [", req.LastLogIndex, "]",
            "Term :[", lastTerm, "]", " [", req.LastLogTerm, "]")
        return newRequestVoteResponse(s.currentTerm, false), false
    }
node LastLogTerm LastLogIndex S3 1 3 S4 1 2 S5 1 1

从上表可知,只有S3能够当选为leader, S3包含了LogIndex为3的日志,那么后续在S3的任期内,此条日志会被S3分发给S4和S5。
只要leader完成Commit动作,即使后续leader发生变更或部分节点崩溃,client所提交的改动依然有效,这个结论是正确的。

image_1ctl4lpa11ch81t3q1nus1ohn1gd69.png-229.8kB

如果我的文章对你有帮助,你可以给我打赏以促使我拿出更多的时间和精力来分享我的经验和思考总结。

微信支付码

Recommend

  • 83
    • zhuanlan.zhihu.com 7 years ago
    • Cache

    Elasticell-Multi-Raft实现

    Elasticell-Multi-Raft实现fagongziElasticell, Gateway项目作者

  • 72
    • www.opscoder.info 7 years ago
    • Cache

    etcd中的raft实现 | jasper的blog

    在之前的一篇文章中我们了解了怎么使用ectd的raft的库来实现一个简单的分布式存储,但是只看了应用端对raft的调用以及周边,但是对于raft的库的内部没有做涉及,那么这篇文章我们就深入到raft内部看看其实现的细节。

  • 31
    • 微信 mp.weixin.qq.com 5 years ago
    • Cache

    Go实现Raft第一篇:介绍

    女主宣言 今天小编为大家分享一篇关于Golang实现Raft的文章,本篇文章为系列中的第一篇,对Raft进行一个全面的介绍,为后面进行Raft的实现打基础。希望能对大家有所帮助。 PS:丰富的一线技术、多元化的表...

  • 27
    • www.ideawu.net 5 years ago
    • Cache

    Raft Read Index 的实现

    首先, 获取"集群"的 ReadIndex. 注意, 不是某个节点上面的某个状态, 而集群的多个节点共同确定的一个变量. 这个变量如何获取, 下面说明. func GetClusterReadIndex(){ foreach(peers as peer){ i = peer.rpc_GetLast...

  • 11
    • www.zenlife.tk 4 years ago
    • Cache

    raft实现如何做测试

    2016-04-15对于一个采用raft协议的分布式系统,raft实现的正确性至关重要。怎么保证raft实现出来是没问题的?要有的严格测试!对于一个稳定可靠的raft实现,用于测试的代码量应该是高于实现本身的,这可以作为开源实现选型时的参考依据。那么,假...

  • 12

    版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 在我的上一篇文章聊聊Raft的一个实现(1),我简要的介绍了 goraf...

  • 13

    聊聊Raft的一个实现(1)–goraft 版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 最近花了不少时间来学习raft相关的知识,写这篇文章的目的 ...

  • 7
    • www.codedump.info 3 years ago
    • Cache

    Etcd Raft库的工程化实现

    Etcd Raft库的工程化实现 2021-05-15 分布式 ...

  • 10
    • vearne.cc 3 years ago
    • Cache

    聊聊Raft协议

    版权声明 本站原创文章 由 萌叔 发表 转载请注明 萌叔 | http://vearne.cc 1. 参考资料 The original project authors have created new raft implementations now used in etcd and InfluxDB.

  • 5

    一个基于GPT模型实现的Git Commit信息自动生成工具

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK