如何在 Kubernetes 上部署 Kafka Stream 应用?
How to deploy Kafka Stream applications on Kubernetes?
我的应用程序有一些 aggregation/window 操作,所以它有一些存储在 state.dir
中的状态存储。 AFAIK,它还将状态存储的变更日志写入代理,
那么可以将 Kafka Stream 应用程序视为无状态 POD 吗?
我也这么认为。 RocksDB 用于保存状态,以便在执行需要状态本身的操作时更快。正如您已经提到的,状态更改也存储在 Kafka 主题中,因此如果当前流应用程序实例失败,另一个实例(在另一个节点上)可以使用该主题 re-build 本地状态并继续像以前一样处理流。
KStreams 使用底层 state.dir
进行本地存储。如果 pod get 在同一台机器上重新启动,并且卷已安装,它将立即从它所在的位置获取。
如果 pod 在本地状态不可用的另一台机器上启动,KStreams 将通过 re-reading 支持 Kafka 主题
重建状态
https://www.youtube.com/watch?v=oikZg7_vy6A 上的一段短视频展示了 Lenses - 适用于 Apache Kafka - 在 Kubernetes 上部署和扩展 KStream 应用程序
My application has some aggregation/window operation, so it has some state store which stores in the state.dir
. AFAIK, it also writes the changelog of state store to the broker, so is that OK to consider the Kafka Stream application as a stateless POD?
无状态 Pod 和数据安全(= 无数据丢失): 是的,就数据安全[=而言,您可以将应用程序视为无状态 Pod 53=] 关注;也就是说,无论 Pod Kafka 发生什么,Kafka Streams 都保证您不会丢失数据(如果您启用了 exactly-once 处理,它们也会保证后者)。
那是因为,正如您已经说过的,您的应用程序中的状态更改始终通过相应状态存储的更改日志持续备份到 Kafka(代理)——除非您明确禁用此更改日志功能(默认情况下启用) ).
注意:当您使用的不是 Kafka 的 Streams 默认存储引擎 (RocksDB),而是替代的 in-memory 存储引擎时,上述情况也适用。许多人没有意识到这一点,因为他们阅读 "in-memory" 并(错误地)得出结论 "data will be lost when a machine crashes, restarts, etc."。
Stateless pod and application restoration/recovery time: 综上所述,你应该明白 vs. not-having local state 在 pod 重启后可用影响 restoration/recovery 您的应用程序(或更确切地说:应用程序实例)的时间,直到它再次完全运行。
假设您的有状态应用程序的一个实例 运行 在一台机器上。它会将其本地状态存储在 state.dir
下,并且还会不断地将对其本地状态的任何更改备份到远程 Kafka 集群(代理)。
- 如果应用程序实例正在重新启动并且没有访问其先前的
state.dir
(可能是因为它在不同的机器上重新启动),它将完全通过从 Kafka 中的相关变更日志恢复来重建其状态。根据您的状态大小,这可能需要几毫秒、几秒、几分钟或更长时间。只有在其状态完全恢复后,它才会开始处理新数据。
- 如果应用程序实例正在重新启动并且确实可以访问其先前的
state.dir
(可能是因为它是在同一台原始机器上重新启动的),它可以恢复得更快,因为它可以 re-use 全部或大部分现有本地状态,因此只需要从关联的变更日志中恢复一个小的增量。只有在其状态完全恢复后,它才会开始处理新数据。
换句话说,如果您的应用程序能够 re-use 现有的本地状态,那么这很好,因为它将最大限度地减少应用程序恢复时间。
备用副本在无状态环境中进行救援:但即使您运行宁无状态pods,您也可以选择通过以下方式最大限度地减少应用程序恢复时间通过 num.standby.replicas
设置将您的应用程序配置为使用 standby replicas:
num.standby.replicas
The number of standby replicas. Standby replicas are shadow copies of local state stores. Kafka Streams attempts to create the specified number of replicas and keep them up to date as long as there are enough instances running. Standby replicas are used to minimize the latency of task failover. A task that was previously running on a failed instance is preferred to restart on an instance that has standby replicas so that the local state store restoration process from its changelog can be minimized.
另请参阅文档部分 State restoration during workload rebalance
更新 2018-08-29:可以说,在 Kubernetes 上 运行 Kafka/Kafka Streams/KSQL 最方便的选择是使用 Confluent Operator或 Confluent 提供的 Helm 图表,请参阅 https://www.confluent.io/confluent-operator/。 (免责声明:我为 Confluent 工作。)
更新 2019-01-10:还有一个 Youtube 视频演示了如何 Scale Kafka Streams with Kubernetes。
我的应用程序有一些 aggregation/window 操作,所以它有一些存储在 state.dir
中的状态存储。 AFAIK,它还将状态存储的变更日志写入代理,
那么可以将 Kafka Stream 应用程序视为无状态 POD 吗?
我也这么认为。 RocksDB 用于保存状态,以便在执行需要状态本身的操作时更快。正如您已经提到的,状态更改也存储在 Kafka 主题中,因此如果当前流应用程序实例失败,另一个实例(在另一个节点上)可以使用该主题 re-build 本地状态并继续像以前一样处理流。
KStreams 使用底层 state.dir
进行本地存储。如果 pod get 在同一台机器上重新启动,并且卷已安装,它将立即从它所在的位置获取。
如果 pod 在本地状态不可用的另一台机器上启动,KStreams 将通过 re-reading 支持 Kafka 主题
重建状态https://www.youtube.com/watch?v=oikZg7_vy6A 上的一段短视频展示了 Lenses - 适用于 Apache Kafka - 在 Kubernetes 上部署和扩展 KStream 应用程序
My application has some aggregation/window operation, so it has some state store which stores in the
state.dir
. AFAIK, it also writes the changelog of state store to the broker, so is that OK to consider the Kafka Stream application as a stateless POD?
无状态 Pod 和数据安全(= 无数据丢失): 是的,就数据安全[=而言,您可以将应用程序视为无状态 Pod 53=] 关注;也就是说,无论 Pod Kafka 发生什么,Kafka Streams 都保证您不会丢失数据(如果您启用了 exactly-once 处理,它们也会保证后者)。
那是因为,正如您已经说过的,您的应用程序中的状态更改始终通过相应状态存储的更改日志持续备份到 Kafka(代理)——除非您明确禁用此更改日志功能(默认情况下启用) ).
注意:当您使用的不是 Kafka 的 Streams 默认存储引擎 (RocksDB),而是替代的 in-memory 存储引擎时,上述情况也适用。许多人没有意识到这一点,因为他们阅读 "in-memory" 并(错误地)得出结论 "data will be lost when a machine crashes, restarts, etc."。
Stateless pod and application restoration/recovery time: 综上所述,你应该明白 vs. not-having local state 在 pod 重启后可用影响 restoration/recovery 您的应用程序(或更确切地说:应用程序实例)的时间,直到它再次完全运行。
假设您的有状态应用程序的一个实例 运行 在一台机器上。它会将其本地状态存储在 state.dir
下,并且还会不断地将对其本地状态的任何更改备份到远程 Kafka 集群(代理)。
- 如果应用程序实例正在重新启动并且没有访问其先前的
state.dir
(可能是因为它在不同的机器上重新启动),它将完全通过从 Kafka 中的相关变更日志恢复来重建其状态。根据您的状态大小,这可能需要几毫秒、几秒、几分钟或更长时间。只有在其状态完全恢复后,它才会开始处理新数据。 - 如果应用程序实例正在重新启动并且确实可以访问其先前的
state.dir
(可能是因为它是在同一台原始机器上重新启动的),它可以恢复得更快,因为它可以 re-use 全部或大部分现有本地状态,因此只需要从关联的变更日志中恢复一个小的增量。只有在其状态完全恢复后,它才会开始处理新数据。
换句话说,如果您的应用程序能够 re-use 现有的本地状态,那么这很好,因为它将最大限度地减少应用程序恢复时间。
备用副本在无状态环境中进行救援:但即使您运行宁无状态pods,您也可以选择通过以下方式最大限度地减少应用程序恢复时间通过 num.standby.replicas
设置将您的应用程序配置为使用 standby replicas:
num.standby.replicas
The number of standby replicas. Standby replicas are shadow copies of local state stores. Kafka Streams attempts to create the specified number of replicas and keep them up to date as long as there are enough instances running. Standby replicas are used to minimize the latency of task failover. A task that was previously running on a failed instance is preferred to restart on an instance that has standby replicas so that the local state store restoration process from its changelog can be minimized.
另请参阅文档部分 State restoration during workload rebalance
更新 2018-08-29:可以说,在 Kubernetes 上 运行 Kafka/Kafka Streams/KSQL 最方便的选择是使用 Confluent Operator或 Confluent 提供的 Helm 图表,请参阅 https://www.confluent.io/confluent-operator/。 (免责声明:我为 Confluent 工作。)
更新 2019-01-10:还有一个 Youtube 视频演示了如何 Scale Kafka Streams with Kubernetes。