首页 > 解决方案 > Kafka:在数据库中保留主题偏移量是一种好习惯吗?

问题描述

我已经开始学习卡夫卡了。我对使用 kafka 的现场项目不太了解。想知道除了在代理中提交之外,偏移量是否可以保存在数据库中?我认为应该始终保存它,否则某些记录将丢失或重新处理。举个例子,如果偏移量没有保存在数据库中,当应用程序(消费者)在此期间部署或重新启动时,如果当时有一些消息发送到代理,那将被错过,因为当消费者启动时,它将读取下一条记录或(从头开始)

标签: apache-kafkakafka-consumer-api

解决方案


你的问题的简短回答是“它很复杂”:-)

你的问题的长答案是这样的:

  1. kafka(无需额外配置和/或仔细设计代码)是一个至少一次的系统(参见官方文档)。这意味着是的,您的消费者可能会多次看到一组特定的记录。这不会在正常关闭/重新平衡时发生,但如果您的应用程序崩溃肯定会发生。
  2. 较新版本的 kafka 支持所谓的“恰好一次”。这涉及以不同的方式配置您的客户端(以及显着的性能和延迟影响),并且只有当您的所有输入和输出都来自/到完全相同的 kafka 集群时,保证才会成立。因此,如果您的消费者执行任何操作,例如调用外部 HTTP API 或插入数据库以响应看到 kafka 记录,我们至少会返回一次。
  3. 如果您的输出进入事务系统(如经典 ACID 数据库),则常见模式是启动事务,并在该事务中记录您的输出和消费者偏移量(您还需要更改代码以从这些DB 偏移量而不是 kafka 默认值)。这有更好的保证(但如果您的代码与非事务性系统交互,例如进行 HTTP 调用,仍然无济于事)
  4. 另一个要克服至少一次的常见设计模式是以某种方式“标记”你所做的每一个操作(记录你产生的,你做的 http 调用......),使用一些 UUID,这些 UUID 来自于产生这个输出的原始 kafka 记录。这意味着如果您的消费者再次看到相同的记录,它将再次执行相同的操作,并重复相同的“标签”值。这将负担转移到下游系统,它们现在必须记住(至少在一段时间内)他们看到的所有“标签”,以便他们可以忽略重复操作,或者以某种方式将所有操作设计为幂等

推荐阅读