风暴,螺栓延迟和总延迟之间的巨大差异?

Posted

技术标签:

【中文标题】风暴,螺栓延迟和总延迟之间的巨大差异?【英文标题】:Storm, huge discrepancy between bolt latency and total latency? 【发布时间】:2015-11-06 02:44:23 【问题描述】:

下面是我的拓扑的 Storm UI 的屏幕截图。这是在拓扑完成处理 10k 条消息后拍摄的。

(拓扑配置有 4 个工作人员并使用 KafkaSpout)。

我的螺栓的“进程延迟”总和约为 8100 毫秒,而拓扑的完整延迟则更长 115881 毫秒。

我知道这些差异可能是由于资源争用或与 Storm 内部相关的原因而发生的。我相信资源争用在这里不是问题;在此测试期间,GC 根本没有运行,分析显示我有足够的可用 CPU 资源。

所以我认为问题在于我以某种方式滥用了 Storm 内部结构。有什么建议去哪里看吗?

元组必须在某个地方等待,可能在喷口中;要么等待被发送到拓扑,要么等待消息被处理后被确认?

可能我应该调整 ackers 的数量(我已将 ackers 设置为 4,与工人的数量相同)?

关于如何解决此问题的任何其他一般性建议?

*请注意,在它的进程和执行延迟之间有很大差异的一个 bolt 实现了 ticking bolt,批处理模式。所以这种差异是预料之中的。

*编辑。 我怀疑这种差异可能涉及在完全处理后由 Spout 确认的消息。如果我在处理 Storm UI 时刷新它,我的最终 Bolt 的 ack-ed 数与 Spout 的 ack-ed 数相比增加得非常快。虽然这可能是由于 Spout 确认的消息比最终的 Bolt 少得多;最终bolt 确认的几百条消息可能代表Spout 中的一条消息。但是,我想我应该提一下这种怀疑,以了解是否有可能,Spout 的 acker 任务正在溢出。

【问题讨论】:

【参考方案1】:

可能有多种原因。首先,您需要了解数字是如何衡量的。

    Spout Complete Latency:发出元组直到调用Spout.ack() 的时间。 Bolt 执行延迟:运行 Bolt.execute() 所需的时间。 Bolt 处理延迟:调用 Bolt.execute() 直到 Bolt 确认给定输入元组的时间。

如果您不立即确认 Bolt.execute 中的每个传入输入元组(这绝对没问题),处理延迟可能会远高于执行延迟。 p>

此外,处理延迟不得叠加到完全延迟,因为元组可以保留在内部输入/输出缓冲区中。这会增加额外的时间,直到最后一次确认完成,从而增加完全延迟。此外,ackers 需要处理所有传入的 ack 并通知 Spout 完全处理的元组。这也增加了完全延迟

问题可能在于操作员之间的内部缓冲区很大。这可以通过增加dop(并行度)或设置参数TOPOLOGY_MAX_SPOUT_PEDING 来解决——这限制了拓扑中元组的数量。因此,如果有太多的元组在进行中,则 spout 停止发出元组,直到它收到确认。因此,元组不会在内部缓冲区中排队,完全延迟会下降。如果这没有帮助,您可能需要增加 acker 的数量。如果 ack 的处理速度不够快,ack 可能会缓冲,从而增加 完全延迟

【讨论】:

再次感谢您的详细回复。我很清楚这些信息,只是几个问题。你提到增加'dop',这是什么?关于如何查看内部缓冲区内容的任何建议?有关如何深入了解 ack 时代是否存在延迟的任何建议? dop = 并行度。没有直接访问内部缓冲区的方法。您可以监控生产者的“发出/传输”计数,并与消费者的“执行”计数进行比较。如果存在很大差异,则元组必须位于某些内部缓冲区中(但不清楚它是生产者输出缓冲区还是消费者输入缓冲区 - 不知道您会从谁获得此信息)。您还可以在 UI 中启用“系统统计信息”以获取有关 acker 的更多信息。但我想没有“黄金方式”来完成这项工作。我会采用一些跟踪和错误的方法。

以上是关于风暴,螺栓延迟和总延迟之间的巨大差异?的主要内容,如果未能解决你的问题,请参考以下文章

映射器执行时间之间的巨大差异

MySQL主从复制延迟解决方案

使用 IOS 计算延迟时间和总动画时间

Apache Storm 工作人员之间的高消息传递延迟

UTF-8 和 UTF-16 之间是不是存在巨大差异

发送和接收意图之间的巨大延迟