跳到主要内容

Apache Kafka 教程

欢迎学习 Apache Kafka!本教程将带你从零基础开始,全面掌握 Kafka 的核心知识和技能。

什么是 Apache Kafka?

Apache Kafka 是一个分布式事件流平台(Distributed Event Streaming Platform),由 LinkedIn 于 2011 年开源,现已成为 Apache 软件基金会的顶级项目。它专门设计用于处理实时数据流,具有高吞吐量、低延迟、高可扩展性和高容错性的特点。

核心定义

从技术角度来看,Kafka 实现了事件流(Event Streaming)的三大核心能力:

  1. 发布与订阅(Publish and Subscribe):持续捕获和处理实时事件流
  2. 存储(Storage):以持久化、容错的方式存储事件流
  3. 处理(Processing):实时或回溯性地处理事件流

Kafka 与传统消息队列的区别

特性Kafka传统消息队列(如 RabbitMQ)
架构分布式日志系统消息代理
消息持久化高性能顺序写入磁盘内存或磁盘
消息顺序分区内有序全局有序(性能代价高)
消费模式消费者组自主控制偏移量推模式(Push)
消息保留基于时间/大小,持久化存储消费后删除
扩展性水平扩展(分区/副本)垂直扩展为主
性能百万级消息/秒万级消息/秒

Kafka 的应用场景

1. 消息队列(Message Queue)

Kafka 最基本的用途是作为高性能消息队列,替代传统的消息中间件:

  • 异步处理:将耗时操作解耦,提高系统响应速度
  • 流量削峰:在流量高峰时缓存请求,平滑处理
  • 系统解耦:微服务之间通过 Kafka 进行异步通信

2. 日志聚合(Log Aggregation)

Kafka 可以收集来自不同服务的日志数据:

  • 集中式日志处理和分析
  • 实时监控告警
  • 日志持久化存储

3. 实时流处理(Real-time Stream Processing)

配合 Kafka Streams 或其他流处理框架:

  • 实时数据清洗和转换
  • 实时指标计算
  • 事件驱动架构(EDA)

4. 事件溯源(Event Sourcing)

  • 记录系统所有状态变更
  • 支持回溯和重放
  • 构建完整的审计日志

5. 变更数据捕获(CDC)

  • 监听数据库变更
  • 实时同步数据到其他系统
  • 构建数据管道

Kafka 核心概念

主题(Topic)

主题是 Kafka 中存储事件的核心抽象,类似于文件系统中的文件夹:

┌─────────────────────────────────────────────────────────────┐
│ Kafka 主题结构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Topic: user-events │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Partition 0 │ Partition 1 │ Partition 2 │ │
│ │ ┌──────────┐ │ ┌──────────┐ │ ┌──────────┐ │ │
│ │ │ Event 1 │ │ │ Event 2 │ │ │ Event 3 │ │ │
│ │ │ Event 4 │ │ │ Event 5 │ │ │ Event 6 │ │ │
│ │ └──────────┘ │ └──────────┘ │ └──────────┘ │ │
│ └─────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

主题特性:

  • 多生产者:一个主题可以有多个生产者
  • 多消费者:一个主题可以被多个消费者组独立消费
  • 持久化:消息持久化到磁盘,支持配置保留时间
  • 分区:主题可以分为多个分区,实现并行处理

生产者(Producer)

生产者负责将事件发布到 Kafka 主题:

// Java 生产者示例
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");

Producer<String, String> producer = new KafkaProducer<>(props);

// 发送消息
ProducerRecord<String, String> record = new ProducerRecord<>("user-events", "user123", "{\"action\":\"login\"}");
producer.send(record);
producer.close();

消费者(Consumer)

消费者从主题订阅和消费消息:

// Java 消费者示例
Properties props = new Properties();
props.put("bootstrap.servers", "localhost:9092");
props.put("group.id", "my-consumer-group");
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer");

KafkaConsumer<String, String> consumer = new KafkaConsumer<>(props);
consumer.subscribe(Arrays.asList("user-events"));

while (true) {
ConsumerRecords<String, String> records = consumer.poll(Duration.ofMillis(100));
for (ConsumerRecord<String, String> record : records) {
System.out.println("Received: " + record.value());
}
}

消费者组(Consumer Group)

消费者组是一组共同消费主题的消费者:

