为什么kafka需要去实现高可用和为什么不支持读写分离

背景

工作中日日在扮演CRUD boy的角色,少有机会去实践高性能,高并发,高可用之地。所以突发奇想,能否通过解读业内如雷贯耳,但又经常接触到的开源中间件redis,kafka 等,去反推这里面的高性能,高并发,高可用的流程和设计,以及这里面的技术抉择的思想。

kafka 高性能和高并发的文章见

技术大佬问我,kafka为什么这么的快?

技术大佬问我,kafka为什么这么的快?(2)

kafka 数据高可靠的文章见

kafka 复制集------概念模型

技术大佬问我,kafka是如何做到数据的高可靠的

技术大佬问我,kafka是如何做到数据的高可靠的(下)

中间件 高可用的概念模型见

技术大佬问我,中间件是如何做到高可用的(上)

kafka为什么需要去做高可用?

大概有两点

硬件故障常态化

当集群规模上升到一定程度后,一台或者多台机器出现宕机或者物理故障,而不能继续提供服务,是一个常态。

在这种故障常态性的情况下;上层软件层面 势必需要一套failover机制,来保证中间件服务的持续和高可用的稳定运行。翻译成人话就是 机器多了,机器出故障的概率就高了,可能这种出故障的概率已经和软件自身的bug一样多了,不得不去解决这种问题了。(让我想到了某IT大神说的,万恶的硬件故障,很多硬件人员不去解决或者兼容硬件的问题,他们只会把问题和矛盾转移到上层,由软件层面来兜底底层的硬件故障

数据丢失风险

在0.8版本之前,kafka是不提供高可用机制的;某个broker所在机器宕机后,如果服务不能恢复,那么在broker上面的消息数据就丢失了。数据丢失的问题,倒逼kafka 必须提供服务高可用。

比如你的订单消费服务正在消费订单数据,突然kafka集群中某台机器的硬盘坏了,导致在这上面的分区订单消息丢失了,此时的你还敢用kafka吗?

kafka 是如何实现高可用的

借用上篇文章《中间件是如何做到高可用的(上)》 分析一般中间件高可用的解决方法可知: 实现高可用关键流程

  • 冗余
  • 故障检测
  • 切主
  • 外部通知

高可用里涉及到的设计点和详细流程可参见这位大佬的总结,此处不详讲了:www.jasongj.com/2015/04/24/...

既然分区提供了冗余,kafka 为什么不提供读写分离?

常用中间件redis,mysql,都可以提供读写分离模式;即主提供写,从提供读,以此来充分的使用机器的资源;并且也是提高系统处理性能的法宝之一。但是为什么kafka也有主从类似的模式,却不提供读写分离了?比如生产者往leader分区写入消息;消费者从其它follower分区读取消息了? **大概有如下几个原因 **

消息的消费并不是单纯的读

消息的消费看起来是一个单纯的读数据的操作,但其实包含了写操作。比如我们消费消息时的代码模式如下:

java 复制代码
while(true){ 
consumer.poll(); #①拉取消息  
XXX #②处理消息;  
consumer.commit();
}

在消费完消息时,一般会手动commit;而这个commit动作,其实是告诉broker端,记录该topic分区上已成功消费消息的位置。这是个写入操作。

主从数据同步的简单性

假设kafka支持了读写分离,即生产端写入消息到leader分区,消费端从follower分区读取消息,并提交位移到follower分区;此时会发现本来follower只需要单纯的从leader拉数据进行处理的单向过程,变的非常复杂。

因为follower保存了分区消息的位置,那么这一数据必须要同步给leader分区,或者其它的follower分区。一个分区的数据同步链路变成了n*n;大大增加了leader和follower间数据同步的复杂性,并且这个同步逻辑还更容易出错。 而单向的同步逻辑,只需要leader保证写入数据的顺序性;follower单向从leader拉取数据即可。

单向数据同步过程

n*n 数据同步过程

消息消费的及时性

如果kafka提供了读写分离,并且规避了n*n的同步过程,和不单纯的读过程 (生产端写入消息到leader分区,消费端从follower分区读取消息,消息成功消费的位移在保存到leader分区)是不是提供读写分离就没啥问题了?

貌似看起来没啥大问题。

但是我们知道使用读写分离,读到的数据,是有一定的延迟的,这是读写分离方案固有的一个缺陷吧。相比较主节点提供写和读的服务,如果写主读从,读势必会存在一定的延迟,而这种延迟取决于主从同步之间的延迟。

总结

kafka 实现高可用的原因:硬件故障常态化和为了解决数据丢失的风险

kafka 实现高可用的核心思想:冗余,故障检测,切主,外部通知

kafka 为什么不提供读写分离:消息的消费并不是单纯的读,主从同步功能的简单性,消息消费的及时性

参考资料:
kafka.apache.org/0102/docume... kafka.apache.org/0102/docume... kafka.apache.org/0102/docume... www.jasongj.com/2015/04/24/...

相关推荐
LabVIEW开发7 小时前
LabVIEW QMH 队列消息处理架构
架构·labview·labview知识·labview功能·labview程序
代码搬运媛7 小时前
Jest 测试框架详解与实现指南
前端
counterxing8 小时前
我把 Codex 里的 Skills 做成了一个 MCP,还支持分享
前端·agent·ai编程
wangqiaowq8 小时前
windows下nginx的安装
linux·服务器·前端
rising start8 小时前
二、全面理解MySQL架构
mysql·架构
之歆8 小时前
DAY_12JavaScript DOM 完全指南(二):实战与性能篇
开发语言·前端·javascript·ecmascript
发现一只大呆瓜8 小时前
Vite凭什么这么快?3分钟带你彻底搞懂 Vite 热更新的幕后黑手
前端·面试·vite
麦客奥德彪8 小时前
Android Skills
架构·ai编程
Maimai108088 小时前
React如何用 @microsoft/fetch-event-source 落地 SSE:比原生 EventSource 更灵活的实时推送方案
前端·javascript·react.js·microsoft·前端框架·reactjs·webassembly
candyTong9 小时前
Claude Code 的 Edit 工具是怎么工作的
javascript·后端·架构