Kafka Streams:使用at_least_once可以保证对状态存储的排序吗?

时间:2019-01-17 08:55:42

标签: apache-kafka apache-kafka-streams

我们有一个使用Processor API构建的Kafka Streams Java拓扑。

在拓扑中,我们只有一个处理器,可以保存到多个状态存储。

当我们使用at_least_once时,我们希望看到状态存储之间的一些不一致之处-例如一条传入记录导致对状态存储A和状态B的写入,但是两次保存之间的崩溃仅导致存储A的保存被写入Kafka更改日志主题。

  1. 我们是否保证保存的顺序也将成为写入状态存储的顺序?例如。如果我们先保存到存储区A,然后再存储到存储区B,我们当然可以遇到两种更改日志都成功写入的情况,以及仅完成对更改日志A的写入的情况-但我们也可以最终得到仅完成更改日志B的写操作的情况?

  2. 什么情况会导致重放?当然发生了崩溃-但是重新平衡,新的经纪人分区负责人或当我们收到“偏移提交失败”错误(请求超时)呢?

  3. 前一段时间,我们尝试使用完全一致的一次,这导致了许多错误消息,这对我们来说是没有意义的。会否为我们提供跨多个状态存储的原子写操作?

1 个答案:

答案 0 :(得分:2)

广告3。根据The original design document on exactly-once support in Kafka Streams,我认为eaxctly_once会在多个状态存储中获得原子写入

  

调用stream.commit()时,将按顺序执行以下步骤:

     
      
  1. 刷新本地状态存储(KTable缓存),以确保所有变更日志记录都发送到下游。
  2.   
  3. 致电producer.sendOffsetsToTransactions(offsets)以提交当前记录的消费者在交易中的头寸。请注意,尽管线程的使用者可以在多个任务之间共享,因此可以在多个生产者之间共享,但任务分配的分区始终是互斥的,因此可以安全地提交该任务分配的分区的偏移量。
  4.   
  5. 调用producer.commitTransaction()提交当前事务。结果,原子表示为上述三元组的任务状态。
  6.   
  7. 再次致电producer.beginTransaction()以开始下一个交易。
  8.