一文让你彻底理解Kafka架构设计

一、简介

Apache Kafka简称Kafka,简单来说它是一个发布与订阅消息系统。

二、五大核心API

  • Kafka Producer :将消息数据流发送到Kafka集群中的主题Topic
  • Kafka Consumer :从Kafka集群中的主题Topic读取消息数据流。
  • Kafka Stream :将消息数据流输入主题Topic转换为输出主题。
  • Kafka Connection :实现连续从某些源系统或者应用程序拉取Kafka或者从Kafka推送到某些接收器系统或者应用程序的连接器。
  • Kafka Admin :管理和检查主题、代理和其他Kafka对象。

三、核心概念和术语

  • 事件Event:从概念上讲事件具有键、值、时间戳和可选的元数据信息,比如:

    • Event KeyIT_sunshine
    • Event Value:向Tony支付了20美元为剪发费用
    • Event Timing:2024年1月10号 下午6点整
  • 生产者Producer :生产者负责将事件发布(写入)到Kafka的客户端应用程序。

  • 消费者Consumer:消费者即为订阅(读取和处理)这些事件的客户端应用程序,kafka支持多个消费者模式,多个消费者可以组成一个消费群组,共享一个消息流,保证整个群组对每个消息只处理一次。

  • 消息代理BrokerKafka集群是有多个Broker组成,每个Broker都是一个独立的服务器,它负责管理一个或者多个主题的分区。Broker负责接收来自生产者的消息,并将消息存储到消息队列中,同时,也是由Broker来处理消费者的请求,将消息发送给消息者。

  • 主题Topic:事件被组织并持久化存储到主题中,主题好比文件系统的文件夹,事件为文件夹中的文件,一个主题可包含零个、一个或者多个生产者,同理也可以有零个、一个或者多个消费者。

  • 分区Partition :主题是分区的,意味着主题Topic分布在不同的Kafka代理的多个区中,这种数据的分布式存储对于扩展性非常重要,当时间被发布到主题时,它实际上就已经附加到对应主题的其中一个分区,具有相同的事件键(比如:消息ID、用户ID、车辆ID)的事件会被有序的写入同一分区

四、Broker和集群

一个独立的kafka服务器被称为brokerbrokerkafka集群的组成部分。

broker是负责接口来自生产者的消息,为消息设置偏移量offset,并提交消息到磁盘保存。 broker同时为消费者提供服务,对读取分区的请求做出响应,返回已经提交到磁盘的消息。

五、Kafka的能力扩展能力伸缩

比如,在我的iot消息服务项目中采用多线程CompletableFuture处理kafka消息:

六、消费者的三种模式

Kafka提供了消息的各种保证,比如一次性处理消息事件的能力,归根结底就是:消息的持久性和幂等性保证。

最多一次at most once模式

消息可能会丢失,但不会重复发送。

基本思想就是需要保证每一条消息commit成功之后,再进行消费处理,设置自动提交开关为false,接收到消息之后,首先commit,然后再进行消费。

最少一次at least once模式

消息不会丢失,但可能重复发送

基本思想就是需要保证每一条消息处理成功之后,再进行commit,设置自动提交为false,消息处理成功之后,再手动进行commit

精确一次exactly once模式

消息不会丢失,也不会重复发送(这个即是业务真正想要的)

核心思想是生产端Producer发送消息成功,并且成功的消息只发送一次(重复的数据会被服务器拒绝),消息端在进行幂等性保障处理。

消费者的三种模式是从消费者角度衡量次数的。但是其实现却依赖生产者,因为生产者可能发送丢失数据或发送重复数据的情况,当ProducerBroker发送数据时,可以通过request.required.acks参数来设置数据可靠性的级别,Kafka的ack参数设置值分别有:-1、0、1,这个ack参数在Kafka的使用中,是非常核心以及关键的参数,下面分别介绍不同参数值的区别:

  • request.required.acks参数值等于0:意味着生产者Producer不会等待来自Broker的确认而会继续发送下一条消息,这种情况下数据传输效率最高,但是数据的可靠性是最低的,可能会丢数据,不会重复发送
    • 特点:延迟性最好,但是可靠性弱
  • request.required.acks参数值等于1(Kafka默认配置):意味着Producer要等待Leader成功收到数据并得到确认,才发送下一条message可能会丢数据,可能会重复发送
    • 特点:提供了较好的持久性较低的延迟性,兼容两大特性。
  • request.required.acks参数值等于-1或者all:意味着生产者发消息发送出去之后,不仅Broker能接收到,ISR列表的从节点Follower也要同步到,生产者才会认为消息发送成功,不会丢失数据,但是可能重复发送
    • 特点:延迟性最差,但是可靠性最强

