apache storm - 运行 jar 在单节点中正确但在多节点中不正确
apache storm - run jar in single node correctly but not in multi nodes
我是 apache storm 的新手,我编写的代码包括 1 个 spout 和 2 个 bolt,当我 运行将这 3 个部分放在一个工人身上时,代码会正确生成输出,但是当我' m 运行ning 代码在三个 worker 中 1 个 worker 执行 spout,另一个 运行 bolt 1 和最后一个 运行 bolt 2,不会生成输出。
具体情况:当我把 bolt 1 和 2 放在一个 worker 中时,产生了输出!
不得不说emit成功了,emit变量也没有问题
详细说明:我在 bolt 1 中创建了 hashmap 结构的树,我想在 bolt 2 中挖掘这棵树。在 bolt 1 中插入树的对象的 id 就像 "MyTreeNode@e70014d5" 并且当我在 bolt 2 中收到了这个元组(hashmap),id 变成了这样 "MyTreeNode@z5542r12".
主要问题是什么?
是对象id改变的问题吗?如果是,能否请您告知我该如何解决?
让我们看一个示例拓扑。
假设您的拓扑结构为 spout -> bolt1,并且您正在从 spout 发射 MyObject 实例。
假设您已将拓扑设置为 运行 1 名工作人员。
当一个元组(例如 MyObject@1234)从 spout 发出时,Storm 将检查该元组是否需要发送给另一个 worker。如果不是,它只是将对象引用传递给 bolt1。这就是您只有 1 名工人时所看到的。当 MyObject@1234 需要从 spout 转移到螺栓时,Storm 只需将 MyObject@1234 引用传递给螺栓。
现在假设您告诉拓扑使用 2 个 worker,Storm 决定将 spout 放在 worker 1 中,将 bolt 放在 worker 2 中。回想一下,每个 worker 都是一个单独的 JVM 进程,因此将对象引用从工人 1 到工人 2 将无法工作。
当元组从 spout 中发出时,Storm 将看到它正在发送给另一个 worker,并根据您的配置使用 Kryo 或 Java 序列化对其进行序列化。这意味着 MyObject@1234 被序列化。 Storm 将序列化的表单交给工人 2,工人 2 反序列化它。反序列化的时候,非常合理地给它一个新的内存地址(例如MyObject@6789)。
如果您将螺栓设计为假设它们不在同一 JVM 中,那么这不是问题,您绝对应该这样做。例如,如果您想将 MyObject 从 worker 1 传输到 worker 2,您可以将其设置为可序列化,或者您可以将其注册到 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 始终序列化您的元组,即使该元组未在 worker 之间传输。这可以帮助您在序列化投入生产之前发现序列化问题。
顺便说一句,与 Java 序列化相比,您应该始终更喜欢 Kryo 序列化。 Kryo 序列化要快得多。
我是 apache storm 的新手,我编写的代码包括 1 个 spout 和 2 个 bolt,当我 运行将这 3 个部分放在一个工人身上时,代码会正确生成输出,但是当我' m 运行ning 代码在三个 worker 中 1 个 worker 执行 spout,另一个 运行 bolt 1 和最后一个 运行 bolt 2,不会生成输出。 具体情况:当我把 bolt 1 和 2 放在一个 worker 中时,产生了输出!
不得不说emit成功了,emit变量也没有问题
详细说明:我在 bolt 1 中创建了 hashmap 结构的树,我想在 bolt 2 中挖掘这棵树。在 bolt 1 中插入树的对象的 id 就像 "MyTreeNode@e70014d5" 并且当我在 bolt 2 中收到了这个元组(hashmap),id 变成了这样 "MyTreeNode@z5542r12".
主要问题是什么?
是对象id改变的问题吗?如果是,能否请您告知我该如何解决?
让我们看一个示例拓扑。
假设您的拓扑结构为 spout -> bolt1,并且您正在从 spout 发射 MyObject 实例。
假设您已将拓扑设置为 运行 1 名工作人员。
当一个元组(例如 MyObject@1234)从 spout 发出时,Storm 将检查该元组是否需要发送给另一个 worker。如果不是,它只是将对象引用传递给 bolt1。这就是您只有 1 名工人时所看到的。当 MyObject@1234 需要从 spout 转移到螺栓时,Storm 只需将 MyObject@1234 引用传递给螺栓。
现在假设您告诉拓扑使用 2 个 worker,Storm 决定将 spout 放在 worker 1 中,将 bolt 放在 worker 2 中。回想一下,每个 worker 都是一个单独的 JVM 进程,因此将对象引用从工人 1 到工人 2 将无法工作。
当元组从 spout 中发出时,Storm 将看到它正在发送给另一个 worker,并根据您的配置使用 Kryo 或 Java 序列化对其进行序列化。这意味着 MyObject@1234 被序列化。 Storm 将序列化的表单交给工人 2,工人 2 反序列化它。反序列化的时候,非常合理地给它一个新的内存地址(例如MyObject@6789)。
如果您将螺栓设计为假设它们不在同一 JVM 中,那么这不是问题,您绝对应该这样做。例如,如果您想将 MyObject 从 worker 1 传输到 worker 2,您可以将其设置为可序列化,或者您可以将其注册到 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 始终序列化您的元组,即使该元组未在 worker 之间传输。这可以帮助您在序列化投入生产之前发现序列化问题。
顺便说一句,与 Java 序列化相比,您应该始终更喜欢 Kryo 序列化。 Kryo 序列化要快得多。