【问题标题】:Does an RDD need to be cached if used more than once?如果多次使用 RDD 是否需要缓存?
【发布时间】:2015-12-31 13:13:53
【问题描述】:

假设我们有以下代码。

x = sc.textFile(...)
y = x.map(...)
z = x.map(...)

这里有必要缓存x吗?不会缓存x 让 spark 读取输入文件两次吗?

【问题讨论】:

  • 不,这不是必需的。但是如果 RDD 被缓存,您的应用程序将运行得更快。如果它没有被缓存,数据将从文件系统中读取两次,在你的例子中。

标签: python scala hadoop apache-spark rdd


【解决方案1】:

这些东西没有必要让 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 转换的所有步骤.

【讨论】:

  • 所以,基本上,你可以在一个 RDD 上进行尽可能多的转换,但动作不能超过一次。
  • 转换将毫无用处,除非该转换存在操作。
  • 添加更多内容。假设您开始将所有 RDD 作为缓存在内存/磁盘中,带/不带序列化。如果在 Spark 内存较少的情况下执行任何任务,那么它将开始使用 LRU(最近一次使用)策略删除旧的 RDD。
  • @imagin 我建议您在最后一条评论中回答,因为它是有用的信息。 (不是每个人都会阅读答案中的所有 cmets)
  • 很好的答案!很好的例子。 first 只会触发第一个分区的处理。 (除非它是空的。)您可以提及这一点或使用count 作为操作。我要补充的另一件事是,重新读取文件可能比缓存它更快。一般来说,决定是否缓存的唯一方法是对特定代码进行基准测试。 (根据经验,我同意你的建议!)
猜你喜欢
  • 1970-01-01
  • 2010-12-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多