Kafka 基础介绍
一、Kafka 核心概念
1. 整体定位
Apache Kafka 是一个分布式流式平台,最初由 LinkedIn 开发,后成为 Apache 顶级项目。其核心特性包括:
- 高吞吐:每秒百万级消息处理能力;
- 持久化:基于磁盘顺序写入,支持 TB 级数据回溯;
- 高可用:多副本机制 + 自动故障转移;
- 可扩展:水平扩展 Broker 节点即可提升容量;
- 实时性:毫秒级端到端延迟。
典型应用场景:
- 日志收集与聚合(替代 Flume/ELK);
- 用户行为追踪(点击流、埋点);
- 微服务解耦与事件驱动架构;
- 实时监控与告警;
- 数据湖/仓的实时入湖(CDC 场景)。
2. 核心组件
| 组件 | 核心作用 |
|---|---|
| Topic | 消息的逻辑分类容器,所有消息必须属于某个 Topic。命名建议:业务域.实体.动作(如 order.payment.success)。 |
| Partition(分区) | Topic 的物理拆分单元。分区是 Kafka 并行度的核心 :• 每个 Partition 是一个有序、不可变的日志序列;• 分区内消息严格有序;• 分区数决定最大消费并发度;• 只能增加不能减少。 |
| Broker | Kafka 服务器节点。一个集群由多个 Broker 组成,每个 Broker 可托管多个 Topic 的多个 Partition。 |
| Producer(生产者) | 消息发送方。可指定 Key 决定分区路由,支持异步发送、幂等、事务等高级特性。 |
| Consumer(消费者) | 消息接收方。从指定 Topic 拉取消息,维护消费位移(offset)。 |
| Consumer Group(消费者组) | 多个消费者的逻辑分组:• 同一组内,每个 Partition 仅被一个 Consumer 消费(负载均衡);• 不同组可独立消费同一 Topic(广播模式)。 |
| ZooKeeper / KRaft | 元数据协调服务 :• Kafka 2.8 之前 :依赖 ZooKeeper 存储 Broker/Topic/Controller 等元数据;• Kafka 2.8+ :支持 KRaft 模式(Kafka Raft Metadata mode) ,完全去 ZooKeeper;• 截至 2026 年,新项目推荐评估 KRaft,存量系统多仍用 ZK 模式。 |
3. 消息结构(Record)
每条 Kafka 消息(Record)包含以下字段:
| 字段 | 说明 |
|---|---|
| Key | 可选。用于分区路由(相同 Key 进同一 Partition),保证局部顺序。 |
| Value | 必填。实际业务数据(如 JSON、Protobuf)。 |
| Timestamp | 消息时间戳,可由 Producer 设置或 Broker 自动生成。 |
| Headers | 元数据键值对(Kafka 0.11+),常用于传递 traceId、版本号等上下文。 |
| Offset | 分区内唯一递增 ID,由 Broker 分配,用于定位消息位置。 |
4. 分区主从(Leader/Follower)机制
- Leader Partition :每个 Partition 有且仅有一个 Leader,所有读写请求都通过 Leader。
- Follower Partition:多个副本,仅同步 Leader 数据,不对外提供服务。
- ISR(In-Sync Replicas) :
- 包含 Leader 和所有与 Leader 同步延迟在阈值内的 Follower;
- 由参数
replica.lag.time.max.ms(默认 30s)控制; - 只有 ISR 中的副本才有资格被选为新 Leader。
- Unclean Leader Election :
- 参数
unclean.leader.election.enable(默认false); - 若设为
true,允许非 ISR 副本成为 Leader → 可能丢数据; - 生产环境务必保持
false。
- 参数
5. 消息持久化与日志管理
- Kafka 将每个 Partition 存储为一组 Log Segment 文件(默认 1GB 或 7 天滚动);
- 利用 顺序 I/O + 零拷贝(sendfile) 实现高吞吐;
- 支持两种日志清理策略:
- Delete(默认):按时间或大小删除旧消息;
- Compact:保留每个 Key 的最新值(适用于状态变更场景,如用户资料更新)。
二、Kafka 基础配置(server.properties)
以下为
config/server.properties中的关键参数,生产环境务必显式配置。
| 参数 | 作用 | 默认值 | 生产建议 |
|---|---|---|---|
broker.id |
Broker 唯一标识(整数) | 0 | 集群内唯一 |
listeners |
Broker 监听地址 | PLAINTEXT://:9092 | 如 PLAINTEXT://192.168.1.10:9092 |
zookeeper.connect |
ZooKeeper 地址(ZK 模式) | localhost:2181 | 如 zk1:2181,zk2:2181/kafka |
num.partitions |
新建 Topic 默认分区数 | 1 | ≥3 |
default.replication.factor |
新建 Topic 默认副本数 | 1 | ≥3(≤ Broker 数) |
auto.create.topics.enable |
是否自动创建 Topic | true | false(防误操作) |
log.dirs |
数据存储目录 | /tmp/kafka-logs | 使用专用磁盘,如 /data/kafka |
offsets.topic.replication.factor |
__consumer_offsets 副本数 |
1 | ≥3 |
min.insync.replicas |
最小同步副本数 | 1 | 2(当 replication.factor=3) |
log.retention.hours |
消息保留时间(小时) | 168(7天) | 按业务需求调整 |
delete.topic.enable |
是否允许删除 Topic | true | true(确保可清理) |
可靠性三要素(Producer + Broker):
acks=allreplication.factor≥3min.insync.replicas=2
三、Kafka 命令行实操
启动集群(ZooKeeper 模式)
bash
# 1. 启动 ZooKeeper
bin/zookeeper-server-start.sh config/zookeeper.properties
# 2. 启动 Kafka Broker
bin/kafka-server-start.sh config/server.properties
注意 :KRaft 模式启动方式不同,需使用
kafka-storage.sh和kafka-server-start.sh --config ...。
1. Topic 管理
(1)创建 Topic
bash
bin/kafka-topics.sh --create \
--topic user_events \
--bootstrap-server localhost:9092 \
--partitions 6 \
--replication-factor 3
(2)查看 Topic 列表
bash
bin/kafka-topics.sh --list --bootstrap-server localhost:9092
(3)查看 Topic 详情
bash
bin/kafka-topics.sh --describe --topic user_events --bootstrap-server localhost:9092
# 输出包含:Partition、Leader、Replicas、ISR
(4)增加分区( 仅能增加)
bash
bin/kafka-topics.sh --alter \
--topic user_events \
--bootstrap-server localhost:9092 \
--partitions 9
警告 :扩容后,相同 Key 可能被路由到新分区,破坏顺序性!
(5)删除 Topic
bash
bin/kafka-topics.sh --delete --topic user_events --bootstrap-server localhost:9092
2. 消息生产与消费
(1)生产者(Console)
bash
bin/kafka-console-producer.sh --topic user_events --bootstrap-server localhost:9092
> {"userId":"1001","event":"login"}
> {"userId":"1002","event":"logout"}
(2)消费者(Console)
bash
# 从最新开始
bin/kafka-console-consumer.sh --topic user_events --bootstrap-server localhost:9092
# 从头开始(含历史)
bin/kafka-console-consumer.sh --topic user_events --bootstrap-server localhost:9092 --from-beginning
# 指定消费者组
bin/kafka-console-consumer.sh --topic user_events --bootstrap-server localhost:9092 --group my-group --from-beginning
3. 消费者组管理
(1)列出所有消费者组
bash
bin/kafka-consumer-groups.sh --list --bootstrap-server localhost:9092
(2)查看组消费状态(含 Lag)
bash
bin/kafka-consumer-groups.sh --describe --group my-group --bootstrap-server localhost:9092
# 关注:CURRENT-OFFSET, LOG-END-OFFSET, LAG
(3)重置消费位移(运维必备)
bash
# 重置到最早
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--group my-group --reset-offsets --to-earliest --execute --topic user_events
# 重置到指定时间
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 \
--group my-group --reset-offsets --to-datetime "2026-03-01T00:00:00.000" --execute --topic user_events
4. 集群元信息查看(ZooKeeper 模式)
bash
# 查看活跃 Broker
bin/zookeeper-shell.sh localhost:2181 ls /brokers/ids
# 查看 Controller Broker
bin/zookeeper-shell.sh localhost:2181 get /controller
四、SpringBoot 集成 Kafka
1. Maven 依赖(pom.xml)
xml
<dependency>
<groupId>org.springframework.kafka</groupId>
<artifactId>spring-kafka</artifactId>
<!-- Spring Boot 2.7+ 对应 spring-kafka 2.9+ -->
</dependency>
2. 核心配置(application.yml)
yaml
spring:
kafka:
producer:
bootstrap-servers: localhost:9092
key-serializer: org.apache.kafka.common.serialization.StringSerializer
value-serializer: org.apache.kafka.common.serialization.StringSerializer
retries: 2147483647 # Integer.MAX_VALUE,配合幂等
enable-idempotence: true # 幂等生产者(防重复)
acks: all # 所有 ISR 副本确认
batch-size: 16384
linger-ms: 5
consumer:
bootstrap-servers: localhost:9092
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
group-id: user-event-consumer
auto-offset-reset: earliest
enable-auto-commit: false # 关闭自动提交
max-poll-records: 500 # 单次拉取最大记录数
listener:
ack-mode: manual_immediate # 手动立即提交
concurrency: 6 # ≈ 分区数
3. 生产者代码(带 Key 与回调)
java
@Component
public class KafkaProducer {
@Resource
private KafkaTemplate<String, String> kafkaTemplate;
// 按 userId 分区,保证同一用户事件有序
public void sendUserEvent(String userId, String eventJson) {
kafkaTemplate.send("user_events", userId, eventJson)
.addCallback(
success -> log.info("发送成功: partition={}, offset={}",
success.getRecordMetadata().partition(),
success.getRecordMetadata().offset()),
failure -> log.error("发送失败", failure)
);
}
}
4. 消费者代码(手动提交 + DLQ)
java
@Component
public class KafkaConsumer {
@Resource
private KafkaTemplate<String, String> kafkaTemplate;
@KafkaListener(topics = "user_events", groupId = "user-event-consumer")
public void consume(ConsumerRecord<String, String> record, Acknowledgment ack) {
try {
// 业务处理
processEvent(record.key(), record.value());
ack.acknowledge(); // 成功则提交
} catch (BusinessException e) {
// 永久错误:发往死信队列
kafkaTemplate.send("user_events.dlq", record.key(), record.value());
ack.acknowledge(); // 避免阻塞
} catch (Exception e) {
// 瞬时错误:不 ack,下次重试(需配合 retry)
log.warn("消费异常,将重试", e);
throw e; // 触发 listener retry
}
}
private void processEvent(String userId, String event) {
// 业务逻辑
}
}
5. 批量消费(高吞吐场景)
java
@KafkaListener(topics = "user_events")
public void consumeBatch(List<ConsumerRecord<String, String>> records, Acknowledgment ack) {
// 批量处理
records.forEach(this::processEvent);
ack.acknowledge();
}
需配置
max-poll-records: 1000控制批量大小。
五、关键原则与最佳实践
1. 可靠性三原则
| 目标 | 实现方式 |
|---|---|
| 不丢消息 | Producer: acks=all + 幂等Broker: replication.factor≥3, min.insync.replicas=2Consumer: 手动提交 offset |
| 不重复消费 | Consumer 业务幂等 或 使用 Kafka 事务(Exactly-Once) |
| 顺序性 | 仅保证单分区内有序;全局有序需单分区(牺牲吞吐) |
2. 分区设计建议
- 初始分区数 ≥ 3;
- 预估未来 1~2 年吞吐,避免频繁扩容;
- 使用有意义的 Key(如 userId)保证局部顺序。
3. 监控指标(必看)
- Broker :
UnderReplicatedPartitions(应为 0) - Consumer :
records-lag-max(积压量) - Producer :
record-error-rate
六、KRaft 模式简介(Kafka 2.8+)
- 目标:完全移除 ZooKeeper 依赖;
- 优势:简化架构、提升元数据一致性、更快启动;
- 状态 :自 Kafka 3.3 起 KRaft 成为默认模式;
- 迁移建议 :
- 新项目:直接使用 KRaft;
- 老项目:谨慎评估迁移成本,可长期运行 ZK 模式。
总结
- 核心模型:Topic(逻辑)→ Partition(物理)→ Leader/Follower(高可用);
- 可靠性基石 :
acks=all+ 多副本 + 手动提交 offset; - 顺序性边界:仅单分区内有序,Key 决定路由;
- 生产规范:关闭自动创建 Topic、显式设置副本/分区、监控 Lag;
- 未来方向:关注 KRaft 模式演进,逐步去 ZooKeeper。