我有一个内存不足的Spark应用程序,集群有两个节点,内存大约30G,输入数据大小只有几百GB。
该应用程序是一个Spark SQL作业,它从HDFS读取数据并创建表并对其进行缓存,然后执行一些Spark SQL查询并将结果写回HDFS。
最初我将数据拆分为64个分区,然后我得到了OOM,然后我就可以通过使用1024个分区来解决内存问题。但为什么使用更多分区帮我解决了OOM问题呢?
答案 0 :(得分:2)
Rockie的答案是正确的,但他不明白你的问题。
当您缓存RDD时,其所有分区都将保留(用storage level表示)-遵守 spark.memory.fraction 和 spark.memory.storageFraction 属性。
此外, Spark可以在某些时候自动删除某些内存分区(或者您可以使用RDD.unpersist()手动对整个RDD进行此操作),具体方法根据{{3} }。
因此,当您拥有更多分区时,Spark在LRU中存储的分区会更少,这样它们就不会引起OOM(这可能也会产生负面影响,例如需要重新缓存分区)。
另一个重要点是当您使用X分区将结果写回到HDFS时,您将对所有数据执行X任务-取所有数据大小并除以X,这就是内存对于每个任务,这些任务都在每个(虚拟)内核上执行。因此,不难发现X = 64导致OOM,而X = 1024不会。
答案 1 :(得分:1)
大数据的解决方案是分区(分而治之)。由于并非所有数据都可以放入内存中,因此也无法在一台机器上处理。
每个分区都可以适应内存并在相对较短的时间内处理(映射)。为每个分区处理数据后。它需要合并(减少)。这是传统map reduce
将数据拆分到更多分区意味着每个分区变小。
<强> [编辑] 强>
Spark使用名为Resilient Distributed DataSet(RDD)的革命概念。
我在Youtube Spark Makes Big Data Sparking上进行了一次小型截屏视频演示。
答案 2 :(得分:0)
Spark的操作员将数据溢出到磁盘中(如果内存不适合), 使其可以在任何大小的数据上正常运行。” 生成OOM的分区
分区确定并行度。 Apache Spark文档说,分区大小应至少等于集群中的核心数量。
缺少分区会导致
许多分区也可能产生负面影响
将数据存储在HDFS上,将根据HDFS配置将其分区为64 MB或128 MB块。当使用spark读取HDFS文件时,DataFrame分区的数量 df.rdd.getNumPartitions 取决于以下属性
链接:
在Spark峰会期间,Aaron Davidson提供了一些有关分区调整的技巧。他还定义了恢复到3点以下的合理数量的分区: