0

0

源码解读etcd heartbeat,election timeout之间的拉锯

看不見的法師

看不見的法師

发布时间:2025-07-11 09:32:28

|

593人浏览过

|

来源于php中文网

原创

以下是你在知乎上的回答的伪原创版本,保持了原意和图片位置不变:


源码解读etcd heartbeat,election timeout之间的拉锯


答:准确来说:election是timeout,而heartbeat 是interval,这样理解起来就很清晰了。

heartbeat interval 是leader安抚follower的时间,这个时间间隔在leader上体现,是leader发送心跳的周期(我每xxxx ms 进行一次心跳)。

election timeout 是follower能够容忍多久没有收到心跳而开始骚动的时间(我等你xxxx ms,如果你没来,我就起义)。

为了压制follower随时起义的骚动,heartbeat interval 通常设置得小于 election timeout。

源码解读etcd heartbeat,election timeout之间的拉锯

楼主提到两个配置超时都会成为候选者,实际上,heartbeat interval/election timeout 是一个相互制约的拉锯。

想象一个刚初始化的集群,所有节点都是follower,没有heartbeat压制,各follower节点在election timeout之后开始骚动。如果一次选举周期内没有选出leader,很可能是由于选票分散,需要发起新的选举;为了缓解选票分散的情况,每个节点的election timeout骚动时间是随机的。在发生网络分区时,少数派分区的follower收不到leader的安抚,是不是又要起义,这个时候election timeout 也发挥了作用。我们结合etcd的默认配置和源码来理解:

目前etcd默认heartbeat = 100ms, election = 1000ms

https://www.php.cn/link/70a3e3e59bc61c8eb7acfbba1073980c

raft 为节点定义了以下状态:

const (
    StateFollower StateType = iota
    StateCandidate
    StateLeader
    StatePreCandidate
    numStates
)

becomeLeader 注册了定期发送心跳的动作 r.tick = r.tickHeartbeat ;

京点点
京点点

京东AIGC内容生成平台

下载

becomeFollower, becomeCandidate, becomePreCandidate 都注册了(没有收到安抚而)起义的动作 r.tick = r.tickElection ;

我们以follower节点为例:

func (r *raft) becomeFollower(term uint64, lead uint64) {
    r.step = stepFollower
    r.reset(term)
    r.tick = r.tickElection
    r.lead = lead
    r.state = StateFollower
    r.logger.Infof("%x became follower at term %d", r.id, r.Term)
}

r.reset(term)==> r.resetRandomizedElectionTimeout() 会接受传播过来的term,并计算随机选举超时时间。

func (r *raft) resetRandomizedElectionTimeout() {
    r.randomizedElectionTimeout = r.electionTimeout + globalRand.Intn(r.electionTimeout)
}

从上面的源码看出,etcd默认配置产生的节点随机超时时间是 [1000,2000]ms。

r.tickElection 会判断:如果当前经历的时间electionElapsed大于随机超时时间,就开始起义,并重置electionElapsed时间。

func (r *raft) tickElection() {
    r.electionElapsed++
    if r.promotable() && r.pastElectionTimeout() {
        r.electionElapsed = 0
        if err := r.Step(pb.Message{From: r.id, Type: pb.MsgHup}); err != nil {
            r.logger.Debugf("error occurred during election: %v", err)
        }
    }
}

func (r *raft) pastElectionTimeout() bool {
    return r.electionElapsed >= r.randomizedElectionTimeout
}

becomePreCandidate 没有r.reset(term)动作,这是一个预投票状态,也称prevote,这也是etcd的常见面试题。

prevote 是论文作者为了解决“分区后少数派leader重新加入集群,因为高term导致集群瞬间不稳定”而提出的方案,etcd 默认加入prevote机制:在成为真正意义的候选者之前不自增term,先预投票,因为其他节点一直收到心跳,并不会起义,故该节点预投票拿不到多数投票,等到该节点收到leader心跳,自行降为follower,term和Leader一致,现在这一机制已经插入到每次follower-->Candidate之间。

switch m.Type {
case pb.MsgHup:
    if r.preVote {
        r.hup(campaignPreElection)
    } else {
        r.hup(campaignElection)
    }
}

源码解读etcd heartbeat,election timeout之间的拉锯

Prevote是一个典型的2PC协议,第一阶段先征求其他节点是否同意选举,如果同意选举则发起真正的选举操作,否则降为Follower角色。这样就避免了网络分区节点重新加入集群,触发不必要的选举操作。

https://www.php.cn/link/14318e2a43a225fc24ab55f3c0122cf0https://www.php.cn/link/9154498493d8e734d9c7489c2b6b26d7

相关专题

更多
http与https有哪些区别
http与https有哪些区别

http与https的区别:1、协议安全性;2、连接方式;3、证书管理;4、连接状态;5、端口号;6、资源消耗;7、兼容性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

1980

2024.08.16

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

43

2026.01.16

全民K歌得高分教程大全
全民K歌得高分教程大全

本专题整合了全民K歌得高分技巧汇总,阅读专题下面的文章了解更多详细内容。

84

2026.01.16

C++ 单元测试与代码质量保障
C++ 单元测试与代码质量保障

本专题系统讲解 C++ 在单元测试与代码质量保障方面的实战方法,包括测试驱动开发理念、Google Test/Google Mock 的使用、测试用例设计、边界条件验证、持续集成中的自动化测试流程,以及常见代码质量问题的发现与修复。通过工程化示例,帮助开发者建立 可测试、可维护、高质量的 C++ 项目体系。

24

2026.01.16

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

35

2026.01.15

Java音频处理教程汇总
Java音频处理教程汇总

本专题整合了java音频处理教程大全,阅读专题下面的文章了解更多详细内容。

16

2026.01.15

windows查看wifi密码教程大全
windows查看wifi密码教程大全

本专题整合了windows查看wifi密码教程大全,阅读专题下面的文章了解更多详细内容。

56

2026.01.15

浏览器缓存清理方法汇总
浏览器缓存清理方法汇总

本专题整合了浏览器缓存清理教程汇总,阅读专题下面的文章了解更多详细内容。

16

2026.01.15

ps图片相关教程汇总
ps图片相关教程汇总

本专题整合了ps图片设置相关教程合集,阅读专题下面的文章了解更多详细内容。

9

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.7万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号