← 中文资源

简体中文版本

用原子事务实现 Kafka 生产与提交

通过事务让数据库提交与 Kafka 生产要么同时生效要么都不生效,并设置稳定的 transactional id 以防僵尸生产者。

阅读英文原文

概述

只有生产而没有匹配的提交是偏移的经典来源。事务把数据库写入与事件合成一个单元,稳定的 transactional id 则在重启后隔离旧生产者。

关键步骤

  1. 配置稳定的 transactional.id,使重启可隔离旧的僵尸生产者。
  2. 在事务内先写数据库再生产事件。
  3. 提交事务;任一步出错则中止,使两个效果都不可见。
  4. 消费者保持 read_committed 隔离级别,避免读到已中止的写入。

验证

  • 生产失败会中止数据库写入。
  • 已提交事务对 read_committed 消费者可见。
  • 重启生产者不会产生重复事件。
  • 已中止的写入在下游不可见。

注意事项

  • 事务会增加延迟并需要 broker 支持,不适合超高吞吐的尽力而为流。
  • 只有当参与存储也加入同一事务协议时,事务才能跨 Kafka 与存储保证原子性。

适用范围

本条目围绕「用原子事务实现 Kafka 生产与提交」给出可复制的步骤、验证方式与常见问题,适合需要按此流程落地的工程团队。执行时请结合自身上下文调整命令与阈值,并在变更前后留存证据,便于后续复核与回滚。

await producer.transaction(async (tx) => {
  await db.query('INSERT INTO orders ...');
  await tx.send({ topic: 'orders', messages: [event] });
});
// abort on throw leaves neither effect visible