本文介绍如何把一个很大的RDD安全取回到Driver端本地的方法。
问题的提出
有时需要把RDD或Dataframe的数据获取到本地进行保存或处理。一般的方法是使用collect()函数来操作,但若数据集的数据量很大,就会导致Driver端的OOM错误。此时,需要考虑使用其他方式来处理。
问题的解决
可以这样考虑,要是把整个RDD取回来不行,那么是否可以按分区把数据取回。
val parts = rdd.partitions
for (p <- parts) {
val idx = p.index
// 注意第2个参数是true,这样避免rdd的重复shuffle操作
val partRdd = rdd.mapPartitionsWithIndex(
a => if (a._1 == idx) a._2 else Iterator(),
true)
// 以数组的方式把分区数据获取到本地
val data = partRdd.collect
// 使用本地的分区数据
/**
* 这里可以对data进行自己的处理,或则保存到文件,或则迭代访问等操作
*/
}
小结
本文介绍了如何把一个很大的RDD或Dataframe取回到Driver端,并进行保存的方法。