rdd.map两次调用一个函数,而不是一次

时间:2019-06-25 10:22:57

标签: scala apache-spark rdd

我是Scala编程的新手,目前正在使用RDD。我试图将RDD传递给函数,并希望函数返回,以便可以将其存储到新的RDD。为此,我正在使用地图。但是map调用了该函数两次,而RDD中只有一个条目。当我使用collect.foreach()而不是map时,它可以正常工作,但是我无法将更新值保存在新的RDD中,因为它在Unit中返回一个值。

此代码从更新函数返回值,但两次调用该函数:

temp_rdd = my_rdd.map{x => update(x)}

尽管这一次完美地调用了它,但是我无法修改RDD值:

my_rdd.collect().foreach{x => update(x)}

由于ehich我无法将其保存在新的RDD中,因此foreach函数以“单位”返回格式。我正在寻找一种将更新的值存储在新的RDD中的方法。

1 个答案:

答案 0 :(得分:2)

来自https://spark.apache.org/docs/2.2.0/rdd-programming-guide.html

map是一种转换,它将每个数据集元素通过一个函数传递,并返回代表结果的新RDD。 Spark中的所有转换都是惰性的,并且在操作需要将结果返回到驱动程序时进行计算。默认情况下,每次您对其执行操作时,每个转换后的RDD都可能会重新计算(或者您可以使用.cache()将RDD保留在内存中)。

另一方面,在RDD上运行计算后,操作(例如collectreduce)向驱动程序返回一个值(不是RDD)

下面是一个缓存RDD以防止多次计算的示例

val array = Array("1", "2", "3")
val rdd = sc.parallelize(array)
var i = 0
val mapRdd = rdd.map(s"$i: " + _)
mapRdd.take(3).foreach(println) // mapRdd is computed here...
// Output
// 0: 1
// 0: 2
// 0: 3

i = i + 1
mapRdd.take(3).foreach(println) // ... and here
// Output
// 1: 1
// 1: 2
// 1: 3

val cachedMapRdd = rdd.map(s"$i: " + _).cache()
cachedMapRdd.take(3).foreach(println) // cachedMapRdd is computed here...
// Output
// 1: 1
// 1: 2
// 1: 3

i = i + 1
cachedMapRdd.take(3).foreach(println) // ... but not here
// Output
// 1: 1
// 1: 2
// 1: 3