当中间输出不适合Spark中的RAM时会发生什么

时间:2015-10-18 05:26:06

标签: hadoop apache-spark rdd

我刚开始学习Spark。根据我的理解,Spark将中间输出存储在RAM中,因此与Hadoop相比非常快。如果我错了,请纠正我。

我的问题是,如果我的中间输出是2 GB而我的空闲RAM是1 GB,那么在这种情况下会发生什么?这可能是一个愚蠢的问题,但我还没有理解Spark的内存概念。任何人都可以向我解释一下Spark的内存概念吗?

由于

2 个答案:

答案 0 :(得分:6)

这个问题是在Spark中询问RDD persistence

  

您可以使用persist()或cache()方法标记要保留的RDD。第一次在动作中计算它,它将保留在节点的内存中。 Spark的缓存是容错的 - 如果丢失了RDD的任何分区,它将使用最初创建它的转换自动重新计算。

根据您为RDD设置存储级别的方式,可以配置不同的结果。例如,如果将存储级别设置为MEMORY_ONLY(这是默认存储级别),则输出将尽可能多地存储在内存中,并在运行时重新计算其余的RDD。您可以保留RDD并应用以下存储级别:rdd.persist(MEMORY_ONLY)

在您的示例中,将计算1GB的输出并在内存中,并在将来步骤需要时计算另一个1GB。根据您的使用情况,还可以设置其他存储级别:

  1. MEMORY_AND_DISK - 计算整个RDD,但在必要时将一些内容泄露到磁盘
  2. MEMORY_ONLY_SERMEMORY_AND_DISK_SER - 与上述相同,但所有元素都已序列化
  3. DISK_ONLY - 将所有分区直接存储到磁盘
  4. MEMORY_ONLY_2MEMORY_AND_DISK_2 - 与上述相同,但分区会被复制两次以获得更大的容忍度
  5. 同样,您必须查看您的用例以确定最佳存储级别。在某些情况下,重新计算RDD实际上可能比从磁盘加载所有内容更快。在其他情况下,快速序列化程序可以减少从磁盘中获取的数据,从而快速响应所讨论的数据。

答案 1 :(得分:2)

如果我理解你的问题,我可以回复以下内容:

配置Spark上下文时,{em>中间或临时存储目录由spark.local.dir配置参数指定。

spark.local.dir目录用于Spark中的“临时”空间,包括映射输出文件和存储在磁盘上的RDD。 [Ref. Spark Configuration.]

这应该位于系统中快速的本地磁盘上。它也可以是不同磁盘上多个目录的逗号分隔列表。

然而,您在此处解决的问题也称为RDD持久性。在您应该已经知道使用Spark缓存的基础知识中,还有一种称为RDD的存储级别,它允许不同的存储级别。

例如,这将允许您将数据集保留在磁盘上将其保留在内存中但作为序列化Java对象(以节省空间),跨节点复制它,或者将它存储在Tachyon的堆外 (最后一个是实验性的)More information here

注意:通过将StorageLevel对象(Scala,Java,Python)传递给persist来设置这些级别。 cache方法是使用默认存储级别的简写,即StorageLevel.MEMORY_ONLY,其中Spark将反序列化的对象存储在内存中。

现在回答你的问题,

如果我的中间输出为2 GB且我的可用内存为1 GB,那么在这种情况下会发生什么?

我说这取决于你如何配置和调整你的Spark(app,cluster)。

注意: Spark中的内存类似于世界上任何内存系统的概念,主要目的是避免繁重且昂贵的IO。这也意味着,如果我回到你的问题,如果你决定坚持DISK每说,你将失去性能。更多内容在答案中引用的官方文档中。