10.4.2 消费者组与再平衡机制

消费者组(Consumer Group)是 Kafka 实现水平扩展与负载均衡的核心机制。同一组内的消费者共同消费一个或多个主题的分区,每个分区在同一时刻只会被组内一个消费者分配,从而避免重复消费并提升吞吐。不同组可以独立消费同一主题,实现多业务并行处理。

原理草图(消费者组与再平衡)#

文章图片

核心概念与分配规则#

  • 组内唯一性:同一分区在组内只分配给一个消费者。
  • 并行度上限:并行度由分区数决定,若消费者数大于分区数,会出现空闲消费者。
  • Offset隔离:每个消费组维护各自的位移,互不影响。
  • 分区分配策略:Range、RoundRobin、Sticky、CooperativeSticky(增量再平衡)。

再平衡触发场景#

  • 组内消费者实例加入或退出(正常关闭或故障宕机)
  • 订阅的主题数量变化
  • 主题分区数变化
  • 会话超时或心跳异常导致成员被踢出

再平衡流程简述#

  1. 成员变更检测:Group Coordinator 发现组成员变更或分区变更。
  2. 暂停消费:组内消费者暂停拉取并释放分区所有权。
  3. 选举 Leader:组内选举一个消费者作为 Leader 负责分配。
  4. 分配分区:Leader 按策略生成分配方案并提交。
  5. 同步与恢复:各成员获取分配结果,重新拉取并继续消费。

实战示例:启动消费者组并观察再平衡#

1) 前置准备与主题创建#

# 1. 创建主题(3分区)
$KAFKA_HOME/bin/kafka-topics.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --create --topic orders --partitions 3 --replication-factor 1

# 2. 查看主题详情
$KAFKA_HOME/bin/kafka-topics.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --describe --topic orders

2) 启动生产者写入消息#

$KAFKA_HOME/bin/kafka-console-producer.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --topic orders
# 在终端输入
# order-1
# order-2
# order-3

3) 启动两个消费者同组,观察分配#

# 终端A:消费者1
$KAFKA_HOME/bin/kafka-console-consumer.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --topic orders \
  --group cg-order \
  --property print.partition=true \
  --property print.offset=true

# 终端B:消费者2
$KAFKA_HOME/bin/kafka-console-consumer.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --topic orders \
  --group cg-order \
  --property print.partition=true \
  --property print.offset=true

预期效果:分区在两个消费者间分配;当启动/停止任一消费者时,触发再平衡,分区重新分配。

4) 查看组状态与分区分配#

$KAFKA_HOME/bin/kafka-consumer-groups.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --describe --group cg-order

关键字段解释
- CURRENT-OFFSET:当前已提交位移
- LOG-END-OFFSET:分区日志末端位移
- LAG:积压量
- CONSUMER-ID / HOST / CLIENT-ID:消费者实例标识

配置示例:优化再平衡与心跳#

文件/etc/kafka/consumer.properties

# 使用增量再平衡策略,减少全量撤销
partition.assignment.strategy=org.apache.kafka.clients.consumer.CooperativeStickyAssignor

# 会话与心跳
session.timeout.ms=10000
heartbeat.interval.ms=3000

# 拉取处理超时时间(防止处理太慢被踢出)
max.poll.interval.ms=300000

效果:降低短暂的停顿与误踢出风险,提高稳定性。

常见问题与排错#

1) 现象:消费者频繁 Rebalance,日志出现 RebalanceInProgress
- 原因:处理耗时超过 max.poll.interval.ms 或心跳异常
- 处理

# 调大 max.poll.interval.ms
# /etc/kafka/consumer.properties
max.poll.interval.ms=600000

2) 现象:有消费者空闲
- 原因:消费者数 > 分区数
- 处理:增加分区或减少消费者实例

$KAFKA_HOME/bin/kafka-topics.sh \
  --bootstrap-server 127.0.0.1:9092 \
  --alter --topic orders --partitions 6

3) 现象:LAG 持续增长
- 原因:消费能力不足或处理逻辑阻塞
- 处理:提升并行度、优化消费逻辑或扩容消费者

安装提示(客户端工具)#

# 以二进制包为例,下载并解压后设置环境变量
export KAFKA_HOME=/opt/kafka
export PATH=$KAFKA_HOME/bin:$PATH

# 验证命令可用
kafka-topics.sh --version

练习题#

1) 创建 orders 主题 3 分区,启动 2 个消费者同组,记录每个消费者分配的分区。
2) 将分区数扩容到 6,观察再平衡与分配变化,输出 kafka-consumer-groups.sh --describe 结果。
3) 将 max.poll.interval.ms 设置为 5000,模拟长时间处理(sleep 10s),观察踢出与再平衡日志。