缓存一个大的RDD或许多小型RDD

时间:2017-12-21 16:38:08

标签: scala apache-spark

我有一个大的RDD(R),我把它切成20个块(C_1,C_2,...,C_20),这样:

Smaller chunks

如果缓存所需的时间仅取决于RDD的大小(例如每MB 10秒),则缓存单个块更好。

但是,我怀疑还有一些我不知道的额外开销,比如在持续存放到磁盘的情况下寻找时间。

所以,我的问题是:

  • 写入内存时是否还有其他开销?
  • 缓存(即在内存中)大型RDD(R)或20个单独块是否更好?

编辑:为了提供更多上下文,我目前正在我的计算机上运行该应用程序,但最后它将在由10个节点组成的集群上运行,每个节点有8个核心。但是,由于我们只能在很短的时间内访问群集,因此我想在我的计算机上进行本地实验。

根据我的理解,应用程序不需要大量的改组,因为我可以很好地对它进行分区,这样每个块都可以在一个节点上运行。 但是,我仍然在考虑分区,所以还没有100%决定。

1 个答案:

答案 0 :(得分:1)

Spark在内存中执行计算。因此,当您将数据缓存到内存时,没有真正的额外开销。缓存到内存本质上说,重用这些中间结果。您可能遇到的唯一问题是内存中的数据太多,然后溢出到磁盘。在那里,您将产生磁盘读取时间成本。如果遇到内存限制,当你完成各种中间结果时,将需要unpersist()来交换内存。

在确定数据缓存位置时,您需要查看数据流。如果你读入一个文件,然后过滤它3次并分别写出这些过滤器中的每一个,没有缓存,你将最终在该文件中读取3次。

val data = spark.read.parquet("file:///testdata/").limit(100)
data.select("col1").write.parquet("file:///test1/")
data.select("col2").write.parquet("file:///test2/")
data.select("col3").write.parquet("file:///test3/")

如果你读入文件,缓存它,然后你过滤3次并写出结果。您将在文件中读取一次,然后写出每个结果。

val data = spark.read.parquet("file:///testdata/").limit(100).cache()
data.select("col1").write.parquet("file:///test4/")
data.select("col2").write.parquet("file:///test5/")
data.select("col3").write.parquet("file:///test6/")

您可以使用的常规测试是,"我是否在同一个RDD上执行多项操作?"如果是,请缓存它。在您的示例中,如果您将大型RDD分解为块并且大型RDD未被缓存,则每次对其执行操作时,您很可能会重新计算大型RDD。然后,如果你不缓存这些块并对那些块执行多个操作,那么每次都必须重新计算这些块。

  

缓存(即在内存中)大型RDD(R)或20个单独块是否更好?

所以回答这个问题,一切都取决于你对每个中间结果做了什么。看起来您肯定希望根据执行程序的数量对大型RDD进行适当的重新分区,然后对其进行缓存。然后,如果您对从大型RDD创建的每个块执行多个操作,则可能需要缓存这些操作。