为什么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/...

相关推荐
博客zhu虎康7 分钟前
ElementUI 的 form 表单校验
前端·javascript·elementui
敲啊敲952736 分钟前
5.npm包
前端·npm·node.js
贵州晓智信息科技41 分钟前
如何优化求职简历从模板选择到面试准备
面试·职场和发展
brrdg_sefg1 小时前
Rust 在前端基建中的使用
前端·rust·状态模式
m0_748230941 小时前
Rust赋能前端: 纯血前端将 Table 导出 Excel
前端·rust·excel
qq_589568101 小时前
Echarts的高级使用,动画,交互api
前端·javascript·echarts
小蜗牛慢慢爬行2 小时前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
黑客老陈2 小时前
新手小白如何挖掘cnvd通用漏洞之存储xss漏洞(利用xss钓鱼)
运维·服务器·前端·网络·安全·web3·xss
正小安2 小时前
Vite系列课程 | 11. Vite 配置文件中 CSS 配置(Modules 模块化篇)
前端·vite