我遇到Kafka流的奇怪分配行为。我有Kafka流的3节点集群。我的流非常简单,一个源主题(24个分区,所有kafka代理都运行在kafka流节点以外的其他机器上),我们的流图只接收消息,按键分组,执行一些过滤,并将所有内容存储到下沉主题。每个节点上都有2个Kafka线程。
然而,每当我在滚动更新我的kafka流时(通过关闭总是只有一个应用程序,所以其他两个节点正在运行),我的kafka流以每个"节点"的分区数量不均匀结束(通常是16:9 -0)。只有当我重新启动node01时,有时node02集群才会恢复到更均匀的状态。
谁能建议任何提示,我如何才能实现更平等的分配之前,额外的重启?
我假设运行kafka流应用程序的两个节点具有相同的组id。
我建议您检查一下您的消费者使用的分区分配策略是否不是org.apache.kafka.clients.consumer.RangeAssignor
。
如果是这种情况,配置为org.apache.kafka.clients.consumer.RoundRobinAssignor
。这样,当组协调器接收到JoinGroup请求并将分区移交给组领导时,组领导将确保节点之间的分布不均匀超过1。
除非你使用的是旧版本的Kafka流,否则默认值是Range,并且不能保证甚至在消费者之间传播。
你的Kafka Streams应用是有状态的吗?如果是这样,您可能要感谢这个善意的KIP: https://cwiki.apache.org/confluence/display/KAFKA/KIP-441%3A+Smooth+Scaling+Out+for+Kafka+Streams
如果你想覆盖这个行为,你可以设置acceptable.recovery.lag=9223372036854775807
(Long.MAX_VALUE)。
该配置的定义来自https://docs.confluent.io/platform/current/streams/developer-guide/config-streams.html#acceptable-recovery-lag
一个实例被认为可以赶上并能够接收活动任务的最大可接受延迟(从变更日志中赶上的偏移总数)。流只将有状态的活动任务分配给状态存储在可接受的恢复延迟范围内(如果存在)的实例,并为尚未赶上的实例分配预热副本以在后台恢复状态。对于给定的工作负载,应该对应于远低于一分钟的恢复时间。必须至少为0。