KTable到KTable的内部联接不会产生所有预期的结果(可能发生共分区问题)

时间:2019-08-27 13:49:15

标签: apache-kafka apache-kafka-streams

鉴于我有一个如下所示的拓扑:

简而言之:

  • A_Value输入A_Id

    • 成为KTable<A_Id, A_Value> store-A_Value-by-A_Id-ktable
  • 带有B_Value的流输入B_Id

    • mapValues:为了将墓碑替换为具有B_Value属性的有效deleted: true
    • groupByKeyKGroupedStream<B_Id, B_Value>
      • reduce:在这里,如果 new B_Value.isDeleted() == true,用B_Value返回 old deleted: true,则为重要,因为稍后我需要A_Id属性
      • 成为KTable<B_Id, B_Value> store-B_Value-by-B_Id-ktable
  • 输入KTable<B_Id, B_Value>

    • toStream
    • groupByB_Value.getA_Id()
      • recudeKTable<A_Id, B_Value>
  • 加入KTable<A_Id, B_Value>KTable<A_Id, A_Value>KTable<A_Id, Pair<B_Value, A_Value>>

    • toStream
    • map:如果B_Value.isDeleted() == true则传播KeyValue<B_Id, null(墓碑),否则传播KeyValue<B_Id, Pair<B_Value, A_Value>>
      • to:输出主题

在Kafka Streams拓扑中:

子拓扑:0

Source: KSTREAM-SOURCE-0000000000 (topics: [input-A_value-A_key])
  --> KTABLE-SOURCE-0000000001
Source: KSTREAM-SOURCE-0000000011 (topics: [input-B_value-A_key])
  --> KSTREAM-REDUCE-0000000008
Processor: KSTREAM-REDUCE-0000000008 (stores: [store-B-by-A_key-ktable])
  --> KTABLE-JOINTHIS-0000000013
  <-- KSTREAM-SOURCE-0000000011
Processor: KTABLE-SOURCE-0000000001 (stores: [store-A-by-A_key-ktable])
  --> KTABLE-JOINOTHER-0000000014
  <-- KSTREAM-SOURCE-0000000000
Processor: KTABLE-JOINOTHER-0000000014 (stores: [store-B-by-A_key-ktable])
  --> KTABLE-MERGE-0000000012
  <-- KTABLE-SOURCE-0000000001
Processor: KTABLE-JOINTHIS-0000000013 (stores: [store-A-by-A_key-ktable])
  --> KTABLE-MERGE-0000000012
  <-- KSTREAM-REDUCE-0000000008
Processor: KTABLE-MERGE-0000000012 (stores: [])
  --> KTABLE-TOSTREAM-0000000015
  <-- KTABLE-JOINTHIS-0000000013, KTABLE-JOINOTHER-0000000014
Processor: KTABLE-TOSTREAM-0000000015 (stores: [])
  --> KSTREAM-MAP-0000000016
  <-- KTABLE-MERGE-0000000012
Processor: KSTREAM-MAP-0000000016 (stores: [])
  --> KSTREAM-SINK-0000000017
  <-- KTABLE-TOSTREAM-0000000015
Sink: KSTREAM-SINK-0000000017 (topic: output-AB_aggregate-B_key)
  <-- KSTREAM-MAP-0000000016

子拓扑:1

Source: KSTREAM-SOURCE-0000000002 (topics: [input-B_value-B_key])
  --> KSTREAM-MAPVALUES-0000000003
Processor: KSTREAM-MAPVALUES-0000000003 (stores: [])
  --> KSTREAM-REDUCE-0000000004
  <-- KSTREAM-SOURCE-0000000002
Processor: KSTREAM-REDUCE-0000000004 (stores: [store-B_value-B_key-ktable])
  --> KTABLE-TOSTREAM-0000000005
  <-- KSTREAM-MAPVALUES-0000000003
Processor: KTABLE-TOSTREAM-0000000005 (stores: [])
  --> KSTREAM-FILTER-0000000006
  <-- KSTREAM-REDUCE-0000000004
Processor: KSTREAM-FILTER-0000000006 (stores: [])
  --> KSTREAM-KEY-SELECT-0000000007
  <-- KTABLE-TOSTREAM-0000000005
Processor: KSTREAM-KEY-SELECT-0000000007 (stores: [])
  --> KSTREAM-FILTER-0000000010
  <-- KSTREAM-FILTER-0000000006
Processor: KSTREAM-FILTER-0000000010 (stores: [])
  --> KSTREAM-SINK-0000000009
  <-- KSTREAM-KEY-SELECT-0000000007
Sink: KSTREAM-SINK-0000000009 (topic: input-B_value-A_key)
  <-- KSTREAM-FILTER-0000000010

重要的是导致这种拓扑的约束条件:

  • A中的记录从不删除
  • 来自B的记录导致删除,从而将墓碑传播到输出主题
  • 包含A条记录的主题比包含B条记录的主题大10倍
  • 输入B的值为A_Id
  • 由于一次加载了一个批处理,因此无法信任来自输入A的时间戳记,代理也不会提取时间戳记

下面列出的所有预期行为对于新的传入数据都非常有效:

  • 记录A到达,连接输出有效
  • 记录B到达,加入输出作品
  • 记录B墓碑到达,输出墓碑有效

观察到的问题发生在流媒体的第一个引导期间,在该引导中,预期的连接数(即1000)实际上为70,如果流媒体继续运行,则不会出现任何不一致的情况。 数字1000来自唯一的B记录,这些记录在我的原始主题数据中具有匹配的A记录,我还检查了转换后我所有的变更日志存储区是否都具有正确的数据,并且

我尝试了什么?

  • 将提交间隔设置为0
  • 禁用缓存
  • 对两个输入主题都使用WallclockTimestampExtractor
  • 对两个总是返回TimestampExtractor的输入主题使用自定义0
  • 使用自定义ValueTransformerWithKeySupplier代替内部连接,该内部连接的操作(基于壁和记录时间)为1秒
  • 我所做的一项测试是将所有主题设置为1个分区,然后实际上拥有所有所需的联接,因为我正在生成KTables,因此,我不理解为什么我的分区可能出错

我没有很多尝试的方法,我仍然可以尝试更深入,但是我想看看我是否在方法上首先犯了其他错误,谢谢您的帮助。

0 个答案:

没有答案