簡體   English   中英

Spark RDD- map與mapPartitions

[英]Spark RDD- map vs mapPartitions

我通讀了map和mapPartitions之間的理論差異,並且很清楚何時在各種情況下使用它們。

但是我下面描述的問題更多地取決於GC活動和內存(RAM)。 有關問題,請閱讀以下內容:

=>我編寫了一個映射函數,將Row轉換為String。 因此,RDD [org.apache.spark.sql.Row]的輸入將映射到RDD [String]。 但是,通過這種方法,將為RDD的每一行創建映射對象。 因此,創建如此大量的對象可能會增加GC活動。

=>要解決以上問題,我想到了使用mapPartitions。 因此,該對象數等於分區數。 mapPartitions提供Iterator作為輸入,並接受return和java.lang.Iterable。 但是大多數Iterable(例如Array,List等)都在內存中。 那么,如果我有大量數據,那么以這種方式創建Iterable會導致內存不足嗎? 還是在這里應該使用其他任何集合(java或scala)(以防萬一內存開始填充到磁盤上)? 還是僅在RDD完全在內存中的情況下才使用mapPartitions?

提前致謝。 任何幫助將不勝感激。

如果您考慮使用JavaRDD.mapPartitions則需要使用FlatMapFunction (或某些類似DoubleFlatMapFunction變體),該函數將返回Iterator not Iterable 如果底層收集很懶,那么您就不用擔心。

RDD.mapPartitions接受從IteratorIterator的函數。

通常,如果您使用參考數據,則可以用map替換mapPartitions並使用靜態成員來存儲數據。 這將具有相同的占用空間,並且更易於編寫。

回答有關mapPartition(f:Iterator => Iterator)的問題。 它是懶惰的,並且不將整個分區保存在mem中。 Spark將使用此(我們可以認為它是FP術語中的Functor)Iterator => Iterator函數,並將其重新編譯為自己的代碼以執行。 如果分區太大,它將在下一個隨機播放點之前溢出到磁盤。 所以不用擔心

需要提到的一件事是,您可以通過執行以下操作來強制函數將數據具體化為內存:

rdd.mapPartition(
  partitionIter => {
    partitionIter.map(do your logic).toList.toIterator
  }
)

toList將強制Spark將整個分區的數據具體化為mem,因此請注意這一點,因為類似於toList ops將打破功能鏈的惰性。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM