【问题标题】:apache storm - run jar in single node correctly but not in multi nodesapachestorm - 在单节点中正确运行 jar,但在多节点中不正确
【发布时间】:2019-01-10 17:55:35
【问题描述】:

我是 apachestorm 的新手,我编写了包含 1 个 spout 和 2 个 bolt 的代码,当我在一个 worker 上运行这 3 个部分时,代码会正确生成输出,但是当我在三个 worker 中运行代码时1个worker执行spout,另一个run bolt 1,最后一个run bolt 2,不会产生输出。 具体情况:当我将螺栓1和2放在一个工人中时,产生了输出!

不得不说emit成功了,emit变量没有问题。

详细说明:我在螺栓 1 中的 hashmap 结构中创建了树,我想在螺栓 2 中挖掘这棵树。在螺栓 1 中插入树中的对象的 id 类似于“MyTreeNode@e70014d5”,当我收到这个时Bolt 2 中的 tuple (hashmap),id 更改为“MyTreeNode@z5542r12”。

主要问题是什么?

问题是因为更改了对象ID吗?如果是,请告诉我如何解决?

【问题讨论】:

    标签: java apache apache-storm bolt


    【解决方案1】:

    让我们看一个示例拓扑。

    假设您的拓扑变为 spout -> bolt1,并且您正在从 spout 发出 MyObject 实例。

    假设您已将拓扑设置为在 1 个工作器中运行。

    当从 spout 发出一个元组(例如 MyObject@1234)时,Storm 将检查该元组是否需要转到另一个工作人员。如果没有,它只是将对象引用传递给bolt1。这就是您只有 1 个工人时所看到的。当 MyObject@1234 需要从 spout 转移到 bolt 时,Storm 只是将 MyObject@1234 引用交给 bolt。

    现在假设您告诉拓扑使用 2 个 worker,Storm 决定将 spout 放在 worker 1 中,将 bolt 放在 worker 2 中。回想一下,每个 worker 都是一个单独的 JVM 进程,因此从 worker 1 传递对象引用对工人 2 不起作用。

    当元组从 spout 发出时,Storm 会看到它正在发送给另一个工作人员,并根据您的配置使用 Kryo 或 Java 序列化对其进行序列化。这意味着 MyObject@1234 被序列化。 Storm 将序列化的表单交给 worker 2,后者将其反序列化。当它被反序列化时,它被非常合理地赋予了一个新的内存地址(例如MyObject@6789)。

    如果您将螺栓设计为假设它们不在同一个 JVM 中运行,这不是问题,您绝对应该这样做。例如,如果您想将 MyObject 从 worker 1 传输到 worker 2,您可以将其设为 Serializable,或者您可以将其注册到 Kryo(参见 https://storm.apache.org/releases/2.0.0-SNAPSHOT/Serialization.html 中的操作方法)。您需要这样做,以便 Storm 可以将您的 spout 和 bolts 放在不同的 JVM 中,而不会破坏您的拓扑结构。

    在测试拓扑时,应启用https://storm.apache.org/releases/1.2.2/javadocs/org/apache/storm/Config.html#TOPOLOGY_TESTING_ALWAYS_TRY_SERIALIZE。这将导致 Storm 总是序列化你的元组,即使元组没有在工作人员之间传输。这可以帮助您在序列化问题投入生产之前发现它们。

    顺便说一句,您应该始终更喜欢 Kryo 序列化而不是 Java 序列化。 Kryo 序列化要快得多。

    【讨论】:

    • 非常感谢“Stig Rohde Døssing”。实际上我发出 TreeMap 和一些整数值。似乎 TreeMap 不会像 HashMap 那样序列化,也许这是我的问题。如何序列化 TreeMap??
    • TreeMap 是可序列化的。问题很可能是您的键或值不可序列化。确保所有键/值都实现了可序列化,或者向 Kryo 注册键/值类型(可能还有 TreeMap)。您可以在我发布到 Storm 文档的链接中查看如何注册 Kryo。
    • 感谢您发布的链接。我序列化了 TreeMap 值,但我收到了这个错误:java.util.HashMap.hash(HashMap.java:339) at java.util.HashMap.get(HashMap.java:557) at com.esotericsoftware .kryo.Generics.getConcreteClass(Generics.java:61) 在 com.esotericsoftware.kryo.Generics.getConcreteClass(Generics.java:62) 在 com.esotericsoftware.kryo.Generics.getConcreteClass(Generics.java:62) 在 .. . 等等或这个错误:com.esotericsoftware.kryo.Generics.getConcreteClass 的 java.lang.StackOverflowError ...
    • 我用谷歌搜索了你的错误,得到了github.com/EsotericSoftware/kryo/issues/462。这可能是 Kryo 中的一个错误。我提出了issues.apache.org/jira/browse/STORM-3315。同时,您可以尝试以下方法:改用 HashMap,改用 Java 序列化,使用其他序列化机制(例如,使用 Jackson 之类的方法序列化为 JSON)。
    • 再次感谢您。我在github.com/EsotericSoftware/kryo/releases 中阅读了 kryo 的发行说明,似乎 kryo 版本 5 和 4 已发布。正如您在issues.apache.org/jira/browse/STORM-3315 中提到的“升级到 Kryo 4”,是否可以升级 kryo 版本?如果是,怎么做?
    猜你喜欢
    • 1970-01-01
    • 2023-02-18
    • 2013-02-27
    • 1970-01-01
    • 2020-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-27
    相关资源
    最近更新 更多