Kafka 入门第一篇:核心概念与整体架构

玄武2026-03-06字数:2178阅读:约 8 分钟kafkaKafka中间件

Kafka 入门第一篇:核心概念与整体架构

🎯 目标读者:有Java基础,第一次接触Kafka
📖 难度:⭐⭐☆☆☆
⏱️ 预计阅读时间:20 分钟


一、Kafka 是什么?

Apache Kafka 是一个由 LinkedIn 开源、后捐献给 Apache 基金会的分布式流处理平台

用一句话概括它的核心能力:

Kafka 是一个高吞吐、低延迟、可持久化、可水平扩展的分布式消息系统。

1.1 它能解决什么问题?

想象一个电商系统:用户下单后,需要同时触发以下操作:

  • 扣减库存
  • 发送短信通知
  • 更新用户积分
  • 通知物流系统
  • 记录用户行为日志

没有 Kafka 时(同步调用)

sequenceDiagram
    participant 用户
    participant 订单服务
    participant 库存服务
    participant 短信服务
    participant 积分服务
    participant 物流服务

    用户->>订单服务: 下单请求
    订单服务->>库存服务: 扣库存(同步)
    订单服务->>短信服务: 发短信(同步)
    订单服务->>积分服务: 加积分(同步)
    订单服务->>物流服务: 通知物流(同步)
    订单服务-->>用户: 返回成功(等待所有完成后)

问题:响应慢、系统耦合、一个服务挂了全挂。

有了 Kafka 后(异步解耦)

sequenceDiagram
    participant 用户
    participant 订单服务
    participant Kafka
    participant 库存服务
    participant 短信服务
    participant 积分服务

    用户->>订单服务: 下单请求
    订单服务->>Kafka: 发布"订单创建"事件
    订单服务-->>用户: 立即返回成功
    Kafka-->>库存服务: 异步消费
    Kafka-->>短信服务: 异步消费
    Kafka-->>积分服务: 异步消费

优势:响应快、解耦、各服务独立失败不影响核心链路。


二、Kafka 的核心概念

2.1 六大核心角色

graph TB
    subgraph Kafka集群
        B1[Broker 1]
        B2[Broker 2]
        B3[Broker 3]
    end

    subgraph Topic-订单事件
        direction LR
        P0["Partition 0\n[offset 0][offset 1][offset 2]..."]
        P1["Partition 1\n[offset 0][offset 1][offset 2]..."]
        P2["Partition 2\n[offset 0][offset 1][offset 2]..."]
    end

    Producer["🖊️ Producer\n(生产者)"] -->|写入消息| P0
    Producer -->|写入消息| P1
    Producer -->|写入消息| P2

    P0 --> B1
    P1 --> B2
    P2 --> B3

    B1 -->|推送/拉取| C1["Consumer A\n(消费者组1)"]
    B2 -->|推送/拉取| C1
    B3 -->|推送/拉取| C2["Consumer B\n(消费者组2)"]

    ZK["🐘 ZooKeeper/KRaft\n(集群协调)"] -.->|元数据管理| B1
    ZK -.->|元数据管理| B2
    ZK -.->|元数据管理| B3
概念说明类比
BrokerKafka 服务节点,负责存储和转发消息邮局
Topic消息的逻辑分类,类似数据库的表邮箱的分类
PartitionTopic 的物理分片,实现并行处理邮筒(多个)
Offset消息在 Partition 内的唯一序号(从0开始,单调递增)信件编号
Producer向 Topic 发送消息的客户端寄信人
Consumer从 Topic 拉取消息的客户端收信人

2.2 Topic 与 Partition

Topic 是一个逻辑概念,真正的数据存储在 Partition 中。

Topic: order-events
├── Partition 0  → 存储在 Broker 1(Leader)+ Broker 2(Follower)
├── Partition 1  → 存储在 Broker 2(Leader)+ Broker 3(Follower)
└── Partition 2  → 存储在 Broker 3(Leader)+ Broker 1(Follower)

为什么要分区?

  • 水平扩展:多个 Partition 分布在不同 Broker 上,突破单机存储瓶颈
  • 并行处理:Consumer Group 中的多个 Consumer 可以并行消费不同 Partition
  • 高可用:每个 Partition 有多个副本(Replica),Leader 宕机后自动切换

2.3 Offset —— Kafka 的"书签"

Offset 是消息在 Partition 中的位置标记,单调递增、不可修改

Partition 0 的消息布局:
┌────────┬────────┬────────┬────────┬────────┐
│Offset 0│Offset 1│Offset 2│Offset 3│Offset 4│
│  msg1  │  msg2  │  msg3  │  msg4  │  msg5  │
└────────┴────────┴────────┴────────┴────────┘

                    Consumer 当前读到这里(offset=3)

⚠️ 重点:Kafka 不删除已消费的消息,消息保留时间由配置决定(默认7天)。这意味着同一条消息可以被多个 Consumer Group 独立消费。

2.4 Consumer Group —— 消费者组

Consumer Group 是 Kafka 消费模型的核心设计:

graph LR
    subgraph Topic-3个Partition
        P0[Partition 0]
        P1[Partition 1]
        P2[Partition 2]
    end

    subgraph 消费者组A-3个Consumer
        CA1[Consumer A-1]
        CA2[Consumer A-2]
        CA3[Consumer A-3]
    end

    subgraph 消费者组B-1个Consumer
        CB1[Consumer B-1]
    end

    P0 --> CA1
    P1 --> CA2
    P2 --> CA3

    P0 --> CB1
    P1 --> CB1
    P2 --> CB1

规则

  • 同一个 Consumer Group 内,一个 Partition 只能被一个 Consumer 消费
  • 不同 Consumer Group 之间互相独立,都能消费全量消息
  • Consumer 数量 > Partition 数量时,多余的 Consumer 会闲置

