Spark - 作用域、数据框和内存管理

Spark - Scope, Data Frame, and memory management

我很好奇作用域如何与 Data Frame 和 Spark 一起工作。在下面的示例中,我有一个文件列表,每个文件都独立加载到一个数据框中,执行一些操作,然后我们将 dfOutput 写入磁盘。

val files = getListOfFiles("outputs/emailsSplit")

for (file <- files){

   val df = sqlContext.read
      .format("com.databricks.spark.csv")
      .option("delimiter","\t")          // Delimiter is tab
      .option("parserLib", "UNIVOCITY")  // Parser, which deals better with the email formatting
      .schema(customSchema)              // Schema of the table
      .load(file.toString)                        // Input file


   val dfOutput = df.[stuff happens]

    dfOutput.write.format("com.databricks.spark.csv").mode("overwrite").option("header", "true").save("outputs/sentSplit/sentiment"+file.toString+".csv") 

}
  1. for loop 中的每个数据帧是在循环完成后被丢弃,还是留在内存中?
  2. 如果不丢弃它们,此时进行内存管理的更好方法是什么?

DataFrame 物体很小。但是,它们可以引用 Spark 执行器上缓存中的数据,并且可以引用 Spark 执行器上的随机播放文件。当 DataFrame 被垃圾回收时,也会导致缓存和随机播放文件在执行程序上被删除。

在您的代码中,没有对循环后的 DataFrame 的引用。所以他们有资格进行垃圾收集。垃圾收集通常是为了响应内存压力而发生的。如果您担心 shuffle 文件填满磁盘,触发显式 GC 以确保删除不再引用的 DataFrame 的 shuffle 文件可能是有意义的。

根据您对 DataFrame 所做的操作 ([stuff happens]),可能没有数据存储在内存中。这是 Spark 中的默认操作模式。如果你只是想读取一些数据,转换它,然后写回,这一切都会逐行发生,永远不会将任何数据存储在内存中。 (缓存仅在您明确要求时发生。)

综上所述,我建议在遇到问题之前不要担心内存管理。