【发布时间】:2019-10-15 09:40:29
【问题描述】:
我只需要在我的应用中交付一次。我探索了 kafka 并意识到要只生成一次消息,我必须在生产者配置中设置 idempotence=true。这也设置了acks=all,使生产者重新发送消息,直到所有副本都提交它。为了保证消费者不做重复处理或留下任何未处理的消息,建议在同一个数据库事务中将处理输出和偏移量提交到外部数据库,这样要么都被持久化,要么都不持久,避免重复和不处理。
在消费者中,如果消费者首先提交消息但在处理之前失败,则消息将被处理;如果消费者首先处理消息但在提交之前失败,则消息被处理多次。
Q1. 现在我在猜测如何使用 Apache Storm 进行模仿。我想通过在KafkaBolt 中设置idemptence=true 可以确保生成消息。我说的对吗?
我在猜测如何确保在 Storm 中处理丢失和重复的消息。例如,this doc page 表示如果我锚定一个元组(通过将其作为第一个参数传递给OutputCollector.emit())然后将元组传递给OutputCollector.ack() 或OutputCollector.fail(),Storm 将确保数据丢失。这正是它所说的:
现在您已经了解了可靠性算法,让我们回顾一下所有故障案例,看看 Storm 在每种情况下如何避免数据丢失:
由于任务死亡,元组未得到确认:在这种情况下,失败元组的树根的 spout 元组 id 将超时并被重放。
Acker 任务终止:在这种情况下,acker 跟踪的所有 spout 元组都将超时并被重放。
Spout 任务终止:在这种情况下,spout 与之对话的源负责重播消息。例如,像 Kestrel 和 RabbitMQ 这样的队列会在客户端断开连接时将所有未决消息放回队列中。
Q2. 我想这可以确保消息不会未被处理,但不会避免重复处理消息。我对此是否正确?此外,Storm 还提供了其他任何东西来确保我缺少像 kafka 这样的语义吗?
【问题讨论】: