分区处理卡住,直到在 Kafka Streams 中重新平衡期间重建状态存储

Partitions processing stuck until state store is rebuilt during rebalancing in Kafka Streams

假设我有一个有状态的 Kafka Streams 应用程序,它使用来自具有 3 个分区的主题的数据。目前我有上述应用程序的 2 个实例 运行。让我们这样说:instance1 分配了分区 part1part2instance2 分配了 part3.

所以现在我想添加新实例以完全利用并行化。

据我了解,一旦我启动一个新实例,就会发生重新平衡:分区 part1part2 之一和相应的本地状态存储将从现有实例迁移到新添加的实例。在此示例中,假设 part1instance3.

上迁移

同时,我意识到新实例instance3在从变更日志主题恢复本地状态存储之前不会开始处理新数据,这可能需要很多时间。

从启动应用程序到恢复状态存储期间:

添加新实例时的重新平衡是在消费者组级别进行的。这意味着分配给消费者组的所有消费者的所有分区将被撤销,然后重新分配。因此所有分区 - part1、part2 和 part3 将被卡住,直到重新平衡完成。

现在估计停机时间有点棘手。您可以在重新平衡触发器和消费开始时发出事件 - 然后计算两个事件之间的时间差以估计停机时间。如果您有一个简单的 java 消费者日志,您还可以得到一个粗略的估计,因为所有相关日志(已撤销的分区以及已分配的分区)都已经存在。

重新平衡随着最近的版本而发展:

从版本 2.4.0 开始 KIP-429

  • 添加了增量合作再平衡,而不是停止世界再平衡协议
  • 针对掉队的成员(例如,当 Pod 挂掉并重新启动时)更好的重新平衡行为,针对云进行了优化
  • 如果组协调器再次将同一分区重新分配给消费者,则消费者无需撤销分区

=> part2part3没有卡住继续处理

从版本 2.6.0 开始 KIP-441

  • 改进 Kafka Streams 横向扩展行为,尤其是对于有状态任务
  • 之前一些任务在处理中被阻止,直到状态存储被重建,这可能需要几个小时
  • 现在新实例首先尝试从更改日志中获取状态存储,然后才将任务设为活动状态
  • 扩展期间没有停机时间

=> part1 继续在 instance1 上处理,直到 instance3 重建 part1 的状态存储并准备好移交其处理