在我的流期间,我的元组无论如何都不会分裂。最终对每个输入的元组执行一个动作。
如果他们遇到某种异常,如果我的KafkaSpout. 虽然,我不知道我的 spout 如何知道当它们没有锚定时要重播哪个元组,但在测试中它似乎重播了正确的元组。这是预期的,KafkaSpout实现以某种我不知道的方式跟踪元组/消息?我可能锚定一个没有意识到它(我的螺栓延伸BaseRichBolt)?可能我只是误认为它重播了正确的?
但是如果手动失败确实有效,那么我相信我从锚定中获得的唯一好处是我的元组将在超时时重播——我不确定这是否值得锚定的开销。
我对此是否正确?在这种情况下,锚定还有其他一些重要的好处吗?
BaseRichBolt不会自动进行任何锚定(BaseBasicBolt会这样做)。因此,您描述的行为仅在您具有简单的Spout -> Bolt拓扑时才有效。对于更深的拓扑,即Spout -> Bolt1 -> Bolt2 并且在 Bolt1 中没有锚定,则 Bolt2 中元组的失败无法工作。
使用KafkaSpout发出的每个元组都会得到一个MessageId分配,从而激活容错机制。因此,每个元组必须在第一个接收这些元组的 Bolt 中得到确认;否则,元组最终会超时。在 Bolt1 中发出的元组应该被锚定(否则,这些元组不会被跟踪,不会失败——无论是在 Bolt2 中手动还是每次超时——并且在失败的情况下无法重播)。
因此,锚定是一种纯粹的容错机制。你应该总是实际上锚的元组,因为锚本身不支持容错; MessageId在 Spout中分配s确实启用了它。如果 Bolt 处理一个没有分配 ID 的元组,锚定调用将“什么都不做”,并且额外方法调用的开销很小。因此,添加锚定代码通常是一个不错的选择,因为 Bolt 可以在启用或不启用容错的情况下使用(取决于 Spout 是否分配消息 ID)。如果省略锚定代码,则此 Bolt 中的容错将中断,并且下游元组无法在失败时恢复。