这些东西没有必要让 Spark 读取输入两次。
列出所有可能的情况:
示例 1: 文件一次都没有读取
x = sc.textFile(...) #creation of RDD
y = x.map(...) #Transformation of RDD
z = x.map(...) #Transformation of RDD
在这种情况下,它不会做任何事情,因为在转换过程中没有任何动作。
示例 2:文件读取一次
x = sc.textFile(...) #creation of RDD
y = x.map(...) #Transformation of RDD
z = x.map(...) #Transformation of RDD
println(y.count()) #Action of RDD
只有一次文件将被 y 读取以使其映射
示例 3:文件读取两次
x = sc.textFile(...) #creation of RDD
y = x.map(...) #Transformation of RDD
z = x.map(...) #Transformation of RDD
println(y.count()) #Action of RDD
println(z.count()) #Action of RDD
现在它只会读取输入文件两次,因为它使用了一个动作
随着转型。
示例 4: 文件读取一次
x = sc.textFile(...) #creation of RDD
y = x.map(...) #Transformation of RDD
z = y.map(...) #Transformation of RDD
println(z.count()) #Action of RDD
示例 5:文件读取两次
x = sc.textFile(...) #creation of RDD
y = x.map(...) #Transformation of RDD
z = y.map(...) #Transformation of RDD
println(y.count()) #Action of RDD
println(z.count()) #Action of RDD
由于action现在用于两个不同的RDD,所以它会读取两次。
示例 6:文件读取一次
x = sc.textFile(...) #creation of RDD
y = x.map(...).cache() #Transformation of RDD
z = y.map(...) #Transformation of RDD
println(y.count()) #Action of RDD
println(z.count()) #Action of RDD
即使是现在,只有一次 RDD 将被执行并存储到内存中时才会使用两种不同的操作。现在第二个操作发生在 Cached RDD 上。
编辑:附加信息
那么问题来了什么要缓存,什么不应该缓存?
Ans:您将反复使用的 RDD 需要缓存。
示例 7:
x = sc.textFile(...) #creation of RDD
y = x.map(...) #Transformation of RDD
z = x.map(...) #Transformation of RDD
所以在这种情况下,我们一次又一次地使用x。所以建议缓存x。因为它不必一次又一次地从源代码读取x。所以如果你正在工作大量数据,这将为您节省大量时间。
假设您开始将所有 RDD 作为缓存在内存/磁盘中,带/不带序列化。如果在 Spark 内存较少的情况下执行任何任务,那么它将开始使用 LRU(最近一次使用)策略删除旧的 RDD。每当再次使用删除的 RDD 时,它将执行从源到到达该 RDD 转换的所有步骤.