2. Kafka 核心概念回顾:Topic、Partition、Offset、Consumer Group、Rebalance 机制
在深入消息重试与故障恢复策略之前,必须重新校准对 Kafka 基础数据模型的认知。这些概念不仅是 Kafka 的基石,更是后续设计重试拓扑、控制消费位移、处理分区故障时的直接操作对象。本节将围绕五个核心概念展开,重点厘清它们在分布式环境下的协作关系。
2.1 Topic 与 Partition:逻辑分类与物理分片
Topic(主题) 是 Kafka 中消息的逻辑分类单元,生产者将消息发送到特定 Topic,消费者从 Topic 拉取消息。一个 Topic 可以被零个、一个或多个消费者订阅。
Partition(分区) 是 Topic 的物理分片,每个 Topic 至少包含一个 Partition。Partition 内部的消息是有序的、不可变的,且每个消息被分配一个唯一的 Offset(偏移量)。Partition 的存在使得 Kafka 能够水平扩展:
- 并行度:一个 Partition 只能被同一个 Consumer Group 中的一个消费者线程消费,因此 Partition 数量决定了消费端的最大并行度。
- 冗余与故障转移:每个 Partition 可以有多个副本(Replica),分布在不同的 Broker 上。Leader 副本负责读写,Follower 副本负责同步。
2.2 Offset:消息的唯一坐标
Offset(偏移量) 是 Partition 内每条消息的唯一、递增的整数标识符。消费者通过提交 Offset 来记录自己的消费进度。Offset 的管理方式直接影响消息重试和故障恢复的可靠性:
| Offset 管理方式 | 提交时机 | 适用场景 | 重试风险 |
|---|---|---|---|
| 自动提交(enable.auto.commit=true) | 周期性(auto.commit.interval.ms) | 非关键日志、监控数据 | 高:消费后未处理即提交,重试时消息已丢失 |
| 手动同步提交 | 处理完成后立即提交 | 核心业务、需要精确一次语义 | 低:提交前崩溃可重新消费 |
| 手动异步提交 | 处理完成后异步回调提交 | 高吞吐、允许少量重复 | 中:回调失败可能导致重复消费 |
2.3 Consumer Group:消费的负载均衡单元
Consumer Group(消费者组) 是 Kafka 实现点对点(Queue)和发布订阅(Pub/Sub)两种模型的关键机制。同一个 Group 内的消费者共同消费一个 Topic 的消息,每条消息只会被 Group 内的一个消费者实例处理。
Consumer Group 的核心特性:
- 负载均衡:Group 内的消费者自动分配 Partition,每个 Partition 只分配给一个消费者。
- 水平伸缩:增加消费者实例可以提升消费吞吐量,但消费者数不能超过 Partition 总数,否则会有空闲消费者。
- 故障隔离:一个消费者崩溃后,其负责的 Partition 会被重新分配给 Group 内其他存活的消费者。
2.4 Rebalance 机制:分区的重新分配
Rebalance(再均衡) 是 Consumer Group 内部分区所有权从一个消费者转移到另一个消费者的协议。Rebalance 是 Kafka 实现消费端高可用的核心机制,但也是导致消费停滞和重复消费的主要来源。
触发 Rebalance 的典型场景:
- 消费者加入或离开 Group:新消费者启动、旧消费者崩溃或主动关闭。
- Topic 分区数变更:管理员增加 Topic 的 Partition 数量。
- 订阅 Topic 变更:消费者动态修改订阅的 Topic 列表。
- 心跳超时:消费者在 session.timeout.ms 内未发送心跳,协调器认为其已死亡。
Rebalance 的两种主要策略:
| 策略 | 分配方式 | 优点 | 缺点 |
|---|---|---|---|
| Range(范围分配) | 按 Topic 的 Partition 范围顺序分配 | 实现简单,每个 Topic 独立分配 | 可能导致分配不均,消费者数变化时影响范围大 |
| RoundRobin(轮询分配) | 所有 Topic 的 Partition 统一轮询分配给消费者 | 分配更均匀,适合多 Topic 订阅 | 消费者数变化时所有 Partition 需重新分配 |
| Sticky(粘性分配) | 尽量保持已有分配不变,只移动必要的 Partition | 减少 Rebalance 期间的数据移动和重复消费 | 实现复杂,Kafka 2.4+ 默认使用 |
2.5 概念协作关系总结
上述五个概念在 Kafka 消息重试与故障恢复中协同工作,形成以下核心链路:
- 生产者 将消息写入 Topic 的某个 Partition,消息获得唯一的 Offset。
- Consumer Group 中的消费者实例通过 Rebalance 机制获得 Partition 的消费权。
- 消费者从 Partition 拉取消息,按 Offset 顺序处理。处理失败时,将消息(携带原始 Offset 和元数据)写入 重试 Topic。
- 重试 Topic 的 Partition 由 重试 Consumer Group 消费,重试逻辑独立于主流程。
- 当消费者崩溃或加入/离开 Group 时,Rebalance 重新分配 Partition,新消费者从上次提交的 Offset 继续消费。