一、简介
Apache Kafka
简称Kafka
,简单来说它是一个发布与订阅消息系统。
二、五大核心API
- Kafka Producer :将消息数据流发送到
Kafka
集群中的主题Topic
。 - Kafka Consumer :从
Kafka
集群中的主题Topic
读取消息数据流。 - Kafka Stream :将消息数据流输入主题
Topic
转换为输出主题。 - Kafka Connection :实现连续从某些源系统或者应用程序拉取
Kafka
或者从Kafka
推送到某些接收器系统或者应用程序的连接器。 - Kafka Admin :管理和检查主题、代理和其他
Kafka
对象。
三、核心概念和术语
-
事件Event:从概念上讲事件具有键、值、时间戳和可选的元数据信息,比如:
Event Key
:IT_sunshine
Event Value
:向Tony
支付了20美元为剪发费用Event Timing
:2024年1月10号 下午6点整
-
生产者Producer :生产者负责将事件发布(写入)到
Kafka
的客户端应用程序。 -
消费者Consumer:消费者即为订阅(读取和处理)这些事件的客户端应用程序,kafka支持多个消费者模式,多个消费者可以组成一个消费群组,共享一个消息流,保证整个群组对每个消息只处理一次。
-
消息代理Broker :
Kafka
集群是有多个Broker
组成,每个Broker
都是一个独立的服务器,它负责管理一个或者多个主题的分区。Broker
负责接收来自生产者的消息,并将消息存储到消息队列中,同时,也是由Broker来处理消费者的请求,将消息发送给消息者。 -
主题Topic:事件被组织并持久化存储到主题中,主题好比文件系统的文件夹,事件为文件夹中的文件,一个主题可包含零个、一个或者多个生产者,同理也可以有零个、一个或者多个消费者。
-
分区Partition :主题是分区的,意味着主题
Topic
分布在不同的Kafka
代理的多个区中,这种数据的分布式存储对于扩展性非常重要,当时间被发布到主题时,它实际上就已经附加到对应主题的其中一个分区,具有相同的事件键(比如:消息ID、用户ID、车辆ID)的事件会被有序的写入同一分区
四、Broker和集群
一个独立的
kafka
服务器被称为broker
,broker
是kafka
集群的组成部分。
broker
是负责接口来自生产者的消息,为消息设置偏移量offset,并提交消息到磁盘保存。 broker
同时为消费者提供服务,对读取分区的请求做出响应,返回已经提交到磁盘的消息。
五、Kafka的能力扩展能力伸缩
比如,在我的iot
消息服务项目中采用多线程CompletableFuture
处理kafka
消息:
六、消费者的三种模式
Kafka
提供了消息的各种保证,比如一次性处理消息事件的能力,归根结底就是:消息的持久性和幂等性保证。
最多一次at most once模式
消息可能会丢失,但不会重复发送。
基本思想就是需要保证每一条消息commit
成功之后,再进行消费处理,设置自动提交开关为false
,接收到消息之后,首先commit
,然后再进行消费。
最少一次at least once模式
消息不会丢失,但可能重复发送
基本思想就是需要保证每一条消息处理成功之后,再进行commit
,设置自动提交为false
,消息处理成功之后,再手动进行commit
。
精确一次exactly once模式
消息不会丢失,也不会重复发送(这个即是业务真正想要的)
核心思想是生产端Producer
发送消息成功,并且成功的消息只发送一次(重复的数据会被服务器拒绝),消息端在进行幂等性保障处理。
消费者的三种模式是从消费者角度衡量次数的。但是其实现却依赖生产者,因为生产者可能发送丢失数据或发送重复数据的情况,当Producer
向Broker
发送数据时,可以通过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
可以通过以下几种方式实现精确一次消费数据(幂等性保证):
- 在
kafka
中,生产者Producer
默认不是幂等性的,需要我们自己创建幂等性Producer
,生产端设置参数enable.idempotence
为true
,为了解决生产端的幂等,Kafka
引入了生产者ID(PID
)和序列号SequenceNumber
,它的底层实现原理是kafka每次发送消息会生成PID
和SequenceNumber
,并将这两个属性一起发送给Broker
,Broker
会将PID
和Sequence Number
跟消息绑定一起存起来,下次如果生产者重发相同消息,Broker
会检查PID
和Sequence Number
,如果相同不会再接收。
Kafka Consumer
可以通过以下几种方式实现精确一次消费数据(幂等性保证):
-
手动提交
offset
:在消费数据之后,手动提交offset
,确保消费数据已经被处理。这种方式需要开发者自己控制offset
的提交,需要注意处理异常情况下的offset
提交。 -
自动提交
offset
:Kafka Consumer
可以自动提交offset
,但是这种方式可能会出现重复消费数据的情况。因为自动提交offset
是在消费数据之后立即提交,而不是在数据被处理之后提交。 -
使用事务:
Kafka 0.11
版本之后,引入了事务机制,可以保证数据的精确一次消费。使用事务需要开发者在代码中显式地开启事务,并在事务中消费数据和提交offset
。如果事务提交失败,Kafka
会自动回滚offset
,确保数据不会被重复消费。 -
使用幂等性:
Kafka 0.11
版本之后,引入了幂等性机制,可以保证数据的精确一次消费。使用幂等性需要开发者在代码中显式地开启幂等性,并在消费数据时使用幂等性的API
。如果出现重复数据,Kafka
会自动过滤掉重复数据,确保数据不会被重复消费。
Kafka
自身幂等只能解决当前回话的分区幂等性,跨分区、回话不能实现精准一次性投递写入,当Producer
重启后,Broker
分配的PID(producer_id)
会发生变化,切换分区后,Patition
也发生了变化。最终导致<PID,Patition,SeqNumber>
作为主键的key
也会发生变化。
八、总结
实际上
Kafka
的整体架构设计思想是值得我们深入研究和学习的,kafka
之所以能做到如此大的吞吐量和可扩展性得益于它自身优秀的设计,好了,今天的分享就到此结束了,如果文章对你有所帮助,欢迎:点赞👍+评论💬+收藏❤ ,我是:IT_sunshine
,我们下期见!