基于Raft分布式Kv存储:leaderHeartBeatTicker

发布时间:2026/7/29 6:38:42

基于Raft分布式Kv存储:leaderHeartBeatTicker
源码里的准确名字是leaderHearBeatTicker()。它是Leader 的周期性调度器控制什么时候启动下一轮心跳或日志复制真正构造AppendEntries、发送快照和处理各节点复制进度的是doHeartBeat()。Raft 要求 Leader 定期向所有 Follower 发送AppendEntries没有新日志时它就是空心跳用来防止 Follower 选举超时。整体结构源码可以简化成void Raft::leaderHearBeatTicker() { while (true) { while (m_status ! Leader) { sleep(HeartBeatTimeout); } lock(); wakeTime now(); remaining HeartBeatTimeout m_lastResetHearBeatTime - wakeTime; unlock(); if (remaining 1ms) { sleep(remaining); } if (heartbeat_was_reset_after(wakeTime)) { continue; } doHeartBeat(); } }项目将心跳间隔配置为25ms选举超时随机范围配置为300500ms。也就是说在正常情况下一个选举超时区间内大约有 1220 次心跳机会。一、最外层无限循环while (true)Ticker 与 Raft 节点生命周期一致。它不会完成一次心跳就退出而是永久执行等待成为 Leader → 等到下一次心跳截止时间 → 调用 doHeartBeat → 重新计算下一次截止时间节点可能经历Follower → Candidate → Leader → Follower → Leader所以 Ticker 不能只在第一次成为 Leader 时运行一次。二、非 Leader 时轮询等待while (m_status ! Leader) { usleep(1000 * HeartBeatTimeout); }Follower 和 Candidate 不应该主动发送 Leader 心跳因此代码每隔25ms检查一次角色。这里的换算是HeartBeatTimeout 25ms usleep 参数单位 微秒 1000 × 25 25000μs 25ms如果节点一直是 Follower这个循环会一直执行当sendRequestVote()获得多数票并把状态改为 Leader内部循环结束。这是一种简单的轮询设计。代价是非 Leader 节点仍然每25ms醒来一次更合适的工程实现通常会用条件变量在角色变成 Leader 时主动唤醒 Ticker。三、为什么不直接睡固定 25ms代码没有简单地写sleep(25ms); doHeartBeat();而是计算suitableSleepTime milliseconds(HeartBeatTimeout) m_lastResetHearBeatTime - wakeTime;把它重新排列下一次截止时间 上次心跳时间 心跳间隔 还需等待时间 下一次截止时间 - 当前时间即deadline lastReset 25ms remaining deadline - now这样心跳周期以“上次实际触发心跳的时间”为基准不会简单地从 Ticker 本轮开始时间重新计算。四、 正常时间示例假设上次心跳时间1000ms 心跳间隔 25ms 当前时间 1010ms计算得到截止时间 1000 25 1025ms 剩余时间 1025 - 1010 15msTicker 再睡15ms然后在约1025ms调用doHeartBeat();doHeartBeat()完成一轮请求构造和分发后会执行m_lastResetHearBeatTime now();下一轮继续以这个新时间为起点。五、 Ticker 已经晚了怎么办假设上次心跳时间1000ms 心跳截止时间1025ms 当前时间 1032ms此时remaining 25 1000 - 1032 -7ms代码只有在剩余时间大于约1ms时才睡眠因此这里不再等待直接调用doHeartBeat()。这可以处理线程调度延迟 互斥锁竞争 进程短暂停顿 前面的代码执行过久但它不会补发错过的每一次心跳。例如错过了三个周期也只会立即发送一轮然后从新的发送时间重新计时。六、wakeTime的作用wakeTime是本轮计算开始时的时间快照wakeTime now();Ticker 睡眠期间另一个路径可能已经调用了doHeartBeat()。例如Candidate 刚获得多数票 → sendRequestVote 将它改为 Leader → 启动线程立即调用 doHeartBeat与此同时leaderHearBeatTicker()也可能发现节点已经成为 Leader并开始计时。如果另一个线程先发送心跳它会更新m_lastResetHearBeatTimeTicker 睡醒后检查m_lastResetHearBeatTime wakeTime如果成立表示从我开始本轮等待之后其他线程已经发送过一轮心跳。于是执行continue;重新根据最新心跳时间计算而不是紧接着再发送一轮重复心跳。七、 为什么叫“重置心跳计时器”这里并没有真正的系统 Timer 对象所谓“重置”只是更新时间戳m_lastResetHearBeatTime now();Ticker 每次根据这个时间戳计算截止时间因此修改时间戳就等价于重新启动定时器旧截止时间 旧 lastReset 25ms 新截止时间 新 lastReset 25ms这个设计和electionTimeOutTicker()很相似只是选举超时300500ms每轮随机 心跳间隔固定25ms八、doHeartBeat()会再次检查角色Ticker 在等待期间Leader 可能收到更高任期的响应并退回 Follower。可能出现Ticker 看到 status Leader → 开始睡眠 → 收到更高任期消息变成 Follower → Ticker 睡醒 → 调用 doHeartBeatdoHeartBeat()自己会持锁并再次判断if (m_status Leader) { // 才真正发送 }因此即使 Ticker 的角色判断已经过期也不会以 Follower 身份构造 Leader RPC九、 Ticker 触发的不只是空心跳leaderHearBeatTicker()名字容易让人误以为它只发送空包。实际上它调用的doHeartBeat()是整个复制调度入口。对每个 FollowernextIndex lastSnapshotIncludeIndex → leaderSendSnapShot() → InstallSnapshot RPC nextIndex lastSnapshotIncludeIndex → sendAppendEntries() → AppendEntries RPC而AppendEntries中entries 为空 → 纯心跳 entries 不为空 → 日志复制所以这个 Ticker 同时驱动维持 Leader 权威 阻止 Follower 超时 复制新日志 修复日志冲突 推进 commitIndex 向严重落后的节点发送快照十、时间从“发送”还是“回复”开始计算源码在doHeartBeat()创建完各个发送线程之后就更新m_lastResetHearBeatTime now();它不会等待所有 Follower 回复。因此心跳周期是本轮 RPC 开始分发 → 等待25ms → 下一轮 RPC 开始分发而不是本轮所有RPC完成 → 等待25ms → 下一轮开始这能避免一个慢 Follower 拖延其他节点的心跳但也意味着 RPC 如果超过25ms同一个 Follower 可能同时存在多轮尚未完成的AppendEntries。源码通过任期检查和max(matchIndex, ...)部分抵抗乱序回复但旧失败响应仍可能让nextIndex回退工程上更适合为每个 Follower 设置独立复制任务保证单节点方向上的 RPC 串行化。(raw.githubusercontent.com)

相关新闻

Selenium Actions类实战:模拟Shift多选、拖拽与右键菜单的复杂交互链

Selenium Actions类实战:模拟Shift多选、拖拽与右键菜单的复杂交互链

2026/7/29 6:28:41

1. 项目概述:为什么需要复杂的交互链?在自动化测试或者网页数据抓取的过程中,我们经常会遇到一些“刁钻”的交互场景。比如,在一个文件管理器的Web界面里,你想用脚本模拟用户按住Shift键连续选中多个文件,然…

C语言预编译深度解析:从宏定义到条件编译的实战指南

C语言预编译深度解析:从宏定义到条件编译的实战指南

2026/7/29 6:28:41

1. 项目概述&#xff1a;为什么预编译是C语言的“幕后功臣”&#xff1f;如果你写过C语言&#xff0c;一定用过#include <stdio.h>或者#define PI 3.14159这样的语句。但你是否想过&#xff0c;在你按下编译按钮到生成可执行文件之间&#xff0c;编译器到底对你的代码做了…

微软GUI框架演进史:从Win32到WinUI 3的技术变迁

微软GUI框架演进史:从Win32到WinUI 3的技术变迁

2026/7/29 6:28:41

1. 微软GUI框架三十年演进脉络 微软图形用户界面(GUI)框架的发展历程堪称一部技术迭代与战略博弈的编年史。从1990年代的Win32 API到如今的WinUI 3&#xff0c;每个关键转折点都折射出技术路线之争与组织架构调整的深层影响。作为亲历多个技术周期的开发者&#xff0c;我认为这…

计算机毕业设计之基于SpringBoot的电动车辆充电桩管理系统

计算机毕业设计之基于SpringBoot的电动车辆充电桩管理系统

2026/7/29 7:28:48

随着新世纪无纸化办公方式的普及&#xff0c;自动化信息处理和基于网络的信息交互方式已被广泛应用。现在很多行业基本上都是交由计算机进行管理和测试&#xff0c;网络与计算机已成为整个线上管理体系中的重要组成部分。虽然信息技术广泛应用和数据存取更加方便&#xff0c;但…

树莓派5本地部署大语言模型:从量化到RAG的完整实践指南

树莓派5本地部署大语言模型:从量化到RAG的完整实践指南

2026/7/29 7:28:48

1. 项目概述&#xff1a;为什么要在树莓派5上折腾大语言模型&#xff1f;最近拿到树莓派5&#xff0c;看着它那小巧的身板和宣称的性能提升&#xff0c;我就在琢磨&#xff0c;除了当个家庭服务器、跑跑Home Assistant&#xff0c;它还能干点啥更“硬核”的活儿&#xff1f;正好…

基于Intel Edison的激光雕刻机控制系统:从矢量图形到实时运动控制

基于Intel Edison的激光雕刻机控制系统:从矢量图形到实时运动控制

2026/7/29 7:28:48

1. 项目缘起&#xff1a;从“玩具”到“生产力工具”的蜕变几年前&#xff0c;Intel Edison这块开发板刚出来的时候&#xff0c;我第一时间就入手了。当时觉得它集成了Atom处理器、Wi-Fi/蓝牙、GPIO&#xff0c;还有Arduino兼容的扩展板&#xff0c;简直就是创客神器。但说实话…

社区问答版块规定设计:从规则制定到高效互动的完整指南

社区问答版块规定设计:从规则制定到高效互动的完整指南

2026/7/29 7:28:48

1. 项目概述&#xff1a;为什么我们需要“版块规定”&#xff1f;在任何一个线上社区、论坛或者内容平台&#xff0c;无论是技术交流、兴趣分享还是行业讨论&#xff0c;你总会发现一个看似不起眼却又至关重要的存在——版块规定。它可能被叫做“版规”、“社区公约”或者“发帖…

C++字符串替换:从基础实现到性能优化的完整指南

C++字符串替换:从基础实现到性能优化的完整指南

2026/7/29 7:28:48

1. 项目概述&#xff1a;为什么字符串替换是C程序员的基本功“C实现字符串替换”&#xff0c;这个标题看起来平平无奇&#xff0c;甚至有点教科书习题的味道。但在我十多年的C开发经历里&#xff0c;从处理简单的配置文件到解析复杂的网络协议&#xff0c;从清洗用户输入到生成…

在信息洪流中修筑巴别塔:WaytoAGI与千万人的“通往通用人工智能之路”

在信息洪流中修筑巴别塔:WaytoAGI与千万人的“通往通用人工智能之路”

2026/7/29 7:18:47

一、 序言&#xff1a;当AI每天刷新世界&#xff0c;我们该如何自处&#xff1f; 2023年至今&#xff0c;人工智能的演进速度快得令人窒息。从GPT-4的横空出世到Sora的惊艳亮相&#xff0c;从Claude的深思熟虑到国产大模型的通义千问、智谱GLM、豆包的百花齐放&#xff0c;我们…

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

[具身智能-649]:个人电脑搭建 RTSP 服务完整方案(Windows / Ubuntu 双平台,适配 RDK X5 rtsp2display 调试)

2026/7/28 13:30:18

目标&#xff1a;电脑作为RTSP 服务端&#xff0c;循环推送 H264/H265 视频流&#xff1b; RDK X5 通过 rtsp2display 拉流预览&#xff0c;完全不需要在开发板编译 live555。 提供两套成熟方案&#xff1a; ✅ 方案 A&#xff1a;FFmpeg&#xff08;最简单&#xff0c;优先推…

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

PDF合并与动态水印的工程化方案:2026国内免费工具实测对比

2026/7/28 16:04:36

一、背景与测试方案 在实际项目交付中&#xff0c;PDF文件合并与版权保护水印的叠加是一个高频但容易被低估的技术需求。典型的处理链路涉及&#xff1a;多源PDF的文件流合并、页面级水印渲染&#xff08;含透明度混合与图层叠加&#xff09;、输出文件体积控制。看似简单的操作…

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

PDF拆分压完图糊了?2026国内免费实测,档案员都在用的组合方案

2026/7/28 16:04:35

说实话&#xff0c;提到PDF拆分再压缩&#xff0c;我真是被折腾得够呛。 上个月公司年度合同归档&#xff0c;一份300多页的PDF总合同&#xff0c;需要按年份拆分成三个独立文件&#xff0c;再分别压缩到10MB以内方便邮件发送各部门确认。我心想这还不简单&#xff1f;先找个海…

AI会议纪要怎么做?会议录音转文字加自动整理,三个月实测流程

AI会议纪要怎么做?会议录音转文字加自动整理,三个月实测流程

2026/7/29 0:08:23

打工人总是跑不掉要写会议纪要。 我在一家互联网公司&#xff0c;一周至少八场会&#xff1a;产品评审、数据复盘、项目同步、客户沟通&#xff0c;每场一小时起步。 以前的标准流程是开会拼命记→会后凭记忆补→整理成文档发群&#xff0c;结果经常记不全、记错、记串。 大概年…

重庆化龙桥老旧小区改造,怎么搞定夜景照明“不扰居”又能省成本?

重庆化龙桥老旧小区改造,怎么搞定夜景照明“不扰居”又能省成本?

2026/7/29 0:08:23

重庆化龙桥靠着嘉陵江&#xff0c;老小区多&#xff0c;最近几年城市更新做的勤&#xff0c;不少住户都反映过小区夜景亮了是好事&#xff0c;可有的灯太晃眼&#xff0c;半夜拉着窗帘都透光&#xff0c;睡不好觉。还有物业算账&#xff0c;这灯开一整晚&#xff0c;公摊电费蹭…

目标模糊、资源泛滥、进度失控,AI学习计划制定失败的3大隐形陷阱及救急方案

目标模糊、资源泛滥、进度失控,AI学习计划制定失败的3大隐形陷阱及救急方案

2026/7/29 0:08:23

更多请点击&#xff1a; https://codechina.net 第一章&#xff1a;目标模糊、资源泛滥、进度失控&#xff0c;AI学习计划制定失败的3大隐形陷阱及救急方案 目标模糊&#xff1a;学得越勤&#xff0c;离真实能力越远 当学习目标停留在“学会AI”或“搞懂大模型”这类宽泛表述…