ApacheStorm官方文件——問題與解決

青衫無名發表於2017-05-22

本文介紹了使用者在使用 Storm 過程中遇到的問題與相應的解決方法。

Worker 程式在啟動時掛掉而沒有留下堆疊跟蹤資訊的問題

可能出現的現象:

  • 拓撲在一個節點上執行正常,但是多個 worker 程式在多個節點上就會崩潰

解決方案:

  • 你的網路配置可能有問題,導致每個節點無法根據 hostname 連線到其他的節點。ZeroMQ 有時會在不能識別 host 的時候掛掉 程式。如果是這種情況,有兩種可行的解決方案:
    • 在 /etc/hosts 檔案中配置好 hostname 與 IP 的對應關係
    • 設定一個區域網 DNS 伺服器,使得節點可以根據 hostname 定位到其他節點

節點之間無法通訊

可能出現的現象:

  • 每個 spout tuple 的處理都不成功
  • 拓撲中的處理過程不起作用

解決方案:

  • Storm 不支援 ipv6,你可以在 supervisor 的 child-opts 配置中新增 -Djava.net.preferIPv4Stack=true 引數,然後重啟 supervisor。
  • 你的網路配置可能存在問題,請參考上個問題中的解決方案。

拓撲在一段時間後停止了 tuple 的處理過程

可能出現的現象:

  • 拓撲正常執行一段時間後突然停止了資料處理過程,並且 spout 的 tuple 一起開始處理失敗

解決方案:

  • 這是 ZeroMQ 2.1.10 中的一個已經確認的問題,請將 ZMQ 降級到 2.1.7 版本。

Storm UI 中沒有顯示出所有的 supervisor 資訊

可能出現的現象:

  • Storm UI 中缺少部分 supervisor 的資訊
  • 在重新整理 Storm UI 頁面後 supervisor 列表會變化

解決方案:

  • 確保 supervisor 的本地工作目錄是相互獨立的(也就是說不要出現在 NFS 中共享同一個目錄的情況)
  • 嘗試刪除 supervisor 的本地工作目錄,然後重啟 supervisor 後臺程式。supervisor 啟動時會為自己建立一個唯一的 id 並儲存在本地目錄中。如果這個 id 被複制到其他節點中,就會讓 Storm 無法確定哪個 supervisor 正在執行(這種情況並不少見,如果需要擴充套件叢集,就很容易出現直接將某個節點的 Storm 檔案直接複製到新節點的情況 —— 譯者注)。

“Multiple defaults.yaml found” 錯誤

可能出現的現象:

  • 在使用 storm jar 命令部署拓撲時出現此錯誤

解決方案:

  • 你很可能在拓撲的 jar 包中包含了 Storm 自身的 jar 包。注意,在打包拓撲時,請不要將 Storm 自身的 jar 包加入,因為 Storm 已經在它的 classpath 中提供了這些 jar 包。

執行 storm jar 命令時出現 “NoSuchMethorError”

可能出現的現象:

  • 執行 storm jar 命令時出現奇怪的 “NoSuchMethodError”

解決方案:

  • 這可能是由於你部署拓撲的 Storm 版本與你構建拓撲時使用的 Storm 版本不同。請確保你編譯拓撲時使用的 Storm 版本與你執行拓撲的 Storm 客戶端版本相同。

Kryo ConcurrentModificationException

可能出現的現象:

  • 系統執行時出現如下的異常堆疊跟蹤資訊
java.lang.RuntimeException: java.util.ConcurrentModificationException
    at backtype.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:84)
    at backtype.storm.utils.DisruptorQueue.consumeBatchWhenAvailable(DisruptorQueue.java:55)
    at backtype.storm.disruptor$consume_batch_when_available.invoke(disruptor.clj:56)
    at backtype.storm.disruptor$consume_loop_STAR_$fn__1597.invoke(disruptor.clj:67)
    at backtype.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 backtype.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 backtype.storm.serialization.KryoValuesSerializer.serializeInto(KryoValuesSerializer.java:27)

解決方案:

  • 這個資訊表示你在將一個可變的物件作為 tuple 傳送出去。你傳送到 outputcollector 中的所有物件必須是非可變的。這個錯誤表明物件在被序列化併傳送到網路中時你的 bolt 正在修改這個物件。

Storm 中的 NullPointerException

可能出現的現象:

  • Storm 執行中出現瞭如下的 NullPointerException
java.lang.RuntimeException: java.lang.NullPointerException
    at backtype.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:84)
    at backtype.storm.utils.DisruptorQueue.consumeBatchWhenAvailable(DisruptorQueue.java:55)
    at backtype.storm.disruptor$consume_batch_when_available.invoke(disruptor.clj:56)
    at backtype.storm.disruptor$consume_loop_STAR_$fn__1596.invoke(disruptor.clj:67)
    at backtype.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:662)
Caused by: java.lang.NullPointerException
    at backtype.storm.serialization.KryoTupleSerializer.serialize(KryoTupleSerializer.java:24)
    at backtype.storm.daemon.worker$mk_transfer_fn$fn__4126$fn__4130.invoke(worker.clj:99)
    at backtype.storm.util$fast_list_map.invoke(util.clj:771)
    at backtype.storm.daemon.worker$mk_transfer_fn$fn__4126.invoke(worker.clj:99)
    at backtype.storm.daemon.executor$start_batch_transfer__GT_worker_handler_BANG_$fn__3904.invoke(executor.clj:205)
    at backtype.storm.disruptor$clojure_handler$reify__1584.onEvent(disruptor.clj:43)
    at backtype.storm.utils.DisruptorQueue.consumeBatchToCursor(DisruptorQueue.java:81)
    ... 6 more

解決方案:

  • 這個問題是由於多個執行緒同時呼叫 OutputCollector 中的方法造成的。Storm 中所有的 emit、ack、fail 方法必須在同一個執行緒中執行。出現這個問題的一種場景是在一個 IBasicBolt 中建立了一個獨立的執行緒。由於 IBasicBolt 會在execute 方法呼叫之後自動呼叫 ack,所以這就會出現多個執行緒同時使用 OutputCollector 的情況,進而丟擲這個異常。也就是說,在使用 IBasicBolt 時,所有的訊息傳送操作必須在同一個執行緒的 execute 方法中執行。
  • 轉載自 併發程式設計網 – ifeve.com


相關文章