当前位置: 首页 > news >正文

关于MQ之kafka的深入研究

目录

1、MQ介绍

1.1、性能对比

1.2、分布式设计

1.3、ACK应答机制

2、Kafka的介绍

2.1、核心组件

2.2、核心特性

2.3、消费 Leader数据

2.4、如何找到 Leader 副本

2.5、消费者组与分区分配

2.6、消费者读取数据的流程

2.7、leader切换的流程

3、kafka架构设计

3.1、消费者组

3.2、消费者和broker联系

3.3、消费模型对比

3.4、消费同一partion原因

1. Offset 的独立性

2. 多订阅场景的需求

3. Partition 的 Leader 机制

4、常见问题


前言

        Apache Kafka 是一个 分布式流处理平台,最初由 LinkedIn 开发,后成为 Apache 软件基金会的顶级开源项目。

        Kafka 的核心目标是 构建实时数据管道和流式应用,支持高吞吐量、持久化、水平扩展和容错能力。它广泛应用于日志聚合、消息队列、事件溯源、流式处理等领域。

更多关于队列MQ的介绍,可参考:MQ消息队列的深入研究-CSDN博客


1、MQ介绍

1.1、性能对比

        Kafka、RabbitMQ、RocketMQ 和 ActiveMQ 是流行的消息队列解决方案,它们在架构设计、性能、特性和适用场景上各有不同。

如下图所示:

        Kafka 适合高吞吐量和流式数据处理,RabbitMQ 适合需要复杂路由和灵活性场景,RocketMQ 适用于高并发的应用场景,而 ActiveMQ 则适合企业级 Java 应用集成。

1.2、分布式设计

对于kafka来讲:

        Kafka是分布式的:其所有的构件borker(服务端集群)、producer(消息生产)、consumer(消息消费者)都可以是分布式的。

        可以进行分区:每一个分区Partion都是一个顺序的、不可变的消息队列, 并且可以持续的添加。

1.3、ACK应答机制

本设计为面试重点提问:

        producer在向kafka写入消息的时候,可以设置参数来确定是否确认kafka接收到数据,这个参数可设置 的值为 0,1,all。

0:

        代表producer往集群发送数据不需要等到集群的返回,不确保消息发送成功。安全性最低但是效 率最高。
1:

        代表producer往集群发送数据只要leader应答就可以发送下一条,只确保leader发送成功。
all:

        代表producer往集群发送数据需要所有的follower都完成从leader的同步才会发送下一条,确保 leader发送成功和所有的副本都完成备份。安全性最⾼高,但是效率最低。

⚠️注意:

        如果往不存在的topic写数据,kafka会⾃动创建topic,partition和replication的数量 默认配置都是1。


2、Kafka的介绍

如下图所示:

2.1、核心组件

        当消息从producer推送给broker,消费者会从broker的leader节点去读取数据。每个broker对应的不同的节点。

1. Producer(生产者)

  • 作用:将数据写入 Kafka 集群。
  • 特性
    • 支持异步发送和同步发送。
    • 可以指定消息的 Key 和 Value,用于分区策略。
    • 消息会被发送到指定的 Topic 和 Partition。

具体写入的流程,如下:

消息发送:

        当生产者发送消息时,首先计算消息的哈希值,以决定将消息发送到哪个分区。默认情况下,Kafka 使用轮询策略和关键字哈希来分配消息。


异步发送:

        生产者可以选择异步发送消息,这样可以提升发送效率。Kafka 会在后台处理消息的生产,在网络性能允许的情况下,可以并行发送。


确认机制:

生产者可以配置确认等级(acks),如:
        acks=0:不要求确认,速度最快。
        acks=1:主 Broker 确认(数据成功写入到领导者)。
        acks=all(或 acks=-1):所有副本都成功确认,最高的可靠性。

2. Consumer(消费者)

如下图所示:

  • 作用:从 Kafka 集群读取数据。
  • 特性
    • 消费者属于一个 Consumer Group(消费者组),组内消费者共同消费 Topic 的 Partition。
    • 支持 offset 管理(记录消费位置),可通过自动提交或手动提交。
    • 提供 拉取模型(Pull Model),消费者主动从 Broker 拉取数据。

