我的应用程序有一些聚合/窗口操作,因此它有一些存储在state.dir
中的状态存储。 AFAIK,它还将状态存储的更改日志写入代理,
那么可以将Kafka Stream应用程序视为无状态POD吗?
答案 0 :(得分:18)
我的应用程序有一些聚合/窗口操作,因此它有一些存储在
state.dir
中的状态存储。 AFAIK,它还将状态存储的更改日志写入代理,因此可以将Kafka Stream应用程序视为无状态POD吗?
无状态容器和数据安全(=无数据丢失):是的,就数据安全而言,您可以将应用程序视为无状态容器;即使无论发生什么事情,Kafka和Kafka Streams保证您不会丢失数据(如果您已经启用了一次处理,他们也会保证后者)。
这是因为,正如您已经说过的,应用程序中的状态更改始终通过相应状态存储的更改日志持续备份到Kafka(代理) - 除非您明确禁用此更改日志功能(已启用)默认情况下)。
注意:如果您不使用Kafka的Streams默认存储引擎(RocksDB),而是替代的内存存储引擎,则上述情况甚至是正确的。很多人都没有意识到这一点,因为他们在内存中阅读了#34;并且(错误地)得出结论"当机器崩溃,重启等时,数据将丢失。"
无状态容器和应用程序恢复/恢复时间:上述说法,您应该了解在pod重启后如何使用本地状态可能会影响应用程序的恢复/恢复时间(或者更确切地说:应用程序实例)直到它再次完全运行。
想象一下,有状态应用程序的一个实例在一台机器上运行。它将其本地状态存储在state.dir
下,并且还将持续备份其本地状态的任何更改到远程Kafka集群(代理)。
state.dir
(可能是因为它在不同的计算机上重新启动),它将通过恢复完全重建其状态来自Kafka的相关变更日志。根据您的状态大小,这可能需要几毫秒,几秒,几分钟或更长时间。只有当状态完全恢复后,它才会开始处理新数据。state.dir
(可能是因为它在相同的原始计算机上重新启动),则可以更快地恢复它可以重用所有或大部分现有的本地状态,因此只需要从关联的更改日志中恢复一个小的增量。只有当状态完全恢复后,它才会开始处理新数据。换句话说,如果您的应用程序能够重用现有的本地状态,那么这很好,因为它可以最大限度地缩短应用程序恢复时间。
无状态环境中的备用副本:但即使您运行的是无状态容器,也可以通过standby replicas配置应用程序来最小化应用程序恢复时间。 1}}设置:
<强> num.standby.replicas 强>
备用副本的数量。备用副本是本地国家商店的卷影副本。只要有足够的实例运行,Kafka Streams就会尝试创建指定数量的副本并使其保持最新状态。备用副本用于最小化任务故障转移的延迟。先前在故障实例上运行的任务首选在具有备用副本的实例上重新启动,以便可以最小化其更改日志中的本地状态存储恢复过程。
另见文档部分State restoration during workload rebalance
更新2018-08-29 :可以说,在Kubernetes上运行Kafka / Kafka Streams / KSQL最方便的选择是使用Confluent运算符或Confluent提供的Helm图表,请参阅{{3} }。 (免责声明:我为Confluent工作。)
更新2019-01-10 :还有一个Youtube视频,可以解除如何https://www.confluent.io/confluent-operator/。
答案 1 :(得分:1)
我是这么认为的。 RocksDB用于保存状态,以便在执行需要状态本身的操作时保持快速。正如您已经提到的,状态更改也存储在Kafka主题中,因此如果当前流应用程序实例失败,另一个实例(在另一个节点上)可以使用该主题重新构建本地状态并继续处理流是前一个。
答案 2 :(得分:1)
KStreams使用底层state.dir
进行本地存储。如果在同一台计算机上重新启动了pod,并且已安装该卷,则会立即从该位置进行拾取。
如果pod在另一台本地状态不可用的机器中启动,KStreams将通过重新阅读支持Kafka主题来重建状态
https://www.youtube.com/watch?v=oikZg7_vy6A的简短视频显示镜头 - 适用于Apache Kafka - 在Kubernetes上部署和扩展KStream应用程序