李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 每日心情
  • Now
  • 系列文章
  • 论坛
  • 左邻右舍
    • 左邻右舍
    • 博友圈
  • 留言
    • 留言
    • 走心评论
  • 关于
    • 关于本站
    • 网站地图
    • 网站统计
    • 另一个网站
    • 我的导航站
    • 赞助
  • 🚇开往
!Destiny
惟坚韧者始能遂其志
  1. 首页
  2. 转载
  3. 正文

为什么同样是分布式架构的Kafka需要Leader而Redis不需要?

2021年3月22日 约 2,122 字8 分钟 128 0 0
本文最后更新于 2021年3月22日,距今已 2002 天,其中的信息可能已经发生变化,请注意甄别。

Redis不需要Leader这个观点其实有歧义,是不准确的,题目的问题本质其实是涉及数据分片、数据复制一致性。

1、Redis Cluster 架构
在Redis3.0版本开始,Redis引入了一种去中心化的集群架构,采用预分片的模式,一个集群中所有节点总共对应16384个槽位,在对一个key进行写入时,首先对key取hashcode,然后求模来映射到具体的某一个节点,其部署架构如下图所示:

自动草稿

上述每一个节点中存储的数据都不一样,即每一个节点存储整体数据的一部分,并且为了实现去中心化每一个节点需要存储集群中所有key所对应存档的节点信息(即Key的路由信息),这样当客户端将查询key1的请求发送到redisA节点,但该key1实际存储在redisB节点,此时A节点需将该节点路由到实际存储该key的节点,内部实现一个重定向,从而实现访问任意一个节点都能查询到存储的值。

在上述架构中是不需要存在Leader的,这也是所谓的集群去中心化设计思想的关键,但问题来了,如果集群中任意一个节点宕机不可用,存储在该节点中的数据就会丢失,为了解决这个问题,通常会引入主从架构,架构图如下所示:

自动草稿

具体的做法是为每一个主节点引入一个或多个从节点,用来拷贝主节点的数据,上图中的每一个虚线框表示一个复制组,也称之为副本,副本之间的数据期望完全一致。

在主从架构中如何保证数据一致性呢?通常主从集群与客户端之间的交互方式有如下几种:

客户端发送写请求到Master,在Master节点写入成功就返回给客户端,同时从节点异步复制数据,主从存在延迟,并且当主节点宕机存在丢数据的风险。
客户端发送写请求到Master,Master节点写入成功后,需要等待从从节点同样写入成功后才会向客户端返回成功,该方式会增大延迟,增加主从数据延迟,但还是无法避免主从数据不一致。
上述两种情况,都无法确保数据在主从两个节点上的一致性。

为什么同步双写也无法保证数据的一致性呢?

自动草稿

客户端只有在master,slave同步写入成功后才会收到响应,乍一看,能提供一致性,其实不然,试想一下,例如将key1的数据先写入到Master节点,在写入从节点的过程中出现错误,客户端会收到写入失败,但此时去往master中查询key1的数据,却能查询出上一次请求失败的数据,即客户端虽然收到了写入失败,但主节点却写入成功,造成了数据语义上的不一致性。

即主从同步这种架构,主从节点、客户端的确认机制存在天然的不足,为了解决该问题,Raft等分布式副本数据强一致性协议就闪亮登场了。

2、副本之间强一致性协议
为了解决数据的高可用性,避免单点故障,通常会将数据同步为多份,高可用性是解决了,但带来了另外一个问题,多个副本数据之间如何保证一致性,为了解决该问题出现了诸如 raft、paxos等一致性协议。

Raft协议的数据复制说明图如下:

自动草稿

图中客户端向Raft协议集群发起一个写请求,集群中的 Leader 节点来处理写请求,首先数据先存入 Leader 节点,然后需要广播给它的所有从节点,从节点接收到 Leader 节点的数据推送对数据进行存储,然后向主节点汇报存储的结果,Leader 节点会对该日志的存储结果进行仲裁,如果超过集群数量的一半都成功存储了该数据,主节点则向客户端返回写入成功,否则向客户端写入写入失败。

并且,如果只有主节点写入成功,但其他从节点没有写入成功,就算数据被写入到Leader节点,但这部分数据对客户端来说是可见的。

Raft协议主要分为两个部分:Leader节点选举与日志复制。

Leader节点选举:从集群中选举一个Leader节点用于处理数据的读写,从节点只负责从Leader节点同步数据,并且Leader节点宕机,会自动触发选举,选举出一个新的Leader节点。

日志复制:数据写入主节点后,主节点需要将数据转发给从节点,只有集群中超过半数节点都成功将一条数据写入才向客户端返回成功。

Raft协议的实现细节本文不打算深究,大家如果感兴趣,可以在文末查看笔者有关Raft协议的专栏,本文只从设计层面剖析为什么Raft协议能实现数据的一致性。

笔者认为Raft协议能确保数据的一致性,主要是引入了全局日志序号与已提交指针。

2.1 引入了全局日志序号
为了方便对日志进行管理与辨别,raft 协议为一条一条的消息进行编号,每一条消息达到主节点时会生成一个全局唯一的递增号,这样可以根据日志序号来快速的判断数据在主从复制过程中数据是否一致。