ACK参数设置值:0,1,-1三种机制性能递减,可靠性递增,如果开启失败重试,可能导致发送重复数据。

七、幂等性保证

实现消息精确一次投递消费是基本上所有业务所需要的!!!

Kafka Producer 可以通过以下几种方式实现精确一次消费数据(幂等性保证):

  1. kafka中,生产者Producer默认不是幂等性的,需要我们自己创建幂等性Producer,生产端设置参数enable.idempotencetrue,为了解决生产端的幂等,Kafka引入了生产者ID(PID)和序列号SequenceNumber,它的底层实现原理是kafka每次发送消息会生成PIDSequenceNumber,并将这两个属性一起发送给BrokerBroker会将PIDSequence Number跟消息绑定一起存起来,下次如果生产者重发相同消息,Broker会检查PIDSequence Number,如果相同不会再接收。

Kafka Consumer 可以通过以下几种方式实现精确一次消费数据(幂等性保证):

  1. 手动提交offset:在消费数据之后,手动提交offset,确保消费数据已经被处理。这种方式需要开发者自己控制offset的提交,需要注意处理异常情况下的offset提交。

  2. 自动提交offsetKafka Consumer可以自动提交offset,但是这种方式可能会出现重复消费数据的情况。因为自动提交offset是在消费数据之后立即提交,而不是在数据被处理之后提交。

  3. 使用事务:Kafka 0.11版本之后,引入了事务机制,可以保证数据的精确一次消费。使用事务需要开发者在代码中显式地开启事务,并在事务中消费数据和提交offset。如果事务提交失败,Kafka会自动回滚offset,确保数据不会被重复消费。

  4. 使用幂等性:Kafka 0.11版本之后,引入了幂等性机制,可以保证数据的精确一次消费。使用幂等性需要开发者在代码中显式地开启幂等性,并在消费数据时使用幂等性的API。如果出现重复数据,Kafka会自动过滤掉重复数据,确保数据不会被重复消费。

Kafka自身幂等只能解决当前回话的分区幂等性,跨分区、回话不能实现精准一次性投递写入,当Producer重启后,Broker分配的PID(producer_id)会发生变化,切换分区后,Patition也发生了变化。最终导致<PID,Patition,SeqNumber>作为主键的key也会发生变化。

八、总结

实际上Kafka的整体架构设计思想是值得我们深入研究和学习的,kafka之所以能做到如此大的吞吐量和可扩展性得益于它自身优秀的设计,好了,今天的分享就到此结束了,如果文章对你有所帮助,欢迎:点赞👍+评论💬+收藏❤ ,我是:IT_sunshine ,我们下期见!

参考

1\]. [Kafka 0.11.0.0 是如何实现 Exactly-once 语义的](https://link.juejin.cn?target=https%3A%2F%2Fwww.jianshu.com%2Fp%2F5d889a67dcd3 "https://www.jianshu.com/p/5d889a67dcd3") \[2\]. [Overview of Kafka Architecture](https://link.juejin.cn?target=https%3A%2F%2Fdeveloper.confluent.io%2Fcourses%2Farchitecture%2Fget-started%2F "https://developer.confluent.io/courses/architecture/get-started/")

相关推荐
左灯右行的爱情2 分钟前
缓存并发更新的挑战
jvm·数据库·redis·后端·缓存
浩宇软件开发6 分钟前
Android开发,实现一个简约又好看的登录页
android·java·android studio·android开发
brzhang6 分钟前
告别『上线裸奔』!一文带你配齐生产级 Web 应用的 10 大核心组件
前端·后端·架构
shepherd1117 分钟前
Kafka生产环境实战经验深度总结,让你少走弯路
后端·面试·kafka
南客先生13 分钟前
多级缓存架构设计与实践经验
java·面试·多级缓存·缓存架构
anqi2715 分钟前
如何在 IntelliJ IDEA 中编写 Speak 程序
java·大数据·开发语言·spark·intellij-idea
袋鱼不重20 分钟前
Cursor 最简易上手体验:谷歌浏览器插件开发3s搞定!
前端·后端·cursor
m0_7401546721 分钟前
maven相关概念深入介绍
java·maven
嘻嘻哈哈开森22 分钟前
Agent 系统技术分享
后端
用户40993225021223 分钟前
异步IO与Tortoise-ORM的数据库
后端·ai编程·trae