性能優化1:kryo序列化
定制序列化
- 自定義的bolt之間emit數據是實體類的時候,注冊kryo
- Storm 使用 Kryo 來處理序列化。如果要實現自定義的序列化生成器,需要注冊一個新的 Kryo 的序列化生成器。
可以通過拓撲的 topology.kryo.register 屬性來添加自定義序列化生成器。兩種姿勢:
只有一個待注冊的類的名稱。在這種情況下,Storm 會使用 Kryo 的 FieldsSerializer 來序列化該類。conf.registerSerialization(UserEntity.class);
一個包含待注冊的類的名稱和對應的序列化實現類名稱,該序列化實現類實現了 com.esotericsoftware.kryo.Serializer接口。
topology.kryo.register:
- com.ly.CustomType1
- com.ly.CustomType2: com.ly.serializer.CustomType2Serializer
- com.ly.CustomType3
Storm序列化文章:
https://www.cnblogs.com/intsmaze/p/7044042.html
http://storm.apache.org/releases/1.0.6/Serialization.html
性能優化2:KafkaBolt批量提交
props.put("request.required.acks", "0");
props.put("producer.type", " async");
props.put("message.send.max.retries", "3");?props.put("batch.num.messages", "200");
props.put("send.buffer.bytes", "1024*100");
性能優化3:使用組件的并行度代替線程池
Storm 自身是一個分布式、多線程的框架,對每個Spout 和Bolt,我們都可以設置其并發度;它也支持通過rebalance 命令來動態調整并發度,把負載分攤到多個Worker 上。如果自己在組件內部采用線程池做一些計算密集型的任務,比如JSON 解析,有可能使得某些組件的資源消耗特別高,其他組件又很低,導致Worker 之間資源消耗不均衡,這種情況在組件并行度比較低的時候更明顯。
如某個Bolt 設置了1 個并行度,但在Bolt 中又啟動了線程池,這樣導致的一種后果就是,集群中分配了這個Bolt 的Worker 進程可能會把機器的資源都給消耗光了,影響到其他Topology 在這臺機器上的任務的運行。如果真有計算密集型的任務,我們可以把組件的并發度設大,Worker 的數量也相應提高,讓計算分配到多個節點上。
性能優化4:注意fieldsGrouping 的數據均衡性
fieldsGrouping 是根據一個或者多個Field 對數據進行分組,不同的目標Task 收到不同的數據,而同一個Task 收到的數據會相同。
假設某個Bolt 根據用戶ID 對數據進行fieldsGrouping,如果某一些用戶的數據特別多,而另外一些用戶的數據又比較少,那么就可能使得下一級處理Bolt 收到的數據不均衡,整個處理的性能就會受制于某些數據量大的節點。可以加入更多的分組條件或者更換分組策略,使得數據具有均衡性。
性能優化5:優先使用localOrShuffleGrouping
localOrShuffleGrouping 是指如果目標Bolt 中的一個或者多個Task 和當前產生數據的Task 在同一個Worker 進程里面,那么就走內部的線程間通信,將Tuple 直接發給在當前Worker 進程的目的Task。否則,同shuffleGrouping。localOrShuffleGrouping 的數據傳輸性能優于shuffleGrouping,因為在Worker 內部傳輸,只需要通過Disruptor 隊列就可以完成,沒有網絡開銷和序列化開銷。因此在數據處理的復雜度不高, 而網絡開銷和序列化開銷占主要地位的情況下,可以優先使用localOrShuffleGrouping 來代替shuffleGrouping。
性能優化6:設置合理的Worker 數
Worker 數越多,性能越好?先看一張Worker 數量和吞吐量對比的曲線
從圖可以看出,在12 個Worker 的情況下,吞吐量最大,整體性能最優。這是由于一方面,每新增加一個Worker 進程,都會將一些原本線程間的內存通信變為進程間的網絡通信,這些進程間的網絡通信還需要進行序列化與反序列化操作,這些降低了吞吐率。
另一方面,每新增加一個Worker 進程,都會額外地增加多個線程(Netty 發送和接收線程、心跳線程、SystemBolt 線程以及其他系統組件對應的線程等),這些線程切換消耗了不少CPU,sys 系統CPU 消耗占比增加,在CPU 總使用率受限的情況下,降低了業務線程的使用效率。