2.2 已提交指针
我们知道,日志先写入主节点,然后再进行传播,在集群中超过半数节点的写入成功之前,这条日志都不能认为写入成功,尽管已经存储到了主节点中,为了让客户端对这条日志不可见,Raft协议引入了已提交指针,只有小于等于已提交的数据才能被客户端感知。

一条日志要能被提交的充分必要条件是日志得到了集群内超过半数节点成功追加,才能被认为已提交,才会向客户端返回成功,这样就实现了数据在集群内、客户端与集群之间的数据一致性语义。

为了让大家更加深入的理解Raft协议数据性一致性问题,给出如下思考题,主从切换会导致Raft丢失数据吗?

例如一个Raft协议中有3个节点,各个节点的写入情况如下:

Node1:100

Node2:89

Node3:88

其中Node1为Leader节点,如果Node1节点宕机,整个集群触发重新选举,会丢失数据吗?

答案是肯定不会的。

首先我们要先明白,在上面的状态下,已提交指针为89,因为集群有两个节点都成功写入了89,即向客户端返回成功的数据也是序号为89的数据,在选举过程中,Node3不可能会被选举为Leader,因为Node3中存储的数据小于Node2存储的数据,当Node2选举为新的Leader时,Node3会向Node2同步数据。

3、总结
本文从知乎上一个不严紧的问题出发,挖掘该问题的本质:分布式数据存储的数据分片与高可用(避免单点故障),从而又引发新的问题(数据副本之间的一致性)
————————————————

原文链接:https://blog.csdn.net/prestigeding/article/details/115071252

参考链接

1
  1. 1https://blog.csdn.net/prestigeding/article/details/115071252blog.csdn.net
除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接

本文链接:https://www.lifengdi.com/transport/2669

本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
分享到

为什么同样是分布式架构的Kafka需要Leader而Redis不需要?

也可使用浏览器菜单中的「分享」功能

微信扫一扫分享

标签: Kafka MQ Redis 分布式
最后更新:2021年3月22日
相关文章
  • 从3秒到30毫秒!SpringBoot树形结构深度优化指南:不止于O(n)算法的全链路提速方案2025年10月31日
  • RedisTemplate和Redisson的区别2025年5月29日
  • 详解 ZooKeeper 数据持久化2021年3月18日
  • 深度解析多级缓存架构:从设计到落地,彻底解决数据一致性难题2025年11月4日
  • Kafka Log Compaction(日志压缩)详解2026年8月26日
blank

李锋镝

既然选择了远方,便只顾风雨兼程。

打赏 点赞
< 上一篇
下一篇 >
1234567891112131415161718192021222324252627282930313233343536373839404142434446474849505152535455575859606162636465666769727476777879808182858687909293949596979899
取消回复

文章评论

还没有评论,快来抢沙发吧~

惟坚韧者始能遂其志。

听点儿音乐吧 朋友~
文章目录
最新 热点 随机
最新 热点 随机
支撑全网40%网站的WordPress正在重新拥抱PHP生态 Kratos-plus v1.1.24版本更新说明 关于主题加载速度优化的一点儿小演进 市场主流AI编程大模型横向深度分析(2026-09-11) 一款节省token的利器:RTK(Rust Token Killer) RAG太难学?LLM Wiki了解一下
给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能WordPress缓存插件WP Fastest Cache、WP Rocket 、FlyingPress对比关于使用AI的一些思考Kratos+ v1.1.16版本更新说明AI时代,个人技术博客的出路在哪里?推荐一个SVG 矢量小图标免费下载网站
Springboot接入DeepSeek API 详解 ZooKeeper 数据持久化 重构 Controller 终极指南:从臃肿到优雅的 7 大黄金法则 + 实战技巧 UUID太长怎么办?快来试试NanoId 写了个日期进度条的小插件 JMX监控权限认证配置
最近评论
blank
lijie blog 发布于 9 小时前(09月14日) 友链申请 名称:lijie blog 链接:https://lijie.cool 描述:懒于当...
blank
Hary 发布于 11 小时前(09月14日) 等PHP9推倒重来,出个船新版本
blank
李锋镝 发布于 23 小时前(09月14日) 不愧是皮总,这措辞~ :30:
blank
皮皮社长 发布于 23 小时前(09月14日) :20: 我勒了个去,中国汉字波大精深。 :42:
blank
李锋镝 发布于 23 小时前(09月14日) 我这里面也带了一堆小表情包,看看不行也优化一波
标签聚合
Redis WordPress AI SpringBoot Claude 架构 JAVA 分布式 AI编程 K8s ElasticSearch Spring 多线程 日常 IDEA MySQL MQ JVM SQL 数据库
友情链接
  • 若梦博客
  • 九仞之行
  • sssr7844的博客
  • Honesty
  • 彬红茶日记
  • 蜗牛工作室
  • 老张博客
  • 搬砖日记
  • 瓦匠个人小站
  • 志文工作室
  • 韩情脉脉
  • 知向前端
  • Serendipity
  • 临窗旋墨
  • 韩小韩博客
  • 皮皮社
  • 哥斯拉
  • Mr.Sun的博客
  • 懋和道人
  • 林羽凡

COPYRIGHT © 2016-2026 lifengdi.com. ALL RIGHTS RESERVED.

Domain age badge for lifengdi.com

Theme Kratos-plus By Dylan Li

津ICP备2024022503号-3

京公网安备11011502039375号