Storm UI介面上出現的Spout Failed 問題解決方案
阿新 • • 發佈:2019-02-03
提問:
1. 在Storm UI上,有大量Failed資料,且往往是一旦開始有Fail資料,則Fail資料越積越多
2. 整體事件端到端延遲很大
分析:
當spout接收到大量資料,而後端bolt處理較慢,如果spout傳送的事件在超時時間(topology.message.timeout.secs 預設為30s)內沒有最終ACK閉環,即在超時時間內最初的原始訊息沒有最終獲得處理完成的ACK響應時,該事件成為Fail事件。當輸入資料量大,且後端處理較為耗時,而無法在設定時間內處理完且ACK時,則會造成超時FAIL。
解決方案:
1、 加大topology.message.timeout.secs預設超時時間,如60s
2、 觀察系統ACK執行緒處理效能,如UI介面中的:
如果該處理效能較低可考慮增加ACK執行緒數:topology.acker.executors(預設為null,即與該任務的work數一致),可設定為worker的倍數
3、 減少topology.max.spout.pending(預設為null,即不做限制),該配置項可以對spout task接收速度進行流控,例如可以從設定topology.max.spout.pending = 1024開始,即表示當spout傳送的資料已經將該pending佇列佔滿,則在該佇列滿未有空間時,spout的nextTuple方法不被呼叫,即進行了流控
可能的影響:
topology.max.spout.pending設定後,會降低整個系統的吞吐量,可以先從1024開始,不斷增加,最終達到系統穩定且吞吐量合適。
這個問題比較麻煩!定位了很久(至少花了我10天左右的時間)才解決此問題!
出現此問題的原因是: spout在預設超時時間(30s)內發射出去的Tuple沒有被bolt處理就會出現spout failed。 嘗試解決問題的過程: 1、調整bolt的worker、executor、task數目,希望能夠解決問題。結果失敗! 2、調整修改預設超時時間(topology.message.timeout.secs)為60s,修改spout的快取佇列(topology.max.spout.pending)由於我的資料量不大,每天處理資料也就最多500M,把它設定成200,由於我設定spout的併發度為5,所以可以暫存1000條tuple(spout數 乘以 topology.max.spout.pending)。結果過了幾個小時還是出現Spout Failed! 3、好吧,我再觀察storm ui介面,發現有兩個bolt延時較大(超過1s),網上看了許多資料,最終判定是bolt處理延時過高,處理速度緩慢,導致spout發射的Tuple堆積過多,很多Tuple在超時時間內沒有被bolt處理,因此發生Spout Failed的慘劇! 解決辦法: 1)找出bolt哪裡耗時最多!在程式碼裡面一步一步打印出時間,比如對資料進行過濾的程式碼處理用了多長時間,入庫用了多長時間... 2)後來我發現,資料插入到hbase裡面耗時最大!!!幾乎達到1s,而且我是一條一條資料進行插入的! 怎麼辦呢?想要減小bolt延時必然需要解決hbase插入資料耗時較大的問題,於是我想到對資料進行批量插入,比如說來了100條Tuple才執行插入操作。因此這100條Tuple需要暫時存放在一個地方,我想到的是用arraylist暫時存放資料。最後執行一下修改後的程式碼,發現問題應該被解決了。 4、未用批量插入和批量插入資料後的區別 1)未用批量插入2)使用批量插入後