Apache Spark处于“加载”状态

时间:2015-03-11 12:37:21

标签: scala apache-spark

这是我从Spark shell运行的工作:

  val l = sc.parallelize((1 to 5000000).toList)  
  val m = l.map(m => m*23)                    
  m.take(5000000)  

工人似乎是"加载"州:

enter image description here

什么是"加载"国家?

更新:

据我所知take将在群集上执行作业,然后将结果返回给Driver。所以"加载" state等于加载到驱动程序的数据?

1 个答案:

答案 0 :(得分:2)

我相信如果你这样做,

(1 to 5000000 ).toList

您一定会遇到java.lang.OutOfMemoryError: GC overhead limit exceeded

当JVM意识到它在Grabage Collection中花费了太多时间时会发生这种情况。默认情况下,如果您在more than 98% of the total time中花费GC并在GC的{​​{1}} less than 2%恢复后,JVM配置为抛出此错误。

在这种特殊情况下,您为每次迭代创建heap new instanceList,因此每次返回immutability new instance时都是如此。这意味着每次迭代都会留下无用的List实例,对于大小为数百万的List,会占用大量内存并频繁触发List。此外,每次GC都必须释放大量内存,因此需要花费大量时间。

这最终导致错误 - GC

如果不存在会怎么样? - >这意味着能够清洁的少量GC将再次快速填充,从而迫使GC再次重新启动清洁过程。这形成了一个恶性循环,其中CPU 100%忙于GC并且无法进行实际工作。应用程序将面临极端减速 - 过去以毫秒为单位完成的操作现在可能需要几分钟才能完成。

这是JVM中实施的先发制人的快速安全保护措施。

您可以使用以下Java选项禁用此安全措施。

java.lang.OutOfMemoryError: GC overhead limit exceeded

但我强烈建议 NOT 这样做。

即使您禁用此功能(或者如果您的Spark-Cluster通过分配大堆空间来避免此-XX:-UseGCOverheadLimit ),也可以使用

to some extent

需要很长时间。

此外,我强烈认为应该运行多个作业的(1 to 5000000 ).toList 等系统(默认情况下,您可以覆盖)配置为Sparkpause这些工作一旦他们意识到可能导致其他工作饥饿的极端GC。这可能是你的工作总是加载的主要原因。

使用reject并使用for循环向其附加值可以大大减轻您的负担。现在,您可以并行化可变列表。

mutable List

但是,每当val mutableList = scala.collection.mutable.MutableList.empty[ Int ] for ( i <- 1 to 5000000 ) { mutableList.append( i ) } val l = sc.parallelize( mutableList ) List时,即使这会导致多次(但严重程度不那么严重)的记忆分配(因此也会产生GC排除),这会导致half-full整个memory relocation 1}}以前分配的内存的两倍。