消费的流程,如下:

消息读取:

        消费者可以通过订阅主题来接收消息。消费者可以设置其消费者组,这样同一组内的多个消费者可以共享处理主题topic的负载。


消费位移:

        每个消费者在 Kafka 中维护自己的消费位移(offset),用于记录它已经消费到的位置。Kafka 允许消费者能够记录和管理自己的消费进度。


组管理:

        在消费者组内,Kafka 会将各个分区的消息分配给不同的消费者。确保每个分区只能被组内一个消费者处理,避免重复消费。

3. Topic(主题)

  • 作用:逻辑上的数据分类,类似数据库中的表。
  • 特性
    • 每个 Topic 被划分为多个 Partition(分区),实现水平扩展。
    • 消息按顺序存储在 Partition 中(每个 Partition 内有序,跨 Partition 无序)。

4. Partition(分区)

如下图所示:

  • 作用:Topic 的物理分片,用于并行处理和水平扩展。
  • 特性
    • 每个 Partition 是一个 有序的、不可变的、顺序追加的日志文件
    • 消息在 Partition 中按顺序存储,并通过 Offset(偏移量)标识位置。
    • 分区数决定了 Kafka 的并行能力(消费者数不能超过分区数)。

5. Broker(节点)

  • 作用:Kafka 集群中的服务器节点,负责存储数据和处理请求。
  • 特性
    • 每个 Broker 有唯一 ID。
    • 支持水平扩展,新增节点可提升吞吐量和容错能力。

6. Replica(副本)

  • 作用:为 Partition 提供冗余备份,确保高可用性。
  • 特性
    • 每个 Partition 有多个副本(Leader + Follower)。
    • Leader:负责处理读写请求。
    • Follower:从 Leader 同步数据,故障时自动选举新 Leader。

7. ZooKeeper

如下图所示:

  • 作用:Kafka 集群的协调服务,管理 Broker、Partition 和 Consumer Group 的元数据。
  • 关键功能
    • 监控 Broker 状态。
    • 管理 Partition 的 Leader 选举。
    • 维护 Consumer Group 的消费进度。

2.2、核心特性

相比较于其他mq,kafka的最大特点:高吞吐量。

1. 高吞吐量

  • 设计目标:每秒处理百万级消息。
  • 优化手段
    • 批量发送:Producer 和 Consumer 支持批量操作,减少网络开销。
    • 顺序写入:磁盘顺序写入(Append-Only),避免随机 I/O。
    • 零拷贝(Zero-Copy):通过 sendfile 系统调用直接从磁盘传输到网络。

2. 持久化与可靠性

  • 消息持久化:消息写入磁盘并保留指定时间(如 7 天),避免数据丢失。
  • 副本机制:每个 Partition 有多个副本,自动同步数据,确保高可用。
  • 确认机制(acks):Producer 可配置 acks=1 或 acks=all,确保消息被多个副本接收。

3. 水平扩展

  • 分区机制:Topic 的 Partition 可动态调整,支持水平扩展。
  • 多 Broker 架构:增加 Broker 节点可提升吞吐量和存储容量。

4. 实时流处理

  • 流处理 API:Kafka 提供 Kafka Streams 和 KSQL,支持实时计算。
  • Exactly-Once 语义:通过事务机制(Transaction)保证消息的精准一次处理。

5. 灵活的消费模式

  • 点对点模式:每个消息被一个 Consumer 消费(单播)。
  • 发布-订阅模式:每个消息被所有 Consumer Group 消费(广播)。

2.3、消费 Leader数据

消费者在消费过程中,只会去请求leader数据,为什么会这样呢?

1、保证数据一致性

        如果消费者直接从 Follower 读取数据,可能会遇到数据不一致的问题。例如,Follower 可能尚未同步最新的消息,导致消费者读取到旧数据。Leader 是唯一负责写入和同步的副本,消费者直接从 Leader 读取可以确保读取到最新的、完整的数据。

