这篇博客列出了在storm官方文档中提及的在storm使用过程中常见的问题及其解决方案。
一、Worker 进程在启动时崩溃,没有堆栈跟踪
可能的现象:
- topology任务都运行在一个节点上,但多节点worker奔溃。
可能的原因:
可能是子网配置错误,其节点无法根据主机名定位其他节点。 ZeroMQ 有时会由于无法解析主机而使进程崩溃。
解决方案:
有两种解决方案:
- 在
/etc/hosts中建立从主机名到 IP 地址的映射。 - 设置内部 DNS,以便节点可以根据主机名相互定位。
二、节点间无法相互通信
可能的现象:
- 每个spout元组都失败
- 进程未工作
解决方案:
- Storm不适用于ipv6.可以通过将
-Djava.net.preferIPv4Stack=true添加到supervisor子选项中来强制使用ipv4. - 子网可能配置错误。解决方法可参考上一个问题的解决方案。
三、topology在一段时间后停止处理元组
现象:
- 进程在正常工作一段时间后突然停止,并且spout 元组开始大量失败。
解决方案:
- 这是 ZeroMQ 2.1.10 的一个已知问题。将版本降到 ZeroMQ 2.1.7即可。
四、Storm UI上未展示所有supervisor
现象:
- 一些supervisor进程未在Strom UI上显示
- 在Storm UI刷新时,supervisor列表发送改变
解决方案:
- 确保supervisor的本地目录为独立目录,而不是共享目录之类的。
- 尝试删除supervisor本地目录并重启supervisor进程。supervisor会为自身创建一个唯一id并存储在本地。当 supervisor的id与其他节点相同时,storm无法区分。
五、"Multiple defaults.yaml found" error
现象:
- 当通过“Storm jar”执行一个任务时,就会抛出该error。
解决方案:
- 有可能在任务jar包中包含了 Storm 的jar。 打包拓扑的 jar 时,不要包含 Storm 的jar,因为 Storm 会将它们放在类路径中。
执行任务时,抛出"NoSuchMethodError"
现象:
- 当运行topology任务时,获得惊喜"NoSuchMethodError"。
解决方案:
- 构建topology时的storm版本与集群中部署的storm版本不一致。确保你编译topology的storm版本与集群中storm版本一致。
六、Kryo ConcurrentModificationException
现象:
- 在运行期间,得到如下堆栈信息:
java.lang.RuntimeException: java.util.ConcurrentModificationException
at org.apache.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:84)
at org.apache.storm.utils.DisruptorQueue.consumeBatchWhenAvailable(DisruptorQueue.java:55)
at org.apache.storm.disruptor$consume_batch_when_available.invoke(disruptor.clj:56)
at org.apache.storm.disruptor$consume_loop_STAR_$fn__1597.invoke(disruptor.clj:67)
at org.apache.storm.util$async_loop$fn__465.invoke(util.clj:377)
at clojure.lang.AFn.run(AFn.java:24)
at java.lang.Thread.run(Thread.java:679)
Caused by: java.util.ConcurrentModificationException
at java.util.LinkedHashMap$LinkedHashIterator.nextEntry(LinkedHashMap.java:390)
at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:409)
at java.util.LinkedHashMap$EntryIterator.next(LinkedHashMap.java:408)
at java.util.HashMap.writeObject(HashMap.java:1016)
at sun.reflect.GeneratedMethodAccessor17.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:616)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:959)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at org.apache.storm.serialization.SerializableSerializer.write(SerializableSerializer.java:21)
at com.esotericsoftware.kryo.Kryo.writeClassAndObject(Kryo.java:554)
at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:77)
at com.esotericsoftware.kryo.serializers.CollectionSerializer.write(CollectionSerializer.java:18)
at com.esotericsoftware.kryo.Kryo.writeObject(Kryo.java:472)
at org.apache.storm.serialization.KryoValuesSerializer.serializeInto(KryoValuesSerializer.java:27)
解决方案:
- 导致的可能原因是发送一个可变对象作为输出元组。发射到output collector中的所有内容都必须是不可变的。而情况是,bolt正在修改对象,而该对象正在序列化以通过网络发送。从而导致上述异常。
该博客仅为初学者自我学习的记录,粗浅之言,如有不对之处,恳请指正。