2.5 ZooKeeper 与 KRaft

  • ZooKeeper(旧):Kafka 早期用 ZooKeeper 存储集群元数据(Broker 列表、Topic 配置、选举信息等)
  • KRaft(新):Kafka 2.8+ 引入内置的 Raft 协议替代 ZooKeeper,Kafka 4.0 已完全移除 ZooKeeper 依赖

💡 面试提示:被问到"Kafka 用 ZooKeeper 做什么"时,重点说元数据管理和 Controller 选举,并补充 KRaft 是未来趋势。


三、Kafka 整体架构

graph TB
    subgraph 生产者端
        App1[应用服务1]
        App2[应用服务2]
    end

    subgraph Kafka集群
        direction TB
        Controller["Controller\n(集群控制器)"]
        subgraph Broker1["Broker 1"]
            T1P0["Topic-A / P0(Leader)"]
            T2P1["Topic-B / P1(Follower)"]
        end
        subgraph Broker2["Broker 2"]
            T1P1["Topic-A / P1(Leader)"]
            T1P0R["Topic-A / P0(Follower)"]
        end
        subgraph Broker3["Broker 3"]
            T2P0["Topic-B / P0(Leader)"]
            T1P1R["Topic-A / P1(Follower)"]
        end
    end

    subgraph 消费者端
        CG1["Consumer Group 1\n(库存服务)"]
        CG2["Consumer Group 2\n(短信服务)"]
    end

    subgraph 元数据存储
        ZK[ZooKeeper / KRaft]
    end

    App1 -->|produce| Broker1
    App2 -->|produce| Broker2
    Broker1 -->|consume| CG1
    Broker2 -->|consume| CG2
    Broker3 -->|consume| CG2
    Controller -.->|协调| Broker1
    Controller -.->|协调| Broker2
    Controller -.->|协调| Broker3
    ZK -.->|元数据| Controller

数据流向

  1. Producer → 确定目标 Partition(分区策略)→ 发送给对应 Broker(Leader)
  2. Broker Leader 接收消息 → 写入本地日志 → 同步给 Follower
  3. Consumer → 向 Broker 拉取消息 → 处理 → 提交 Offset

四、Kafka vs RabbitMQ vs RocketMQ

对比维度KafkaRabbitMQRocketMQ
定位流处理平台 / 日志系统传统消息队列企业级消息队列
吞吐量百万级/秒万级/秒十万级/秒
消息顺序分区内有序队列内有序全局/分区有序
消息延迟毫秒级微秒级毫秒级
消息积压极强(日志存储)较弱(内存为主)较强
事务消息支持不支持支持
延迟消息不支持(需扩展)支持(插件)原生支持
运维复杂度中(需ZooKeeper/KRaft)
生态超强(大数据/流处理)较强(阿里生态)
适用场景日志采集/大数据/事件流业务解耦/任务队列电商/金融/交易系统

如何选择?

大数据量 / 日志采集 / 流处理     →  选 Kafka
对消息延迟极敏感 / 复杂路由      →  选 RabbitMQ
国内电商 / 需要延迟消息 / 事务   →  选 RocketMQ

五、Kafka 在工作中的常见应用场景

mindmap
  root((Kafka 应用场景))
    日志收集
      应用日志 → Kafka → ELK
      访问日志 → Kafka → 实时分析
    消息解耦
      订单服务 → Kafka → 库存/短信/积分
      用户注册 → Kafka → 下游多系统
    流量削峰
      秒杀请求 → Kafka → 排队处理
    实时计算
      用户行为 → Kafka → Flink → 实时推荐
    数据同步
      MySQL → Kafka → 多端数据同步(CDC)

六、面试高频追问

Q1:Kafka 的 Partition 数量设置多少合适?

参考答案

没有固定答案,需要综合考虑:

  • 吞吐量:目标吞吐量 / 单 Partition 吞吐量(约 10MB/s)= 最小分区数
  • Consumer 数量:Partition 数 ≥ 最大 Consumer 数(否则有 Consumer 闲置)
  • 文件句柄:每个 Partition 对应多个文件,过多会消耗文件描述符
  • 经验值:中小规模系统 3-12 个,大规模系统按吞吐量计算

实际建议:从 6 个开始,按需扩大(可以增加 Partition,但不能减少)。

Q2:Kafka 支持哪几种消费模式?

  1. 点对点(Queue 模式):同一 Consumer Group 内,消息只被消费一次
  2. 发布订阅(Pub-Sub 模式):不同 Consumer Group 各自消费全量消息
  3. Kafka 通过 Consumer Group 机制同时支持上述两种模式

Q3:Kafka 的 Offset 存储在哪里?

  • 旧版(0.9以前):存储在 ZooKeeper 中(性能差)
  • 新版(0.9+):存储在 Kafka 内部 Topic __consumer_offsets
  • 自定义:也可以存在 Redis / 数据库中,用于精确控制 exactly-once

Q4:为什么 Kafka 不支持主动推送,而是消费者主动拉取?

Pull 模式的优势

  • Consumer 自己控制消费速率,不会被压垮(流控友好)
  • 可以批量拉取,提升吞吐量
  • 便于重放历史消息

Pull 模式的缺点

  • 消息到达后有一定延迟(Consumer 需要轮询)
  • Kafka 通过 fetch.min.bytesfetch.max.wait.ms 实现"长轮询"来减少空轮询

📚 下一篇

Kafka入门-02-快速上手与Java示例


本文是 Kafka 系统学习路线 的第 1 篇

💬 文章评论 (0)

支持 Markdown,请友善交流
正在加载评论...