提问者:小点点

Spark驱动程序在读取多个文件时内存不足


我的程序是这样工作的:

  1. 读取大量文件作为数据帧。在这些文件中有大约60个文件,每个文件有5k行,我为每个文件创建一个单独的数据帧,做一些简单的处理,然后将它们合并成一个数据帧,用于进一步的连接。
  2. 我对一些数据帧执行了一些连接和列计算,最终得到一个目标数据帧。
  3. 我将目标数据框保存为一个拼花文件。
  4. 在同一个Spark应用程序中,我加载了那个拼花文件,并在该数据框上进行了一些繁重的聚合,然后进行了多个自连接。
  5. 我将第二个数据帧保存为另一个拼花文件。

问题

如果我只有一个文件,而不是我上面提到的60个文件,那么所有的驱动程序都有8g内存。对于60个文件,前3步工作正常,但在准备第二个文件时驱动程序内存不足。只有当我将驾驶员的记忆增加到20g时,情况才会有所改善。

问题

那是为什么呢?当计算第二个文件时,我不使用用于计算第一个文件的Dataframes,所以它们的数量和内容不应该真的很重要,如果第一个镶木地板文件的大小保持不变,应该吗?这60个数据帧会以某种方式缓存并占用驱动程序的内存吗?我自己不做任何缓存。我也从不收集任何东西。我不明白为什么8g的内存对火花驱动程序来说是不够的。


共2个答案

匿名用户

缓存或持久性是(迭代和交互式)Spark计算的优化技术。它们有助于保存中期部分结果,以便在后续阶段重用。因此,这些作为RDD的中期结果被保存在内存(默认)或更坚固的存储(如磁盘和/或复制)中。RDD可以使用缓存操作进行缓存。也可以使用持久化操作来持久化它们。缓存和持久化操作之间的区别纯粹是语法上的。缓存是持久化或持久化(MEMORY_ONLY)的同义词,即缓存仅仅是具有默认存储级别MEMORY_ONLY的持久化。

请参阅持久化和非持久化的使用

匿名用户

conf.set("spark.serializer", "org.apache.spark.serializer.KryoSerializer")
//you have to use serialization configuration if you are using MEMORY_AND_DISK_SER 


val rdd1 = sc.textFile("some data")
rdd1.persist(storageLevel.MEMORY_AND_DISK_SER)   // marks rdd as persist
val rdd2 = rdd1.filter(...)
val rdd3 = rdd1.map(...)

rdd2.persist(storageLevel.MEMORY_AND_DISK_SER)
rdd3.persist(storageLevel.MEMORY_AND_DISK_SER)

rdd2.saveAsTextFile("...")
rdd3.saveAsTextFile("...")

rdd1.unpersist()
rdd2.unpersist()
rdd3.unpersist()

要调优代码,请点击以下链接