使用 Storm,在这种情况下锚定我的元组有很大的好处吗?

With Storm, is there significant benefit to anchoring my tuples in this case?

在我的流中,我的元组无论如何都不会拆分。最终对每个元组执行一个操作。

如果他们 运行 出现某种异常,如果我的 KafkaSpout 重播,他们可能会征服,我仍然可以让他们失败。虽然,我不知道我的 spout 如何知道在未锚定时重播哪个元组,但在测试中它似乎重播了正确的元组。这是预期的吗,KafkaSpout 实现以某种我不知道的方式跟踪 tuples/messages?我是否可能在没有意识到的情况下锚定(我的螺栓延伸 BaseRichBolt)?可能我只是误以为它重播了正确的?

但是如果手动失败确实有效,那么我相信我从锚定中获得的唯一好处是我的元组在超时时将被重播——我不确定锚定的开销是否值得。

我说得对吗?在这种情况下,锚定还有其他重要的好处吗?

BaseRichBolt 不会自动进行任何锚定(BaseBasicBolt 会这样做)。因此,您描述的行为只有在您具有简单的 Spout -> Bolt 拓扑时才有效。对于更深的拓扑结构,即 Spout -> Bolt1 -> Bolt2 并且 Bolt1 中没有锚定,Bolt2 中的元组失败将无法工作。

使用KafkaSpout 发出的每个元组都会分配一个MessageId,从而激活容错机制。因此,每个元组必须在接收到这些元组的第一个 Bolt 中得到确认;否则,元组最终超时。在 Bolt1 中发出的元组应该被锚定(否则,这些元组不会被跟踪,不会失败——无论是在 Bolt2 中手动还是超时——并且在失败的情况下无法重播)。

因此,锚定是一种纯粹的容错机制。实际上,您应该始终锚定元组,因为锚定本身不会 启用 容错;在 Spout 中分配 MessageId 确实会启用它 。如果 Bolt 处理一个没有分配 ID 的元组,锚定调用将执行 "nothing" 并且额外的方法调用的开销很小。因此,添加锚定代码通常是一个不错的选择,因为 Bolt 可以在启用或不启用容错的情况下使用(取决于 Spout 是否分配消息 ID)。如果省略锚定代码,容错将在此 Bolt 中中断,并且下游元组在失败时无法恢复。