Spark streaming實時計算程序的性能優化

一、並行化數據接收

這個 方法在處理多個topic的數據是比較有效。

int numStreams = 5;

List<JavaPairDStream<String, String>> kafkaStreams = new ArrayList<JavaPairDStream<String, String>>(numStreams);

for (int i = 0; i < numStreams; i++) {

  kafkaStreams.add(KafkaUtils.createStream(...));

}

JavaPairDStream<String, String> unifiedStream = streamingContext.union(kafkaStreams.get(0), kafkaStreams.subList(1, kafkaStreams.size()));

unifiedStream.print()

 

二、調節blockInterval參數

主旨:增加block數量,增加每個batch rdd的partition的數量,增加處理的並行度。

receiver從數據源源源不斷地獲取到數據,首先會按照block interval,將指定時間間隔的數據收集到一個block;默認時間是200ms,官方推薦不要小於50ms;然後會將指定batch interval時間間隔內的block合併爲一個batch,創建爲一個rdd,然後啓動一個job去處理這個batch rdd中的數據。

batch rdd的partition數量的確定:一個batch有多少個block,就有多少個partition,就意味着並行度是多少,意味着每個batch rdd有多少個task會並行計算和處理。

我們希望可以閉默認的task數量和並行度再多一些,可以手動調節block interval,減少block interval的數值,讓每個batch可以包含更多的block,有更多的partition,也就有更多的task並行處理每個batch rdd。

 

三、重分區

InputStream.repartition(<number of partitions>),增加每個batch rdd的partition數量,這樣可以提高指定的dstream的rdd的計算並行度。

 

四、調節並行度

調節參數:

spark.default.parallelism

reduceByKey(numPartitions)

 

五、使用Kryo序列化機制

提高序列化task發送到executor上執行的性能,如果task很多的時候,task序列化和反序列化的性能開銷會比較可觀。

默認輸入數據的存儲級別是StorageLevel.MEMORY_AND_DISK_SER_2,receiver接收到數據,默認就會進行持久化操作。首先持久化數據,存儲到內存中;如果內存資源不夠大,那麼就寫入磁盤;而且還會有一份冗餘副本寫到其他executor的block manager中。

 

六、設置batch interval

設置該參數,使每個batch的運行時間小於該參數。batch的運行時間可以通過spark ui進行查看。

如果發現batch的處理時間大於batch interval,必須調節batch interval,不要讓batch的處理時間大於batch interval。

比如batch每隔5秒生成一次,batch的處理時間要達到6秒。這個時候,batch在內存中日積月累,一直囤積着,沒法及時計算掉,釋放資源;而且對內存空間的佔用越來越大,導致內存空間快速消耗。

如果發現batch處理時間比batch interval大,儘量將batch interval調大一些。

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章