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

Spark Using Disk Resources When Memory is Available

我正在努力优化我的 Spark 集群(运行 on AWS EMR)的性能,该集群使用 ALS 矩阵分解算法执行协同过滤。我们正在使用相当多的因素和迭代,所以我正在尝试特别优化这些步骤。我试图理解为什么当我有足够的可用内存时我使用 disk space 。这是可用的总集群内存:

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

我试过查看 Yarn 管理器,它似乎显示每个节点从属有:110 GB(已用)4 GB(可用)。您还可以看到第一个图像 (700 GB) 上分配的总数。我也试过更改 ALS 源并强制 intermediateRDDStorageLevelfinalRDDStorageLevel 从 MEMORY_AND_DISK 到 MEMORY_ONLY 并且没有影响任何东西。

我没有在我的代码中的任何其他地方保留我的 RDD,所以我不确定这个磁盘利用率是从哪里来的。我想更好地利用集群上的资源,有什么想法吗?如何更有效地使用可用内存?

很少有 spark 使用磁盘而不是内存的场景

  1. 如果你有随机播放操作。 Spark 只将打乱后的数据写入磁盘,所以如果你有打乱操作,那你就不走运了

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

  3. 如果你没有 shuffle 操作,你不妨调整一下 spark.memory.fraction 如果你使用的是 spark 2.2

来自documentation

spark.memory.fraction (doc) 将 M 的大小表示为 (JVM 堆 space - 300MB) 的一部分(默认为 0.6)。其余的 space (40%) 保留给用户数据结构,Spark内部元数据,稀疏异常情况下的OOM错误防护 大记录。

因此您可以将 spark.memory.fraction 设为 .9 并查看行为。

  1. 最后,除了 MEMORY_ONLY 之外,还有一些选项作为存储级别,例如 MEMORY_ONLY_SER,它将序列化数据并存储在内存中。此选项减少了内存使用量,因为序列化对象的大小远小于实际对象的大小。如果您看到大量溢出,您可以选择此存储级别。