Spark RDD的collect()算子與collectPartitions()算子

1.collect的作用    

    Spark內有collect方法,是Action操作裏邊的一個算子,這個方法可以將RDD類型的數據轉化爲數組,你可以隨時val arr = data.collect(),將RDD類型數據轉化爲數組來存放並參與後續運算。

2.已知的弊端

    首先,從時間上來講,前邊已經說過了,collect是Action裏邊的,根據RDD的惰性機制,真正的計算髮生在RDD的Action操作。由於collect是從各節點將數據拉到driver端,需要重新分區,所以,一次collect就會導致一次Shuffle,而一次Shuffle調度一次stage,然而一次stage包含很多個已分解的任務碎片Task。這麼一來,會導致程序運行時間大大增加,屬於比較耗時的操作,即使是在local模式下也同樣耗時。

    其次,從環境上來講,本機local模式下運行並無太大區別,可若放在分佈式環境下運行,一次collect操作會將分佈式各個節點上的數據匯聚到一個driver節點上,而這麼一來,後續所執行的運算和操作就會脫離這個分佈式環境而相當於單機環境下運行,這也與Spark的分佈式理念不合。

    最後,將大量數據彙集到一個driver節點上,並且像這樣val arr = data.collect(),將數據用數組存放,佔用了jvm堆內存,可想而知,是有多麼輕鬆就會內存溢出。

3.如何規避 

    若需要遍歷RDD中元素,大可不必使用collect,可以使用foreach語句;

    若需要打印RDD中元素,可用take語句,data.take(1000).foreach(println),這點官方文檔裏有說明;

    若需要查看其中內容,可用saveAsTextFile方法。

總之,單機環境下使用collect問題並不大,但分佈式環境下儘量規避,如有其他需要,手動編寫代碼實現相應功能就好。

補充:

    collectPartitions:同樣屬於Action的一種操作,同樣也會將數據彙集到Driver節點上,與collect區別並不是很大,唯一的區別是:collectPartitions產生數據類型不同於collect,collect是將所有RDD彙集到一個數組裏,而collectPartitions是將各個分區內所有元素存儲到一個數組裏,再將這些數組彙集到driver端產生一個數組;collect產生一維數組,而collectPartitions產生二維數組。

例:

   RDD類型data,數據類型爲[labeledPoint],labeledPoint爲(label,features)

   那麼 val collectArr = data.collect();(collectArr內數組元素爲labeledPoint[label,features]) 

   而val collectPArr= data.collectPartitions();(collectPArr內數組元素爲Array[label,features],即爲二維數組)
————————————————
版權聲明:本文爲CSDN博主「Fortuna_i」的原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/Fortuna_i/article/details/80851775

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