[英]Sorting an RDD in Apache Spark using mapPartitions and reduce
[英]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
接受从Iterator
到Iterator
的函数。
通常,如果您使用参考数据,则可以用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.