那些storm的坑坑

轉載請聲明出處:http://blackwing.iteye.com/blog/2147633

在使用storm的過程中,感覺它還是不如hadoop那麼成熟。當然,它的流式處理能力挺讓人眼前一亮,以前做的個性化推薦都是離線計算,現在總算把實時部分也加上了。

總結一下storm使用的些心得:
1.儘量把大量數據處理行爲分拆成多個處理component。
2.storm不擅長保存狀態,一般需要藉助如redis這些外部存儲比較方便實現邏輯。
3.其實跟1有點類似,不用在component(例如spout或者bolt)中保存大量數據,因爲很容易撐爆內存,導致worker被kill掉。

下面是我遇到的一些坑:
[color=darkred][b][size=medium]1.[/size][/b][/color] 出現錯誤:GC overhead limit exceeded
從[url]http://www.slideshare.net/miguno/apache-storm-09-basic-training-verisign[/url]
這裏的117頁看到:
“OOM: GC overhead limit exceeded” exception, then typically your upstream spouts/bolts are outpacing your downstream bolts.

意思是說,上游的spout或者boltemit的數據速度超過下游bolt的處理速度。因此導致很多emit出去的tuple被緩存起來,積累到一定程度後就會撐爆內存。

[color=darkred]PS:看不到原ppt的可以到附件下載。[/color]

[color=darkred][b][size=medium]2.[/size][/b][/color] 需要在component間傳輸的類,外部類如果對內部類有引用,則內部類也要實現串行化

public Class A implements Serializable {
B tmp = new B();
Class B{
....
}
}


如果A要被emit出去,則B也有串行化,不然下一個接收bolt會包tmp變量爲null錯誤。

public Class A implements Serializable {
B tmp = new B();
Class B implements Serializable{
....
}
}


[color=darkred][b][size=medium]3.[/size][/b][/color] spout、bolt中初始化儘量放到prepare()中進行

public class ReadLogsFromFileEmitSetSpout extends BaseRichSpout {

Configuration conf = new Configuration();
......

}

這個spout在初始化時就會報錯:java.io.NotSerializableException
原因是supervisor先實例化這個spout,再傳輸到具體的worker機器後,跟着調用其prepare()方法來初始化spout,那麼如果在spout聲明變量時就初始化變量,而該變量是不能串行化的,則會報錯。以下是來自google的原文解釋:
The supervisor instantiates the bolts, sends them to the workers, and then calls prepare() on all of them. Therefore, anything that isn't serializable that is instantiated before prepare() causes this process to fail.
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章