一文让你彻底理解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 语义的

[2]. Overview of Kafka Architecture

相关推荐
向前看-2 小时前
验证码机制
前端·后端
xlsw_2 小时前
java全栈day20--Web后端实战(Mybatis基础2)
java·开发语言·mybatis
神仙别闹3 小时前
基于java的改良版超级玛丽小游戏
java
黄油饼卷咖喱鸡就味增汤拌孜然羊肉炒饭4 小时前
SpringBoot如何实现缓存预热?
java·spring boot·spring·缓存·程序员
暮湫4 小时前
泛型(2)
java
超爱吃士力架4 小时前
邀请逻辑
java·linux·后端
南宫生4 小时前
力扣-图论-17【算法学习day.67】
java·学习·算法·leetcode·图论
转码的小石4 小时前
12/21java基础
java
李小白664 小时前
Spring MVC(上)
java·spring·mvc
GoodStudyAndDayDayUp4 小时前
IDEA能够从mapper跳转到xml的插件
xml·java·intellij-idea