2、简化系统设计

        所有读写操作集中到 Leader,避免了多副本间并发控制的复杂性。如果允许消费者直接读取 Follower,需要额外的协调机制来保证一致性,增加系统复杂度。

3、性能优化

        Follower 的主要职责是数据复制,而非处理读请求。若消费者直接读取 Follower,可能导致 Follower 资源被争用,影响同步效率。

2.4、如何找到 Leader 副本

1、ZooKeeper 的作用

        Kafka 使用 ZooKeeper 维护集群的元数据,包括每个分区的 Leader 和 Follower 信息。

        消费者启动时会向 ZooKeeper 查询目标分区的 Leader 位置(Broker ID 和端口)。

2、动态感知 Leader 变更

        如果 Leader 副本故障,Kafka 会触发 Leader 选举,从 Follower 中选出新的 Leader消费者通过 ZooKeeper 监听分区的元数据变更,一旦发现 Leader 变更,会重新连接到新的 Leader。

2.5、消费者组与分区分配

如下图所示:

1、消费者组(Consumer Group)

        同一消费者组内的消费者共同消费一个 Topic 的所有分区。Kafka 会将分区分配给消费者组中的消费者,确保每个分区仅被一个消费者消费。

2、分区分配策略

        Range 分配:按分区顺序依次分配给消费者。

        Round-Robin 分配:轮询方式分配分区。

        Sticky 分配:尽量保持分区分配的稳定性,减少再平衡开销。

3、再平衡(Rebalance)

        当消费者加入/退出组,或分区 Leader 变更时,Kafka 会触发再平衡,重新分配分区给消费者。再平衡期间,消费者会短暂停止消费,直到分配完成。

2.6、消费者读取数据的流程

如下图所示:

1、初始化阶段

        消费者向 ZooKeeper 查询目标分区的 Leader 信息。消费者连接到 Leader 所在的 Broker。

2、拉取数据(Fetch Request)

        消费者向 Leader 发送 FetchRequest,请求指定 Offset 的消息。Leader 返回消息批次(Batch),消费者处理后更新消费 Offset。

3、Offset 管理

自动提交

        消费者定期自动提交 Offset 到 Kafka 的 __consumer_offsets Topic。

手动提交

        消费者通过 API 显式提交 Offset,确保消息处理完成后才提交。

2.7、leader切换的流程

1. 消费者组启动时:
   - 消费者 A 被分配到 Partition 0(Leader 在 Broker 1)。
   - 消费者 B 被分配到 Partition 1(Leader 在 Broker 2)。

2. Broker 1 故障:
   - Kafka 选举 Partition 0 的 Follower(假设在 Broker 3)为新 Leader。
   - 消费者 A 通过 ZooKeeper 检测到变更,重新连接到 Broker 3。
   - 消费者 A 继续从新的 Leader 读取数据,无需中断消费流程。
 


3、kafka架构设计

kafka的消息模型为发布-订阅方式。kafka的架构设计如下图所示:

3.1、消费者组

如下图所示:

        在 Kafka 中,不同消费者组的消费者可以同时消费同一个 Partition 的数据,而 同一消费者组内的消费者不能同时消费同一个 Partition

3.2、消费者和broker联系

1、消费者

        同一组内的不同消费者可以消费不同的broker。

如下图所示:

 

       这是 Kafka 保证消息消费的灵活性和可靠性的核心机制之一。

同一组内的消费者

        共享一个组 ID(group.id),共同消费一个 Topic 的所有 Partition,每个 Partition 只能被组内 一个消费者 消费。

不同组的消费者

        彼此独立,可以同时消费同一个 Topic 的所有 Partition,包括同一 Partition。

3.3、消费模型对比

示例:

  • 不同消费者组的消费者可以同时消费同一个 Partition
  • 每个消费者组会独立维护自己的消费偏移量(Offset),互不干扰。
  • 示例
    • 假设 Topic my-topic 有 3 个 Partition(P0, P1, P2)。
    • 消费者组 A:包含两个消费者 C1 和 C2,分别消费 P0 和 P1。
    • 消费者组 B:包含两个消费者 C3 和 C4,分别消费 P0 和 P2。
    • 此时,C1(组 A)和 C3(组 B)可以同时消费 P0,互不影响。

