3. Topic与Partition
Topic 是 Kafka 中消息的逻辑分类,而 Partition 是 Kafka 实现水平扩展与高可用的核心单元。理解 Topic 的创建方式、Partition 的分区策略、副本机制以及 Leader 选举流程,是掌握 Kafka 架构的基石。本章将深入剖析这些核心概念,并结合微服务链路中的实际场景进行讲解。
3.1 Topic 的创建与管理
Topic 的创建方式分为自动创建与手动创建。在生产环境中,建议使用手动创建以精确控制分区数与副本因子。
3.1.1 创建方式对比
| 创建方式 | 触发条件 | 适用场景 | 注意事项 |
|---|---|---|---|
| 自动创建 | 生产者或消费者向不存在的 Topic 发送/拉取消息 | 开发测试环境、快速验证 | 可能因配置不当导致分区数或副本数不符合预期 |
| 手动创建 | 通过 kafka-topics.sh 脚本或 Admin API |
生产环境、微服务正式链路 | 可精确指定分区数、副本因子及配置参数 |
3.1.2 手动创建示例
# 创建一个名为 "order-events" 的 Topic,6 个分区,3 个副本
bin/kafka-topics.sh --create \
--bootstrap-server localhost:9092 \
--replication-factor 3 \
--partitions 6 \
--topic order-events \
--config cleanup.policy=delete \
--config retention.ms=604800000
微服务实践建议: 在微服务链路中,建议为每个核心业务事件(如订单创建、支付成功)创建独立的 Topic。分区数建议设置为 Broker 数量的整数倍,以便均匀分布负载。
3.2 Partition 分区策略
分区策略决定了消息被发送到哪个 Partition。合理的分区策略可以保证数据均匀分布,并支持消息的顺序性需求。
3.2.1 常见分区策略
- 轮询策略(Round-Robin): 默认策略,消息依次发送到每个 Partition,负载最均匀。
- 哈希策略(Hash): 对消息 Key 进行哈希计算,相同 Key 的消息总是进入同一 Partition,保证局部顺序。
- 粘性分区策略(Sticky Partitioner): Kafka 2.4+ 默认,减少网络开销,提高吞吐量。
- 自定义分区策略: 实现
Partitioner接口,满足业务特殊路由需求。
3.2.2 分区策略选择矩阵
| 业务需求 | 推荐策略 | 说明 |
|---|---|---|
| 全局顺序 | 单分区 Topic | 所有消息进入同一 Partition,牺牲并行度 |
| 局部顺序(按 Key) | 哈希策略 | 相同订单 ID 的消息进入同一 Partition |
| 高吞吐、无顺序要求 | 轮询 / 粘性分区 | 均匀分布,最大化并行处理能力 |
| 按业务字段路由 | 自定义分区器 | 例如按用户地域、事件类型路由 |
3.3 副本机制(Replication)
副本机制是 Kafka 高可用的核心保障。每个 Partition 可以有多个副本,分布在不同的 Broker 上。
3.3.1 副本角色
- Leader: 每个 Partition 有且仅有一个 Leader,负责处理所有读写请求。
- Follower: 被动同步 Leader 的数据,不对外提供服务。当 Leader 故障时,Follower 可被选举为新的 Leader。
- ISR(In-Sync Replicas): 与 Leader 保持同步的副本集合。只有 ISR 中的副本才有资格成为 Leader。
3.3.2 副本同步机制
Leader 收到消息后,Follower 会主动拉取(Pull)数据进行同步。只有当消息被 ISR 中所有副本确认后,才被认为“已提交”。
关键参数:
min.insync.replicas:最小 ISR 副本数,控制写入可用性。建议设置为 2。acks:生产者确认级别。acks=all 表示等待 ISR 全部确认,保证数据不丢失。
3.4 分区 Leader 选举
当 Partition 的 Leader 发生故障时,Kafka Controller 会负责从 ISR 中选举一个新的 Leader。选举过程对客户端透明,但会影响短暂的可用性。
3.4.1 选举触发条件
- Leader 所在的 Broker 宕机。
- Leader 发生网络分区,与 Controller 心跳超时。
- Leader 因异常退出(如 OOM、磁盘故障)。
3.4.2 选举流程
- 检测故障: Controller 通过 ZooKeeper 或 KRaft 心跳检测到 Leader 不可用。
- 获取 ISR 列表: Controller 从元数据中获取该 Partition 的 ISR 集合。
- 选举新 Leader: 从 ISR 中选择第一个副本作为新 Leader(按副本 ID 排序)。
- 更新元数据: Controller 将新的 Leader 信息广播给所有 Broker 和客户端。
- 恢复服务: 新 Leader 开始处理读写请求,Follower 开始从新 Leader 同步数据。
注意: 如果 ISR 为空(所有副本都不可用),Kafka 会等待第一个恢复的副本成为 Leader,但该副本可能丢失部分数据(unclean leader election)。生产环境建议关闭 unclean leader election(
unclean.leader.election.enable=false),以数据一致性优先。
3.5 微服务链路中的最佳实践
微服务链路配置建议:
- 分区数规划: 根据业务流量预估,建议分区数 = Broker 数 × 2~4,便于后续扩展。
- 副本因子: 生产环境至少 3 副本,容忍 1 个 Broker 故障;重要链路建议 3 副本 + 2 个机架。
- 分区策略: 需要保证事件顺序(如订单状态变更)时,使用订单 ID 作为 Key 进行哈希分区。
- 监控指标: 关注 UnderReplicatedPartitions、LeaderElectionRateAndTimeMs 等指标,及时发现副本同步和选举异常。