疑难解答

本页列出了用户使用Storm时遇到的问题及其解决方案.

worker进程在启动时崩溃,没有堆栈跟踪(stack trace)

可能的现象:

  • Topologies 在单个节点工作正常, 但是多个节点时崩溃

解决方案:

  • 可能部分节点网络配置错误,其中节点无法根据其主机名定位其他节点. 当无法解析主机时,ZeroMQ该进程有时会崩溃. 有两个解决方案:
    • 在 /etc/hosts 文件中配置主机名与IP地址的映射表
    • 设置内部DNS,以便节点可以根据主机名相互定位.

节点无法相互通信

可能的现象:

  • 每个 spout tuple 都失败了
  • 处理不起作用

解决方案:

  • Storm不适用于ipv6. 你可以通过添加强制ipv4 -Djava.net.preferIPv4Stack=true 到 supervisor子选项 然后重启supervisor.
  • 可能部分节点网络配置错误. 查看 worker进程在启动时崩溃,没有堆栈跟踪的解决方案

Topology在一段时间后停止处理tuple

现象:

  • 处理工作正常工作一段时间,然后突然停止,并且spout tuple开始大量失败.

解决方案:

  • 这是ZeroMQ 2.1.10的已知问题. 降级至ZeroMQ 2.1.7

Storm UI中supervisor节点显示缺失

现象:

  • Storm UI 查看部分 supervisor进程缺失
  • Storm UI 在刷新时supervisors 列表会变化

解决方案:

  • 确保supervisor本地目录是独立的(例如,不通过NFS共享本地目录)
  • 尝试删除supervisor的本地目录并重新启动守护进程. supervisor启动时为自己创建一个唯一的ID,并将其存储在本地. 当该id被复制到其他节点时,Storm会感到困惑.

"Multiple defaults.yaml found" 错误

现象:

  • 当使用 "storm jar" 部署topology时发生上述错误

解决方案:

  • 很有可能在您的topology jar中包含有Storm相关jar. 当打包 topology jar时, 不要包含 Storm jars ,Storm 会自动将相关的jar包加入classpath中.

运行storm jar 发生 "NoSuchMethodError"

现象:

  • 当运行 storm jar发生奇怪的 "NoSuchMethodError"错误

解决方案:

  • 您正在使用与构建topology不同的Storm版本来部署topology. 确保您使用的Storm客户端与您编译topology的版本相同

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 tuple发出. 发送到output collector的一切对象都必须是不可变的.当对象被序列化以通过网络发送时您的bolt同时正在修改对象.