源码解读etcd heartbeat,election timeout之间的拉锯
转一个我在知乎上回答的有关raft election timeout/ heartbeat interval 的回答吧。
答:准确来讲: election是timeout,而heartbeat 是interval, 这样就很容易理解了。
heartbeat interval 是leader 安抚folower的时间,这个时间间隔是体现在leader上,是leader发送心跳的周期 (我xxxx ms 来一次)。
election timeout 是follower能容忍多久没收到心跳开始骚动的时间 (我等你xxxx ms,没来我就起义)。
为压制follower随时起义的骚动,heartbeat timeout 一般小于 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://github.com/etcd-io/etcd/blob/5fd69102ce785136aeb3168c56adce7957b99e2d/raft/raft.go#L1718
raft 为节点定义了以下状态:
const (
StateFollower StateType = iota
StateCandidate
StateLeader
StatePreCandidate
numStates
)
becomeLeader 注册了定期发送心跳的动作 r.tick = r.tickHeartbeat ;
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 是论文作者为解决“分区少数派重新加入集群,因为高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之间的拉锯的更多相关文章
- etcd学习(6)-etcd实现raft源码解读
etcd中raft实现源码解读 前言 raft实现 看下etcd中的raftexample newRaftNode startRaft serveChannels 领导者选举 启动并初始化node节点 ...
- php-msf 源码解读【转】
php-msf: https://github.com/pinguo/php-msf 百度脑图 - php-msf 源码解读: http://naotu.baidu.com/file/cc7b5a49 ...
- Prometheus 源码解读(一)
Prometheus 源码解读(一) Prometheus 是云原生监控领域的事实标准,越来越来的开源项目开始支持 Prometheus 监控数据格式.从本篇开始,我将和大家一起阅读分析 Promet ...
- AFNetworking 3.0 源码解读 总结(干货)(上)
养成记笔记的习惯,对于一个软件工程师来说,我觉得很重要.记得在知乎上看到过一个问题,说是人类最大的缺点是什么?我个人觉得记忆算是一个缺点.它就像时间一样,会自己消散. 前言 终于写完了 AFNetwo ...
- AFNetworking 3.0 源码解读(五)之 AFURLSessionManager
本篇是AFNetworking 3.0 源码解读的第五篇了. AFNetworking 3.0 源码解读(一)之 AFNetworkReachabilityManager AFNetworking 3 ...
- YYModel 源码解读(二)之NSObject+YYModel.h (1)
本篇文章主要介绍 _YYModelPropertyMeta 前边的内容 首先先解释一下前边的辅助函数和枚举变量,在写一个功能的时候,这些辅助的东西可能不是一开始就能想出来的,应该是在后续的编码过程中 ...
- AFNetworking 3.0 源码解读 总结
终于写完了 AFNetworking 的源码解读.这一过程耗时数天.当我回过头又重头到尾的读了一篇,又有所收获.不禁让我想起了当初上学时的种种情景.我们应该对知识进行反复的记忆和理解.下边是我总结的 ...
- 线程本地变量ThreadLocal源码解读
一.ThreadLocal基础知识 原始线程现状: 按照传统经验,如果某个对象是非线程安全的,在多线程环境下,对对象的访问必须采用synchronized进行线程同步.但是Spring中的各种模板 ...
- 第二十三课:jQuery.event.add的原理以及源码解读
本课主要来讲解一下jQuery是如何实现它的事件系统的. 我们先来看一个问题: 如果有一个表格有100个tr元素,每个都要绑定mouseover/mouseout事件,改成事件代理的方式,可以节省99 ...
随机推荐
- html 不常用标签介绍
文本元素 <wbr> 如果单词太长,或者您担心浏览器会在错误的位置换行,那么您可以使用 <wbr> 元素来添加 Word Break Opportunity(单词换行时机).英 ...
- js和原生应用常用的数据交互方式
场景1 在原生app中经常会使用到H5页面,比如说电商中的活动页,一些电商中的详情页,等等...这些页面都有一个特点,那就是在未来修改的可能性,和一次性的几率特别的大.所以用H5的页面是最睿智的一种选 ...
- [FireshellCTF2020]ScreenShooter 1
此题关键在于理清逻辑,本地将url发送给服务器,服务器请求sereenshooter以后将结果返回 所以应该在服务器查看日志. 发现了PhantomJS 引擎一下 <!DOCTYPE html& ...
- Exception Handling Considered Harmful
异常处理被认为存在缺陷 Do, or do not. There is no try. - Yoda, The Empire Strikes Back (George Lucas) by Jason ...
- ffmpeg将视频生成gif
1.安装ffmpeg 2.cmd中输入 ffmpeg -i 0.mp4 -f gif 0.gif 即可将视频转为gif
- sequelize模型
model表示数据库中的表,有时它也会被称为"模型"或"工厂".Model不能通过构造函数创建,只能通过sequlize.define方法来定义或通过sequl ...
- java——封装
java--封装 java--封装1 封装的理解和好处2 封装的事项实现步骤3 将构造器和setXx结合4 this和super区分 1 封装的理解和好处 隐藏实现细节:[方法(连接数据库)<- ...
- 线性表(python实现)
线性表 1 定义 线性表是由 \(n(n>=0)\)个数据元素(节点)\(a1.a2.a3.-.an\) 成的有限序列.该序列中的所有节点都具有相同的数据类型.其中,数据元素的个数 \(n\) ...
- DFS与N皇后问题
DFS与N皇后问题 DFS 什么是DFS DFS是指深度优先遍历也叫深度优先搜索. 它是一种用来遍历或搜索树和图数据结构的算法 注:关于树的一些知识可以去看<树的概念及基本术语>这篇文章 ...
- 2021.11.09 P3426 [POI2005]SZA-Template(KMP+DP)
2021.11.09 P3426 [POI2005]SZA-Template(KMP+DP) https://www.luogu.com.cn/problem/P3426 题意: 你打算在纸上印一串字 ...