卡夫卡如何知道是“前滚还是后滚”交易?

时间:2019-05-15 19:57:28

标签: apache-kafka kafka-producer-api

来自the exactly-once KIP,涉及使用InitPidRequest重新启动应用程序时生产者的幂等性:

  

2.1指定TransactionalId时如果设置了transactional.id配置,则此TransactionalId与   InitPidRequest,并登录到相应的PID的映射   步骤2a中的事务日志。这使我们能够返回相同的PID   对于生产者的未来实例的TransactionalId,因此   可以恢复或中止以前未完成的交易。

     

除了返回PID,InitPidRequest还执行   以下任务:

     
      
  1. 增加PID的时间,以便任何先前的僵尸   生产者实例被隔离,无法继续前进   它的交易。

  2.   
  3. 恢复(前滚或后滚)任何   生产者的先前实例未完成交易。   InitPidRequest的处理是同步的。一旦返回,   生产者可以发送数据并开始新的交易。

  4.   

当生产者失败并再次启动并执行InitPidRequest时,最后一个事务是“前滚”(我猜这意味着已提交)还是“回滚”?如何控制?

1 个答案:

答案 0 :(得分:1)

事务协调器是使Kafka实现这一目标的关键组件。这是您提到的KIP的一部分。交易协调器是由经纪人在初始化过程中构建的,并在内存中保留以下信息:

  1. TransactionalId到分配的PID的映射,当前时期号(Unix时间戳)和事务超时值
  2. PIDPID所指示的生产者当前正在进行的交易状态,参与者主题分区以及该状态最后一次更新的映射。

现在,要回答有关前滚或后退事务的问题

当生产者发生故障并重新启动时,如果生产者附带非空的InitPidRequest(生产者应用程序作为配置参数提供),则它将新的TransactionalId发送到事务协调器。

事务协调器在接收到此请求之后,然后检查内存映射中是否已经存在带有提供的TransactionalId的条目(上述点1)。如果存在映射,它将在第二个内存映射(上面的第2点)中查找PID,以检查是否有针对该PID的正在进行的事务:

  • 如果正在进行的交易处于启动状态,即BEGIN,则该交易将被中止 ( 注释 这是回滚版本
  • 如果正在进行的交易已开始并且在PREPARE_ABORTPREPARE_COMMIT中,则交易协调器将等待交易通过COMPLETE_ABORT 回滚 版本)或COMPLETE_COMMIT 前滚 版本)。

此后,事务处理协调器以最新的PIDTransactionalId的时期时间戳作为响应,然后生产者就可以开始发送新的事务了。

我已尝试将解释保持在最低限度,但是如果您对更多详细信息感兴趣,请参考detailed design document

我希望这会有所帮助!