Apache Kafka 教程
欢迎学习 Apache Kafka!本教程将带你从零基础开始,全面掌握 Kafka 的核心知识和技能。
什么是 Apache Kafka?
Apache Kafka 是一个分布式事件流平台(Distributed Event Streaming Platform),由 LinkedIn 于 2011 年开源,现已成为 Apache 软件基金会的顶级项目。它专门设计用于处理实时数据流,具有高吞吐量、低延迟、高可扩展性和高容错性的特点。
核心定义
从技术角度来看,Kafka 实现了事件流(Event Streaming)的三大核心能力:
- 发布与订阅(Publish and Subscribe):持续捕获和处理实时事件流
- 存储(Storage):以持久化、容错的方式存储事件流
- 处理(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.8 | 2014 | 复制机制引入 |
| 0.9 | 2015 | 安全机制、新的消费者 API |
| 0.10 | 2016 | Kafka Streams 引入 |
| 0.11 | 2017 | 精确一次语义、事务支持 |
| 1.0 | 2017 | Kafka Streams 改进 |
| 2.0 | 2018 | 改进的监控、安全增强 |
| 2.4 | 2019 | 改进的复制协议 |
| 3.0 | 2021 | KRaft 模式(实验性) |
| 3.4 | 2023 | KRaft 模式正式可用 |
| 3.7 | 2024 | 增强的可观测性 |
Kafka 3.x 新特性(推荐使用)
- KRaft 模式:不再依赖 Zookeeper,简化部署
- 增量备份(Incremental Rebalance):减少消费者重平衡影响
- 改进的分区管理:更平滑的分区迁移
教程目录
基础入门
核心组件
进阶内容
- 副本机制 - 数据复制和高可用
- Kafka Streams - 流处理框架
- Kafka Connect - 数据集成
- 安全配置 - 认证和授权
- 监控运维 - 性能调优和监控
知识速查
- 速查表 - Kafka 常用命令速查
学习建议
- 动手实践:本地搭建 Kafka 集群,动手操作
- 理解原理:深入理解分区、复制、偏移量等核心概念
- 关注性能:学习生产者/消费者调优
- 结合场景:结合实际业务场景学习
- 阅读官方文档:官方文档是最权威的参考
参考资源
准备好开始学习了吗?点击下一章开始你的 Kafka 学习之旅!