Kafka Streams - 主题中消息数量的不一致性

时间:2018-04-25 13:44:27

标签: apache-kafka apache-kafka-streams

假设我们有一个包含1000条消息的Kafka主题。我们从中创建一个流(我们称之为st),并执行以下操作:

int count = 0;

st.groupByKey().count().foreach((key, value) -> {

       count += value)
       System.out.println(count)
});

当处理"结束"时,它返回略大于1000的数字。 什么可能导致这种奇怪的行为?

1 个答案:

答案 0 :(得分:1)

如果您的某些消息具有相同的密钥,则您的代码会重复计算。 请注意,传递给KTable上的foreach()方法的函数不是每行执行一次,而是每次更新一次执行一次(可能不会因缓存而每次更新)。请参阅:https://kafka.apache.org/11/javadoc/org/apache/kafka/streams/kstream/KTable.html#foreach-org.apache.kafka.streams.kstream.ForeachAction-

  

对此KTable的每个更新记录执行操作。注意   这是一个返回void的终端操作。

     

请注意,foreach()未应用于内部状态存储和   只调用每个新的KTable更新记录。

想象一下,您有3条带有“A”键的消息。 count()聚合创建的KTable将更新3次,并且您的函数(lambda表达式)将使用以下参数调用3次: (“A”,1),(“A”,2),(“A”,3)导致计数增加1 + 2 + 3 = 6,而不是增加3。

KStream和KTable表示“运动中的数据”,它们的方法通常在数据流上运行。如果要对数据的当前快照进行操作,请考虑使用交互式查询。可能是因为KTable.foreach方法最初可能令人困惑,因此不推荐使用以下注释:

  

已过时。使用Interactive Queries API(例如,   KafkaStreams.store(String,QueryableStoreType)后跟   ReadOnlyKeyValueStore.all())迭代KTable的键。   或者使用toStream()转换为KStream然后使用   关于结果的foreach(行动)。