来自the exactly-once KIP,涉及使用InitPidRequest
重新启动应用程序时生产者的幂等性:
2.1指定TransactionalId时如果设置了transactional.id配置,则此TransactionalId与 InitPidRequest,并登录到相应的PID的映射 步骤2a中的事务日志。这使我们能够返回相同的PID 对于生产者的未来实例的TransactionalId,因此 可以恢复或中止以前未完成的交易。
除了返回PID,InitPidRequest还执行 以下任务:
增加PID的时间,以便任何先前的僵尸 生产者实例被隔离,无法继续前进 它的交易。
恢复(前滚或后滚)任何 生产者的先前实例未完成交易。 InitPidRequest的处理是同步的。一旦返回, 生产者可以发送数据并开始新的交易。
当生产者失败并再次启动并执行InitPidRequest
时,最后一个事务是“前滚”(我猜这意味着已提交)还是“回滚”?如何控制?
答案 0 :(得分:1)
事务协调器是使Kafka实现这一目标的关键组件。这是您提到的KIP的一部分。交易协调器是由经纪人在初始化过程中构建的,并在内存中保留以下信息:
TransactionalId
到分配的PID
的映射,当前时期号(Unix时间戳)和事务超时值PID
到PID
所指示的生产者当前正在进行的交易状态,参与者主题分区以及该状态最后一次更新的映射。现在,要回答有关前滚或后退事务的问题:
当生产者发生故障并重新启动时,如果生产者附带非空的InitPidRequest
(生产者应用程序作为配置参数提供),则它将新的TransactionalId
发送到事务协调器。
事务协调器在接收到此请求之后,然后检查内存映射中是否已经存在带有提供的TransactionalId
的条目(上述点1)。如果存在映射,它将在第二个内存映射(上面的第2点)中查找PID
,以检查是否有针对该PID
的正在进行的事务:
BEGIN
,则该交易将被中止
( 注释 :这是回滚版本)PREPARE_ABORT
或PREPARE_COMMIT
中,则交易协调器将等待交易通过COMPLETE_ABORT
( 回滚 版本)或COMPLETE_COMMIT
( 前滚 版本)。此后,事务处理协调器以最新的PID
和TransactionalId
的时期时间戳作为响应,然后生产者就可以开始发送新的事务了。
我已尝试将解释保持在最低限度,但是如果您对更多详细信息感兴趣,请参考detailed design document。
我希望这会有所帮助!