我是新来的apache风暴,我写的代码,其中包括1喷口和2螺栓,当我在一个工人运行这3部分,代码生成正确的输出,但当我在三个工人运行代码,其中一个工人执行喷口,另一个运行螺栓1和最后一个运行螺栓2,输出不会生成。具体情况:当我把螺栓1和2放在一个工人,输出产生!
我不得不说emit工作成功,emit变量没有问题。
细节:我在bolt1的hashmap结构中创建了树,我想在bolt2中挖掘这棵树。在螺栓1的树中插入的对象的id类似于“mytreenode@e70014d5当我在bolt 2中收到这个元组(hashmap)时,id变成了这样mytreenode@z5542r12".
主要问题是什么?
问题是因为对象id的变化吗?如果是,你能告诉我怎么解决吗?
1条答案
按热度按时间yrdbyhpb1#
让我们看一个拓扑示例。
假设您的拓扑变成了spout->bolt1,并且您正在从spout发出myobject示例。
假设您已将拓扑设置为在1个工作进程中运行。
当一个元组(例如。myobject@1234)是从喷口发出的,storm将检查元组是否需要转到另一个工作者。如果没有,它只是将对象引用传递给bolt1。这就是当你只有一个工人时你所看到的。什么时候myobject@1234 需要从喷口转移到螺栓上,风暴就把螺栓交给他myobject@1234 参考文献。
现在让我们假设您告诉拓扑使用2个worker,而storm决定将喷口放在worker 1中,将螺栓放在worker 2中。回想一下,每个worker都是一个单独的jvm进程,因此将对象引用从worker 1传递到worker 2是行不通的。
当元组从喷口发出时,storm将看到它将被发送到另一个worker,并根据您的配置使用kryo或java序列化对其进行序列化。这意味着myobject@1234 获取序列化。storm将序列化的表单交给worker 2,worker 2对其进行反序列化。当它被反序列化时,它被非常合理地赋予一个新的内存地址(例如。myobject@6789).
如果您将螺栓设计为假设它们不在同一个jvm中运行,那么这不是问题,您绝对应该这样做。例如,如果要将myobject从worker 1传输到worker 2,可以使其可序列化,也可以向kryo注册它(请参见https://storm.apache.org/releases/2.0.0-snapshot/serialization.html). 您需要这样做,这样storm就可以在不破坏拓扑的情况下将您的管道和螺栓放在单独的JVM中。
测试拓扑时,应该启用https://storm.apache.org/releases/1.2.2/javadocs/org/apache/storm/config.html#topology_testing_always_try_serialize. 这将导致storm总是序列化您的元组,即使元组没有在worker之间传输。这可以帮助您在序列化问题进入生产环境之前发现它们。
另外,您应该总是更喜欢kryo序列化而不是java序列化。kryo序列化要快得多。