gpt4 book ai didi

java - Apache Storm : Mutable Object emitted to different bolts

转载 作者:行者123 更新时间:2023-11-30 10:42:30 26 4
gpt4 key购买 nike

几周以来,我们在项目中使用了 Storm。今天,我们发现了一个非常奇怪的行为。假设我们有以下拓扑:


SpoutA ---> BoltB
---> BoltC

因此,我们有一个 SpoutA,它向两个不同的 Bolt 发出自定义 Java 对象(我们称之为消息)。 bolt B 和 bolt C。基本上,我们执行拆分。

直到今天,我们假设如果 SpoutA 发出消息对象,它会在 SpoutA 上序列化并在 BoltB 和 BoltC 上反序列化。然而,这个假设似乎是错误的。今天,我们发现BoltB中的反序列化对象与BoltC中的对象完全相同(Same System.identitfyHashCode)。换句话说,如果我操作了BoltB中的Object,我也操作了BoltC中的Object,导致许多不可预见的副作用。

此外,这种行为对我来说似乎很奇怪,因为它只适用于 SpoutA 和相应的 Bolt B 和 C 在同一个 worker 中运行的情况。如果我明确强制使用三个作品,那么该对象(正如预期的那样)是 BoltB 和 BoltC 的不同对象,因为它用于不同的 JVM。因此,如果我们假设我们有一个更大的拓扑(50 个不同的 bolts)在三个 worker 上运行,那么我们永远无法确定对象当前是否在 bolts 之间共享。

所以基本上,我们真的不希望在 bolt 之间共享一个对象。我们通常期望在反序列化过程中,为每个 bolt 创建新的不同对象。

所以这是我的问题:我们这里的主要缺陷是什么?我们发出“可变”对象是我们的主要缺陷吗?我们使用序列化/反序列化错误吗?或者它甚至可能是 Storm 的设计缺陷?

显然,我们可以通过仅发出字节数组来强制创建新对象,但我认为这与 Storm 相矛盾。

最好的问候,安德烈

最佳答案

Storm 在将元组从一个组件移动到另一个组件时使用两种不同的排队方法,一种是两个组件位于同一 JVM 内,另一种是元组必须跨 JVM 传输。我认为您陷入了同一个 JVM 的情况,其中元组中的对象实际上并未序列化,因为只有跨 JVM 队列才需要序列化。

我总是对元组和 Java bean 之间的数据进行编码和解码,以便在每个 bolt/spout 中为我的业务逻辑提供强类型接口(interface)。这样做我想我无意中避免了你遇到的问题。这可能是解决您的问题的一种方法。

关于java - Apache Storm : Mutable Object emitted to different bolts,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38105443/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com