Spark 2.2中DataSet的可用内存。独立的

时间:2018-07-26 11:03:46

标签: scala apache-spark memory

我正在使用Spark 2.2/2.3中的Scala通过Spark SQL和Scala Dataset/Dataframe集合API(地图,过滤器等)来处理大量的CSV文件。

我目前发现我的开发笔记本电脑上的Spark大大超过了spark.executor.memory(8 GB)设置的内存限制。运行驱动程序/执行器的JVM的内存使用量最多可增加约16 GB的堆使用量(执行期间通过jvisualvm进行观察,请参见下图)。 linux htop的峰值显示为〜16.6 GB RES和21.8 GB VIRT内存使用。在生产系统上,使用相同的spark配置,该过程似乎可以获取更多的内存(据称约为33GB)。

在执行过程中,我使用Spark Web UI看了执行器内存的使用情况-我看到了12.2GB / 8.8GB执行器内存(在生产中,UI处于关闭状态)之类的东西。

我知道实际的执行者内存限制不仅取决于spark.executor.memory配置,还取决于一些其他的提琴手因素,这些因素解释了额外的0.8 GB的执行者内存。据我所知,该驱动程序还需要内存,默认情况下它需要约1GB的内存。

  • 然后,Spark UI如何显示12.2 GB的执行程序内存使用情况?
  • 为什么JVM的VIRT内存使用率如此之高?

memory footprint

但是,更重要的是,在执行驱动程序以释放未使用的数据集时我该怎么办?

示例:

  • 将文件fafb读取到数据集dsA, dsB中。
  • dsA, dsB => dsA1, dsB1进行一些过滤和映射。
  • 调用dsA1 & dsB1.persist(MEMORY_AND_DISK)以避免重新读取和重新处理。
  • 加入dsA1dsB1来创建dsAB2
  • dsAB2.persist(MEMORY_AND_DISK)
  • 仅继续使用dsAB2

=>假设:现在,我可以“删除” dsA, dsB, dsA1dsB1来释放它们使用的内存。

我打电话给

  • dsA1.unpersist(true); dsA1= null; dsA= null
  • dsB1.unpersist(true); dsB1= null; dsB= null

现在,垃圾收集器应该释放出数据集使用的部分GB数据。但是,即使在用System.getRuntime().gc()修饰GC之后,在用jvisualvm进行观察时,我也看不到JVM堆内存使用率没有明显变化。

是否有任何技巧可以真正丢弃未使用的数据集/数据帧?

0 个答案:

没有答案