┌─────────────────────────────────────────────────────────────┐
│ 消费者组消费模型 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Topic: orders │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐ │
│ │ P0 │ │ P1 │ │ P2 │ │
│ └────┬────┘ └────┬────┘ └────┬────┘ │
│ │ │ │ │
│ └───────────┼───────────┘ │
│ ▼ │
│ ┌───────────────────────────────────────┐ │
│ │ Consumer Group: group-A │ │
│ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │
│ │ │ C0 (P0) │ │ C1 (P1) │ │ C2 (P2) │ │ │
│ │ └─────────┘ └─────────┘ └─────────┘ │ │
│ └───────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌───────────────────────────────────────┐ │
│ │ Consumer Group: group-B │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ C0 (P0) │ │ C1 (P1) │ │ │
│ │ └─────────┘ └─────────┘ │ │
│ └───────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘

关键特性:

  • 每个分区只能被组内一个消费者消费
  • 不同消费者组独立消费,互不影响
  • 支持消息重放(通过重置偏移量)

分区(Partition)

分区是 Kafka 实现并行和处理的核心:

  • 顺序保证:同一分区内的消息有序
  • 负载均衡:消息分布在不同分区
  • 并行消费:消费者并行消费不同分区

消息键(Key)可以决定消息发送到哪个分区:

// 使用键确保同一用户的消息在同一个分区
ProducerRecord<String, String> record = new ProducerRecord<>(
"user-events", // 主题
"user123", // 键 - 决定分区
"{\"action\":\"login\"}"
);

偏移量(Offset)

偏移量是消息在分区内的唯一标识:

┌─────────────────────────────────────────────────────────────┐
│ 分区偏移量示意 │
├─────────────────────────────────────────────────────────────┤
│ │
│ Partition 0: │
│ ┌───┬───┬───┬───┬───┬───┬───┬───┬───┐ │
│ │ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ ... │
│ └───┴───┴───┴───┴───┴───┴───┴───┴───┘ │
│ ↑ ▲ │
│ │ │ │
│ earliest latest │
│ (消费起点) (最新消息) │
│ │
│ 消费者偏移量位置: 3 │
│ 下一次消费将从 offset=3 开始 │
│ │
└─────────────────────────────────────────────────────────────┘

消费者可以控制消费位置:

  • 从头开始:earliest
  • 从最新开始:latest
  • 指定位置:指定具体的 offset

Broker 和集群

Kafka Broker 是 Kafka 集群中的服务节点:

┌─────────────────────────────────────────────────────────────┐
│ Kafka 集群架构 │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Zookeeper/KRaft │ │
│ │ (集群元数据管理) │ │
│ └─────────────────────────────────────────────────────┘ │
│ │ │
│ ┌─────────────────┼─────────────────┐ │
│ ▼ ▼ ▼ │
│ ┌───────────┐ ┌───────────┐ ┌───────────┐ │
│ │ Broker 0 │ │ Broker 1 │ │ Broker 2 │ │
│ │ Leader │ │ Follower │ │ Follower │ │
│ │ (P0, P1) │ │ (P1, P2) │ │ (P0, P2) │ │
│ └───────────┘ └───────────┘ └───────────┘ │
│ │
│ Topic: orders (3 partitions, replication factor: 3) │
│ │
└─────────────────────────────────────────────────────────────┘

每个 Broker 存储多个分区的数据,通过选举产生分区 Leader,负责处理读写请求。

复制(Replication)

Kafka 通过副本机制保证高可用性:

  • Leader 副本:处理所有读写请求
  • Follower 副本:被动复制 Leader 数据
  • ISR(In-Sync Replicas):与 Leader 保持同步的副本集合
  • Ack 配置
    • acks=0:不等待确认(高吞吐,低可靠)
    • acks=1:Leader 确认即返回(默认)
    • acks=all:所有 ISR 确认(高可靠)

Kafka 版本演进

主要版本特性

版本发布年份主要特性
0.82014复制机制引入
0.92015安全机制、新的消费者 API
0.102016Kafka Streams 引入
0.112017精确一次语义、事务支持
1.02017Kafka Streams 改进
2.02018改进的监控、安全增强
2.42019改进的复制协议
3.02021KRaft 模式(实验性)
3.42023KRaft 模式正式可用
3.72024增强的可观测性

Kafka 3.x 新特性(推荐使用)

  • KRaft 模式:不再依赖 Zookeeper,简化部署
  • 增量备份(Incremental Rebalance):减少消费者重平衡影响
  • 改进的分区管理:更平滑的分区迁移

教程目录

基础入门

核心组件

进阶内容

知识速查

学习建议

  1. 动手实践:本地搭建 Kafka 集群,动手操作
  2. 理解原理:深入理解分区、复制、偏移量等核心概念
  3. 关注性能:学习生产者/消费者调优
  4. 结合场景:结合实际业务场景学习
  5. 阅读官方文档:官方文档是最权威的参考

参考资源

准备好开始学习了吗?点击下一章开始你的 Kafka 学习之旅!