如何确保风暴不会将消息写入本地文件两次?

时间:2015-07-03 10:39:41

标签: apache-kafka apache-storm trident

我构建了一个topo来获取来自kafka的消息,然后grep一些关键字,如果适合,写入本地文件。

我使用storm-kafka的OpaqueTridentKafkaSpout来确保元组不会错过或重复,但考虑一种情况:将消息写入本地文件时,会发生一些错误(例如,空间不足)。此时,有些消息已写入本地文件,而其他消息则没有,如果喷口重新发送消息,则消息将写入两次。

如何处理?

2 个答案:

答案 0 :(得分:1)

很简单。写入文件的代码需要执行以下操作:

1)确认元组 - 仅当对文件的写入成功时。 2)使元组失败 - 如果写入文件不成功。

对于所有确认的元组,Kafka spout都不会重新发送它们。喷口将重置失败的元组。

答案 1 :(得分:0)

您必须为此目的设计锚定策略。我建议您可以从kafkaspoutconfig减少批量大小,并将所选消息存储在列表中。处理批处理中的所有邮件时,可以将列表内容写入本地文件。

如您所知,Trident处理批处理流,如果您的系统在处理流中的任何元组时抛出任何错误,则所有批处理都将被丢弃。

在你的情况下,你可以尝试捕获负责写入本地文件的代码块,并且在catch块中你必须抛出 backtype.storm.topology.ReportedFailedException 。通过这种方式,您可以确保一个语义。

此外,您必须使用事务性kafka spout来确保一个语义。