问题 为什么Spark RDD分区对HDFS有2GB的限制?


使用mllib RandomForest训练数据时出错。由于我的数据集很大,默认分区相对较小。所以抛出异常表示“Size超过Integer.MAX_VALUE”,原始堆栈跟踪如下,

15/04/16 14:13:03 WARN scheduler.TaskSetManager:失去的任务19.0 in   第6.0阶段(TID 120,10.215.149.47):   java.lang.IllegalArgumentException:大小超过Integer.MAX_VALUE
  在sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:828)at   org.apache.spark.storage.DiskStore.getBytes(DiskStore.scala:123)at at   org.apache.spark.storage.DiskStore.getBytes(DiskStore.scala:132)at at   org.apache.spark.storage.BlockManager.doGetLocal(BlockManager.scala:517)   在   org.apache.spark.storage.BlockManager.getLocal(BlockManager.scala:432)   在org.apache.spark.storage.BlockManager.get(BlockManager.scala:618)   在   org.apache.spark.CacheManager.putInBlockManager(CacheManager.scala:146)   在org.apache.spark.CacheManager.getOrCompute(CacheManager.scala:70)

Integer.MAX_SIZE是2GB,似乎有些分区内存不足。所以我将我的rdd分区重新分配到1000,这样每个分区可以保存比以前少得多的数据。最后,问题解决了!

所以,我的问题是: 为什么分区大小有2G限制?似乎没有为spark中的限制设置配置


6939
2018-04-17 03:28


起源

stackoverflow.com/questions/8076472/... - experquisite


答案:


spark中块的基本抽象是a ByteBuffer,不幸的是有一个Integer.MAX_VALUE(~2GB)的限制。

它是一个 关键问题 这可以防止在非常大的数据集中使用spark。 增加分区的数量可以解决它(如在OP的情况下),但并不总是可行的,例如当存在大的转换链时,其中一部分可以增加数据(flatMap等)或者在数据倾斜的情况下。

提出的解决方案是提出一个类似的抽象 LargeByteBuffer 它可以支持块的字节缓冲区列表。这会影响整体火花结构,因此它在相当长的一段时间内仍未得到解决。


10
2018-04-17 04:40



也可以看看 issues.apache.org/jira/browse/SPARK-5928 - Glenn Strycker
这个问题是否有任何已知的良好解决方法?增加分区数量还是减少?将RDD拆分成部分,运行命令,然后联合?关掉Kryo?使用数据帧?我试图通过键简单地(重新)分区一个适度大小(84GB)和低偏斜(AFAIK)的RDD,遇到2GB的错误。每个执行程序,每个主节点,每个Java等都有我的内存请求,所有这些内容都会被启动,我正在尝试将这个RDD划分为6800个分区。这太多了,实际上导致了我的问题吗? - Glenn Strycker
看到 issues.apache.org/jira/browse/SPARK-6235 在2016年9月似乎是一个修复。 - pd40
@ pd40,现在是官方发布的修复程序吗? - James Gan
截至今天,我认为它只是部分修复 - pd40