如何在部署期间实现 Kafka Streams 应用程序的高可用性?

Ism*_*mic 10 java apache-kafka apache-kafka-streams

主要问题:我们在 Kubernetes 上运行 Kafka Streams (Java) 应用程序,以在 Kafka 集群中消费、处理和生成实时数据(运行 Confluence Community Edition v7.0/Kafka v3.0)。我们如何以限制消耗记录的停机时间的方式部署应用程序?我们最初的目标是2 sec每项任务大约有一次停机时间。

我们的目标是对生产环境的更改进行持续部署,但部署的破坏性太大,会导致应用程序中的记录消耗停机,从而导致生成的实时记录出现延迟。

我们尝试了不同的策略来看看它如何影响延迟(停机时间)。

策略#1:

  • 终止所有应用实例(共6个)
  • 立即启动所有新的应用程序实例
  • 结果:测量到的消耗记录的最大延迟:85 sec

策略#2:

  • 启动一个新的应用程序实例
  • 等待3 minutes允许在新应用程序实例中恢复本地状态
  • 3 minutes终止一个旧应用程序实例后
  • 重复直到所有旧应用程序实例都终止
  • 结果:测量到的消耗记录的最大延迟:39 sec

策略#3:

  • 与策略 2 相同,但增加等待时间15 minutes
  • 结果:测量到的消耗记录的最大延迟:7 sec。但是,15 minutes每个应用程序实例将需要 15 分钟 x 6 个实例 =90 minutes部署更改 + 额外的时间30 minutes来完成增量重新平衡协议。我们发现部署时间相当过长。

我们一直在阅读KIP-429:Kafka 消费者增量再平衡协议,并尝试配置应用程序以支持我们的用例。

以下是我们为策略 #2 和策略 #3 所做的关键 Kafka Streams 配置:

acceptable.recovery.lag: 6000
num.standby.replicas: 2
max.warmup.replicas: 6
probing.rebalance.interval.ms: 60000
num.stream.threads: 2
Run Code Online (Sandbox Code Playgroud)

输入主题的平均12 partitions留言率。800 records/s有 3 个 Kafka Streams 键值状态存储,其中两个与输入主题具有相同的速率。这两个大概是20GB size. 键集的大小约为4000。理论上,每个分区的变更日志主题的延迟acceptable.recovery.lag应该是~60秒。

以下是策略 #3的每个应用实例的一些指标(上升、接收消息的速率和接收消息的延迟): 在此输入图像描述

我们所做的值得注意的观察:

1a- 第一个新应用程序实例启动

1b- Kafka 立即重新平衡,2 ​​个旧应用程序实例被分配更多任务,2 个旧应用程序实例丢失任务

1c- 同时记录的最大延迟从 增加到0.2 sec3.5 sec这表明重新平衡大约需要3 sec

2- 发生探测重新平衡,Kafka Streams 以某种方式决定撤销旧应用程序实例之一的任务,并将其交给已经拥有最多任务的实例

3- 最后一个旧应用程序实例被终止

4- 所有分区都在升级之前重新平衡,增量重新平衡完成(大约33 minutes在最后一个应用程序实例终止之后)

Other- 第一个新应用程序实例大约需要大约40 minutes时间才能分配任务。此外,每个任务都会被重新分配多次,从而导致许多小的中断3 sec

如果需要的话,我们可以提供有关其他策略的拓扑、主题、配置和指标图的更多详细信息(该线程已经很大)。

tch*_*udo 0

一些针对您的 Kafka Stream 应用程序的一般建议(不是专业人士,而是我个人观察到的)。

  1. 将您的 pod 从 Deployment 更改为 StatefulSet 并添加此配置group.instance.id: "${hostname}"。这样,pod将保持与pod相同的名称,您将能够使用Kafka消费者增量再平衡协议
  2. 当您现在使用 StatefulSet 时,将状态存储保留在永久存储中,它将删除从 Kafka 重新加载状态存储。但请注意,您需要根据 Kubernetes 收到的信号正确关闭 Kafka Stream,并调整terminationGracePeriodSeconds以允许正确关闭。如果没有,Kafka Stream 将检测到检查点不干净,并将重新获取状态存储(不太清楚您的状态存储是否已持久化,但我认为它已经完成了)。

我观察到的唯一一件事是一个简单的消费者组重新平衡比您预期的 2 秒要长,而且这似乎是一个复杂的目标(就像您所说的重新平衡需要 3 秒)。但是使用增量重新平衡,我认为您将在重新平衡期间处理一些分区(目前没有亲自测量)。