当使用带有Changelog的RocksDb状态存储时,Kafka Stream能提供哪些保证?

时间:2018-08-31 12:32:54

标签: apache-kafka-streams stream-processing

我正在构建一个Kafka Streams应用程序,该应用程序通过将每个新计算出的对象与最后一个已知对象进行比较来生成更改事件。

因此,对于输入主题上的每条消息,我都会更新状态存储中的一个对象,并不时地(使用标点符号)对这个对象进行计算,并将结果与​​先前的计算结果进行比较(来自另一个州立商店)。

为确保此操作的一致性,我在标点触发之后执行以下操作:

  1. 将元组写入状态存储
  2. 比较这两个值,创建更改事件并context.forward。因此,事件进入结果主题。
  3. 用new_value交换元组并将其写入状态存储

我将这个元组用于应用程序崩溃或重新平衡的情况,因此我可以在继续之前始终发出正确的事件集。

现在,我注意到结果事件并不总是一致的,尤其是在应用程序频繁重新平衡的情况下。在极少数情况下,Kafka Streams应用程序向事件主题发出事件,但changelog主题尚未更新。换句话说,我对结果主题产生了一些影响,但是我的变更日志主题尚未处于同一状态。

因此,当我执行stateStore.put()并且方法调用成功返回时,是否可以保证它何时会出现在changelog主题上?

我可以强制执行变更日志刷新吗?当我执行context.commit()时,何时刷新+提交会发生?

process flow

1 个答案:

答案 0 :(得分:2)

要获得完全的一致性,您将需要启用processing.guarantee="exaclty_once";否则,如果存在潜在的错误,可能会导致结果不一致。

如果您想呆在“ at_least_once”上,则可能要使用一个商店,并在处理完成后(即,在调用forward()之后更新 )。这样可以最小化获得不一致的时间窗口。

是的,如果您调用context.commit(),则在提交输入主题偏移之前,所有存储都将被刷新到磁盘,并且所有未决的生产者写也将被刷新。