内存可用时使用磁盘资源的Spark

时间:2017-09-27 19:11:45

标签: amazon-web-services apache-spark yarn apache-spark-mllib emr

我正在努力优化使用ALS矩阵分解算法执行Collaborative Filtering的Spark集群(在AWS EMR上运行)的性能。我们正在使用相当多的因素和迭代,所以我试图特别优化这些步骤。当我有足够的内存时,我试图理解为什么我使用磁盘空间。以下是可用的总集群内存:

enter image description here

这是剩余的磁盘空间(注意磁盘利用率的下降):

enter image description here

我已经尝试过查看Yarn管理器,看起来它显示每个节点slave都有:110 GB(used)4 GB(avail。)。您还可以在第一张图像(700 GB)上看到分配的总数。我还尝试更改ALS源并强制将intermediateRDDStorageLevelfinalRDDStorageLevel从MEMORY_AND_DISK强制转换为MEMORY_ONLY,这不会影响任何内容。

我没有在我的代码中的任何其他位置保留我的RDD,所以我不确定这个磁盘利用率来自何处。我想更好地利用我的集群上的资源,任何想法?如何更有效地使用可用内存?

1 个答案:

答案 0 :(得分:3)

可能很少有一些场景,其中spark将使用磁盘使用而不是内存

  1. 如果你有洗牌操作。 Spark只会将洗牌后的数据写入磁盘,因此如果您进行了随机播放操作,那么运气不佳

  2. 低执行程序内存。如果执行程序内存较少,则内存较少,因此保留数据的内存较少,因此会将数据从内存溢出到磁盘。但是正如您所建议的那样,您已经尝试过从20G到40G的执行程序内存。我建议将执行程序内存保留到40G,因为JVM GC可能会使您的进程变慢。

  3. 如果您没有随机播放操作,如果使用spark 2.2,也可以调整spark.memory.fraction

  4. 来自documentation

    spark.memory.fraction将M的大小表示为(JVM堆空间 - 300MB)的一小部分(默认值为0.6)。剩下的空间(25%) 保留用户数据结构,Spark中的内部元数据,以及在稀疏和异常情况下防止OOM错误 大记录。

    所以你可以将spark.memory.fraction设为.9并查看行为。

    1. 最后除MEMORY_ONLY之外还有其他选项作为MEMORY_ONLY_SER等存储级别,它将序列化数据并存储在内存中。此选项减少了内存使用量,因为序列化对象大小远小于实际对象大小。如果您发现大量泄漏,可以选择此存储级别。