繁体   English   中英

Kubernetes 上的 Kafka 流:重新部署后的长时间重新平衡

[英]Kafka Streams on Kubernetes: Long rebalancing after redeployment

问题

我们使用 StatefulSet 在 Kubernetes 上部署 Scala Kafka Streams 应用程序。 这些实例具有单独的applicationId ,因此它们每个都复制完整的输入主题以实现容错。 它们本质上是只读服务,仅读取 state 主题并将其写入 state 存储区,从该存储区通过 REST 处理客户请求。 这意味着,在任何给定时间,消费者组始终只包含一个 Kafka Streams 实例

我们现在的问题是,当触发滚动重启时,每个实例大约需要 5 分钟才能启动,其中大部分时间都花在了REBALANCING state 中等待。 我在这里读到 Kafka Streams 不会发送LeaveGroup请求以便在容器重新启动后快速返回,而无需重新平衡。 为什么这对我们不起作用?为什么重新平衡需要这么长时间,即使applicationId是相同的? 理想情况下,为了最大限度地减少停机时间,应用程序应该立即从它重新启动时离开的位置接管。

配置

以下是我们从默认值更改的一些配置:

properties.put(StreamsConfig.consumerPrefix(ConsumerConfig.MAX_POLL_RECORDS_CONFIG), "1000")
properties.put(StreamsConfig.consumerPrefix(ConsumerConfig.SESSION_TIMEOUT_MS_CONFIG), "300000")
properties.put(StreamsConfig.consumerPrefix(ConsumerConfig.AUTO_OFFSET_RESET_CONFIG), "earliest")
// RocksDB config, see https://docs.confluent.io/current/streams/developer-guide/memory-mgmt.html
properties.put(StreamsConfig.ROCKSDB_CONFIG_SETTER_CLASS_CONFIG, classOf[BoundedMemoryRocksDBConfig])    

问题/相关配置

  • 减少session.timeout.ms会有所帮助吗? 我们将其设置为相当大的值,因为 Kafka 代理位于不同的数据中心,并且网络连接有时不是超级可靠。
  • 这个答案建议减少max.poll.interval.ms ,因为它与重新平衡超时有关。 那是对的吗? 我犹豫要不要更改它,因为它可能会对我们应用程序的正常运行模式产生影响。
  • 提到了一个配置group.initial.rebalance.delay.ms在部署期间延迟重新平衡 - 但这也会在从崩溃中恢复后导致延迟,不是吗?
  • 我还偶然发现了KIP-345 ,它旨在完全通过group.instance.id消除 static 会员资格的消费者再平衡,这非常适合我们的用户案例,但它似乎还没有在我们的经纪人上可用。

我对大量配置以及如何使用它们在更新后启用快速恢复感到困惑。 谁能解释一下他们是怎么一起玩的?

您引用的另一个问题并没有说在重新启动时避免重新平衡。 不发送LeaveGroupRequest只会在您停止应用程序时避免重新平衡。 因此,重新平衡的数量从两个减少到一个。 当然,对于你有点不寻常的单实例部署,你在这里没有任何收获(事实上,它实际上可能会“伤害”你......)a

减少 session.timeout.ms 会有所帮助吗? 我们将其设置为相当大的值,因为 Kafka 代理位于不同的数据中心,并且网络连接有时不是超级可靠。

可能是,取决于您重新启动应用程序的速度。 (下面有更多详细信息。)也许只是尝试一下(即,将其设置为 3 分钟以仍然具有较高的稳定性值,并看到重新平衡时间下降到 3 分钟?

这个答案建议减少 max.poll.interval.ms,因为它与重新平衡超时有关。 那是对的吗? 我犹豫要不要更改它,因为它可能会对我们应用程序的正常运行模式产生影响。

max.poll.interval.ms也会影响重新平衡时间(下面有更多详细信息)。 但是,默认值为 30 秒,因此不应导致 5 分钟的重新平衡时间。

提到了一个配置 group.initial.rebalance.delay.ms 在部署期间延迟重新平衡 - 但这也会在从崩溃中恢复后导致延迟,不是吗?

这仅适用于空消费者组,默认值仅为 3 秒。 所以它不应该影响你。

我还偶然发现了 KIP-345,它旨在完全通过 group.instance.id 消除 static 会员资格的消费者重新平衡,这非常适合我们的用户案例,但它似乎还没有在我们的经纪人上可用。

使用 static 组成员身份实际上可能是最好的选择。 也许值得升级您的经纪人以获得此功能。

顺便说一句, session.timeout.msmax.poll.interval.ms之间的区别在另一个问题中解释: Difference between session.timeout.ms and max.poll.interval.ms for Kafka 0.10.0.0 and later versions

通常,代理端组协调器维护每个“组生成”所有成员的列表。 如果成员主动离开组(通过发送LeaveGroupRequest )、超时(通过session.timeout.msmax.poll.interval.ms )或新成员加入组,则会触发重新平衡。 如果发生重新平衡,每个成员都有机会重新加入该组以包含在下一代中。

对于您的情况,该组只有一名成员。 当您停止应用程序时,不会发送LeaveGroupRequest ,因此组协调器仅在session.timeout.ms过去后才会删除此成员。

如果您重新启动应用程序,它会作为“新”成员返回(从组协调员的角度来看)。 这将触发重新平衡,使该组的所有成员都可以更改以重新加入该组。 对于您的情况,“旧”实例可能仍在组中,因此重新平衡只会在组协调器从组中删除旧成员后继续进行。 问题可能是,组协调员认为该组从一个成员扩展到两个成员......(这就是我上面的意思:如果发送LeaveGroupRequest ,当您停止应用程序时,该组将变为空,并且在重新启动时,只有新成员会在组中,并且重新平衡将立即进行。)

使用 static 组成员身份可以避免该问题,因为在重新启动时,可以将实例重新识别为“旧”实例,并且组协调器不需要等待旧组成员过期。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM