KStream和KTable之间的时间语义

时间:2019-08-14 15:56:34

标签: apache-kafka-streams

我正在尝试构建以下拓扑:

  1. 使用Debezium连接器,我拉出2个表(我们称它们为表A和DA)。根据DBZ,存储表行的主题的结构为{之前:“ ...”,之后:“ ...”}。

  2. 拓扑的第一步是从这两个“表”主题创建“干净的” KStream。那里的子拓扑大致如下:

private static KStream<String, TABLE_A.Value> getTableARowByIdStream(
    StreamsBuilder builder, Properties streamsConfig) {
  return builder
      .stream("TABLE_A", Consumed.withTimestampExtractor(Application::getRowDate))
      .filter((key, envelope) -> [ some filtering condition ] )
      .map((key, envelope) -> [ maps to TABLE_A.Value ] )
      .through(tableRowByIdTopicName);
}
  1. 请注意,我明确指定了记录时间,因为表行在最初发布后将被CDC标记为“年”。该函数当前正在执行的操作是伪造从2010-01-01开始的时间,并使用AtomicInteger为每个消耗的实体增加1毫秒。它对表A执行此操作,但对DA不执行此操作(稍后将解释原因)。

  2. 拓扑的第二阶段是基于表A的“清理”主题构建1个KTable,如下所示:

private static KTable<String, EntityInfoList> getEntityInfoListById(
    KStream<String, TABLE_A.Value> tableAByIdStream) {
  return tableAByIdStream
      .map((key, value) -> [ some mapping ] )
      .groupByKey()
      .aggregate(() -> [ builds up a EntityInfoList object ] ));
}
  1. 最后,在准备好KTable之后,我将通过DA与KStream一起加入他们,就像这样:
private static KStream<String, OutputTopicEntity> getOutputTopicEntityStream(
    KStream<String, Table_DA.Value> tableDAStream,
    KTable<String, EntityInfoList> tableA_KTable) {

  KStream<String, Table_DA>[] branches = tableDAStream.branch(
      (key, value) -> [ some logic ],
      (key, value) -> true);

  KStream<String, OutputTopicEntity> internalAccountRefStream = branches[0]
      .join(
          tableA_KTable,
          (streamValue, tableValue) -> [ some logic to build a list of OutputTopicEntity ])
      .flatMap((key, listValue) -> [ some logic to flatten it ]));

   [ similar logic with branch[1] ]
}

我的问题是,尽管事实上我在“假装”来自Table_A主题的记录(我已经验证它们使用kafkacat引用了2010/01/01)和Table_DA中的条目(流端)的连接)在今天'2019/08/14'附近有时间戳),似乎Kafka Streams不会从Table_DA KStream读取任何条目,直到将Table_A的所有记录都提取到KTable中为止。

因此,我没有我所期望的所有“加入匹配”,这也是不确定的。根据{{​​3}}的这句话,我的理解是相反的:

  

对于流表连接,Kafka Stream会根据记录时间戳顺序排列记录处理。因此,对表的更新与您的流记录保持一致。

到目前为止,我的经验是这没有发生。在使用完Table_DA流中的所有条目(它的大小恰好缩小了10倍)之后,我还可以轻松地看到我的应用程序如何继续通过Table_A主题方式进行搅动。

我做错什么了吗?

1 个答案:

答案 0 :(得分:0)

在2.1.0版本发布之前,时间戳同步是最大的努力(请参阅https://issues.apache.org/jira/browse/KAFKA-3514)。

从2.1.0版开始,时间戳严格同步。但是,如果一个输入没有任何数据,Kafka Streams将按照KIP-353中的描述“强制”处理,以避免永远阻塞。如果输入突发,并且如果一个输入没有数据,并且希望“阻止”处理一段时间,则可以通过KIP-K增大2.1.0中引入的配置参数max.task.idle.ms(默认为0)。 353。