我想使用Kafka流Processor API,并在预定的punctuator function中每分钟生成一些消息。 Kafka Streams是否可以保证将这些消息准确地写入输出主题一次?
我了解在Kafka Streams中可以执行一次精确处理,因为它可以通过以下操作进行单个事务:
这个概念是否扩展到处理器API中的标点函数,对此没有关联的输入消息需要提交?
例如,此标点函数对key value state store中的项目进行迭代。每个商品都将从商店中删除并转发到下游:
override def punctuate(timestamp: Long) : Unit =
store.all.asScala.foreach { keyValue =>
store.delete(keyValue.key)
context.forward(keyValue.key, keyValue.value)
}
即使在处理器故障并重新启动的情况下,存储中的每条消息也应该在输出主题上恰好出现一次。
假设商店是持久性的;它由一个kafka changelog主题支持。在每分钟的墙上时钟时间安排标点器。我已经在配置中配置了processing.guarantee=exactly_once
。
答案 0 :(得分:2)
如果您使用的是Punctuator,那么语义恰好也适用。
在使用状态存储的情况下,所有要写到changelog主题(甚至删除-使用某些键和null
值写消息)
在您的用例中,Kafka Streams将从某些输入主题中读取消息,并写入输出主题和某些changelog主题(对状态存储的操作)。
如果您仅在Kafka Streams中启用一次,它将在 transaction 模式下运行。使用事务-原子多分区写入-Kafka Streams确保执行偏移提交时,结果将写入输出主题,状态存储也将闪烁到代理上的changelog主题。上面的操作是原子的,因此,如果其中之一失败,则应用程序将从前一个偏移位置重新处理消息。以上所有操作均有效,因为Processor::process
和Punctuator::punctuate(...)
在特定分区的单个线程中执行。
可以找到更多详细信息:
Kafka Summit的Matthias J. Sax演讲:https://kafka-summit.org/sessions/dont-repeat-introducing-exactly-semantics-apache-kafka
王国章的博客文章在融合页面:https://www.confluent.io/blog/enabling-exactly-kafka-streams-有一节: How Kafka Streams Guarantees Exactly-Once Processing
。