李锋镝的博客

  • 首页
  • 时间轴
  • 说说
  • 左邻右舍
  • 博友圈
  • 关于我
    • 关于我
    • 另一个网站
    • 我的导航站
    • 网站地图
    • 赞助
  • 留言
  • 走心评论
  • 系列文章
  • Now
  • 每日心情
  • 🚇开往
Destiny
自是人生长恨水长东
  1. 首页
  2. 转载
  3. 正文

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

2021年3月22日 约 2,122 字8 分钟 21点热度 0人点赞 0条评论
本文最后更新于 2021年3月22日,距今已 1964 天,其中的信息可能已经发生变化,请注意甄别。

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

除非注明,否则均为李锋镝的博客原创文章,转载必须以链接形式标明本文链接

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

推荐阅读

  • Kafka常见面试题(一)
  • 深度解析 Kafka Rebalance:从原理到实战,彻底解决消息积压、重复与丢失
  • 10 个MQ高频业务场景深度解析
  • Redis 不只是缓存:8 大实战场景 + 深度避坑指南,从入门到架构师级应用
  • Kafka 为什么要抛弃 Zookeeper?
本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可
标签: Kafka MQ Redis 分布式
最后更新:2021年3月22日

岁月同一天 8 月 8 日

回望过去的今天,你在写什么

  • 4 年前 2022年8月8日
    减肥四个月~

    今年四月初开始每天跳绳减肥,到了今天刚好四个月了。从一开始的每天跳绳十分钟到半个小时,再从半个小时到一个小时,最后又稳定…

相关文章
  • RedisTemplate和Redisson的区别2025年5月29日
  • 部署consul配置中心2025年3月20日
  • 10 个MQ高频业务场景深度解析2025年10月17日
  • 深度解析多级缓存架构:从设计到落地,彻底解决数据一致性难题2025年11月4日
  • 深度解析 Kafka Rebalance:从原理到实战,彻底解决消息积压、重复与丢失2025年10月30日

李锋镝

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

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

文章评论

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

九年没联系的女友突然问我借钱,我开口道:四十万行么?不够了再说话。”前女友很是高兴地回复说:“够用,还是我男朋友有办法啊,你放心,我日后一定还给你,九年多没见了你现在干啥呢,这么有钱?”我呵呵一笑:“没事,不够用您尽管说话,俺现在改做抵押贷款了。”

听点儿音乐吧 朋友~
文章目录
最新 热点 随机
最新 热点 随机
Kratos+ v1.1.14版本更新说明 Spring Boot 指定外部配置文件的方式 Spring Boot 配置加载优先级总结 Claude Fable 5(claude-fable-5)深度详解 如何通过命令查看Java应用内存中对象数量 关于服务的探活端口和业务端口不一致有什么问题
给主题增加了Now、每日心情、年度回顾、岁月同一天、随机漫步等功能AI时代,个人技术博客的出路在哪里?增加了两套复古皮肤-牛皮纸、千禧网页这个域名注册整整十年了,十年时间,真快啊WordPress实现用户评论等级排行榜插件WordPress网站换了个字体,差点儿把样式换崩了
MybatisCodeHelperPro激活 解决kubectl exec -it xxxx-service-bfbd45bb9-ktvzj bash -n bit error: exec [POD] [COMMAND] is not supported anymore. Use exec [POD] -- [COMMAND] instead See 'kubectl exec -h' for help and examples Apollo配置中心中的protalDB的作用是什么 k8s + docker + Jenkins使用Pipeline部署SpringBoot项目时Jenkins错误集锦 彻底搞懂mysql日志系统binlog,redolog,undolog Spring事件驱动深度指南:从单机异步到亿级流量,比MQ更轻的架构神器
最近评论
Huo 发布于 8 小时前(08月07日) 挺有特色的主题,还是感觉 WP 的确是强大
李锋镝 发布于 21 小时前(08月07日) 没理解你想说啥
aboss 发布于 21 小时前(08月07日) 你的后台web-login?
李锋镝 发布于 22 小时前(08月07日) 这个专门的插件实现的功能更好更全,还能对接支付之类的
李锋镝 发布于 22 小时前(08月07日) 自定义登录地址是为了防止大部分机器人通过WP固定登录页面暴力破解用户账号密码
标签聚合
K8s 日常 Claude docker JVM WordPress Redis AI编程 多线程 SQL 架构 MySQL IDEA JAVA SpringBoot Spring AI 数据库 ElasticSearch 分布式
友情链接
  • Blogs·CN
  • 懋和道人
  • 旧时繁华
  • Honesty
  • 拾趣博客导航
  • 搬砖日记
  • 知向前端
  • 临窗旋墨
  • 皮皮社
  • 瓦匠个人小站
  • 志文工作室
  • 韩小韩博客
  • 风渡言
  • 彬红茶日记
  • 老张博客
  • Mr.Sun的博客
  • 韩情脉脉
  • 哥斯拉
  • 林羽凡

COPYRIGHT © 2026 lifengdi.com. ALL RIGHTS RESERVED.

正在博友圈履约中

域名年龄

Theme Kratos+ By Dylan Li

津ICP备2024022503号-3

京公网安备11011502039375号