KStream-KTable LeftJoin,未完全加载KTable时发生联接

时间:2020-04-27 21:06:08

标签: apache-kafka apache-kafka-streams

我正在尝试使用KStream-KTable leftJoin来丰富主题A中带有主题B的项目。主题A是我的KStream,主题B是我的KTtable,它具有大约2300万条记录。这两个主题的键都没有计算,因此我必须使用reducer将KStream(主题B)转换为KTable。

这是我的代码:

KTable<String, String> ktable = streamsBuilder
     .stream("TopicB", Consumed.withTimestampExtractor(new customTimestampsExtractor()))
     .filter((key, value) -> {...})
     .transform(new KeyTransformer()) // generate new key
     .groupByKey()
     .reduce((aggValue, newValue) -> {...});

streamBuilder
     .stream("TopicA")
     .filter((key, value) -> {...})
     .transform(...)
     .leftJoin(ktable, new ValueJoiner({...}))
     .transform(...)
     .to("result")

1)KTable初始化缓慢。 (大约2000 msg / s),这正常吗?我的主题是只有1个分区。有什么方法可以改善效能吗? 我尝试将以下内容设置为重新写入吞吐量,但似乎并没有改善很多。

CACHE_MAX_BYTES_BUFFERING_CONFIG = 10 * 1024 * 1024
COMMIT_INTERVAL_MS_CONFIG = 15 * 1000

2)当未从主题B加载KTable时,将发生联接。 这是发生连接时的偏移量(CURRENT-OFFSET / LOG-END-OFFSET)

   Topic A: 32725/32726 (Lag 1)
   Topic B: 1818686/23190390 (Lag 21371704)

我检查了失败的主题A记录的时间戳记,它是4天前的记录,而处理的主题B的最后记录是6天前。 据我了解,kstream进程基于时间戳记录,我不明白为什么在我的情况下,KStream(Topic A)没有等到KTable(Topic B)完全加载到4天前触发加入。

我还尝试将时间戳记提取器设置为返回0,但它也不起作用。

已更新:将时间戳设置为0时,出现以下错误:

Caused by: org.apache.kafka.common.errors.UnknownProducerIdException: This exception is raised by the broker if it could not locate the producer metadata associated with the producerId in question. This could happen if, for instance, the producer's records were deleted because their retention time had elapsed. Once the last records of the producerID are removed, the producer's metadata is removed from the broker, and future appends by the producer will return this exception. 

我也尝试将max.task.idle.ms设置为> 0(3秒和30分钟),但是仍然遇到相同的错误。

已更新:我通过将customTimestampsExtractor设置为6天前(仍早于主题A的记录)来解决“ UnknownProducerIdException”错误。我认为(不确定)将其设置为0会在导致该错误的变更日志上保留触发器。但是,在ktable完成加载之前,join仍然无法正常工作。为什么呢?

我正在使用Kafka Streams 2.3.0。

我在这里做错什么了吗?非常感谢。

1 个答案:

答案 0 :(得分:1)

1。KTable初始化缓慢。 (大约2000 msg / s),这正常吗?

这取决于您的网络,我认为限制是TopicB的使用率,您使用的两个配置CACHE_MAX_BYTES_BUFFERING_CONFIGCOMMIT_INTERVAL_MS_CONFIG是在选择KTable的输出量之间进行权衡您想要产生(因为KTable更新日志是修订流)以及将KTable更新到基础主题和下游处理器时所接受的延迟时间。详细了解Tables, Not Triggers的{​​{3}}和Kafka Streams caching config for state store部分。

我认为增加TopicB消耗率的好方法是添加更多分区。

  1. KStream.leftJoin(KTable,...)始终是表查询,它始终将当前流记录与KTable上的最新更新记录连接在一起,在决定是否连接时不会考虑流时间。如果要在加入时考虑流时间,请查看this blog

在您的情况下,此延迟是TopicB的延迟,这并不意味着KTable未完全加载。在实际运行流应用之前,从KTable的基础changelog主题读取KTable以恢复当前状态时,处于状态还原过程中的KTable尚未完全加载,以防万一您无法执行连接,因为运行直到状态完全恢复。

相关问题