3.4、消费同一partion原因

为什么不同消费者组可以消费同一 Partition?

如下图所示:

1. Offset 的独立性

        每个消费者组会将消费进度(Offset)保存在 Kafka 的内部 Topic __consumer_offsets 中。

        不同组的 Offset 是独立存储的,因此它们可以独立地从 Partition 的任意位置(如起始位置或某个特定 Offset)开始消费。

2. 多订阅场景的需求

        Kafka 的设计目标是支持 多订阅者(Multi-subscriber) 模型,即多个消费者组可以同时消费同一个 Topic 的数据。

例如:

        一个消费者组用于实时数据分析。

        另一个消费者组用于历史数据归档。

        第三个消费者组用于监控告警。

3. Partition 的 Leader 机制

        所有消费者(无论属于哪个组)都必须从 Partition 的 Leader 副本 读取数据。

        Kafka 通过 ZooKeeper 维护 Partition 的 Leader 信息,不同组的消费者会同时向 Leader 发送请求,但 Kafka 允许多个客户端并发读取。


4、常见问题

1: 如果两个消费者组都消费同一个 Partition,会不会导致消息丢失?

        不会。只要 Kafka 的副本机制正常运行,消息会被持久化到磁盘,并且每个消费者组会独立维护自己的 Offset。即使一个组消费失败,另一个组仍能正常消费。

2: 如何控制不同组的消费进度?

如下图所示:

手动提交 Offset

        通过 consumer.commitSync() 或 consumer.commitAsync() 显式控制每个组的消费进度。

自动提交 Offset

        通过 enable.auto.commit=true 配置,Kafka 会定期自动提交 Offset。

3: 如果 Partition 的 Leader 故障,不同组的消费者会如何反应?

        Kafka 会选举新的 Leader,所有消费者(无论属于哪个组)会重新连接到新的 Leader,并继续消费。


总结

        Kafka 是一个强大的分布式流处理平台,凭借其 高吞吐量、持久化、水平扩展 和 实时处理能力,成为大数据和实时系统的核心组件。

        尽管其配置和调优较为复杂,但在日志聚合、消息队列、流式处理等场景中表现优异。


参考文章:

1、kafka全解-CSDN博客

相关文章:

  • Vue.js教学第二十一章:vue实战项目二,个人博客搭建
  • kafka-重平衡
  • CSS 工具对比:UnoCSS vs Tailwind CSS,谁是你的菜?
  • STM32 _main 里做了什么
  • OceanBase 桌面版
  • NL2SQL模型应用实践-解决上百张表筛选问题
  • 节拍定时器是什么?
  • Ai自动补全编程工具:llama vscode
  • SpringBoot+uniapp 的 Champion 俱乐部微信小程序设计与实现,论文初版实现
  • LLM - LlamaFactory 的大模型推理 踩坑记录
  • uni-app学习笔记三十五--扩展组件的安装和使用
  • VRFF: Video Registration and FusionFramework 论文详解
  • 年度峰会上,抖音依靠人工智能和搜索功能吸引广告主
  • 【JavaAPI搜索引擎】自动化测试报告
  • React---day11
  • llama-factory微调大模型环境配置避坑总结
  • Html实现图片上传/裁剪/马赛克/压缩/旋转/缩放
  • 【Dv3Admin】系统视图菜单管理API文件解析
  • 阿里云服务器 篇十七:网站悬浮球
  • centos开启samba服务
  • java做的网站怎么设置关闭和开启网站访问不了怎么办/昆山网站建设
  • 代码源/什么是优化师
  • 朝阳区社会建设网站/win优化大师怎么样
  • 云梦网络做网站/seo营销推广服务公司
  • 公司网站建设有什么好处/全媒体运营师
  • 现在清算组备案在哪个网站做/搜狗搜索推广