使用mllib RandomForest来训练数据时,我收到错误.由于我的数据集是巨大的,默认分区是相对较小的.所以抛出一个异常,表示“Size over Integer.MAX_VALUE”,orignal stack trace如下,
15/04/16 14:13:03 WARN scheduler.TaskSetManager: Lost task 19.0 in
stage 6.0 (TID 120,10.215.149.47):
java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE
at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:828) at
org.apache.spark.storage.DiskStore.getBytes(DiskStore.scala:123) at
org.apache.spark.storage.DiskStore.getBytes(DiskStore.scala:132) at
org.apache.spark.storage.BlockManager.doGetLocal(BlockManager.scala:517)
at
org.apache.spark.storage.BlockManager.getLocal(BlockManager.scala:432)
at org.apache.spark.storage.BlockManager.get(BlockManager.scala:618)
at
org.apache.spark.CacheManager.putInBlockManager(CacheManager.scala:146)
at org.apache.spark.CacheManager.getOrCompute(CacheManager.scala:70)
Integer.MAX_SIZE是2GB,似乎有一些分区内存不足.所以我把我的rdd分区重新分配到1000,这样每个分区可以像以前一样容纳更少的数据.最后,问题解决了!!!
所以我的问题是:
为什么分区大小有2G限制?似乎在火花中没有配置限制的限制
Spark中的块的基本抽象是一个ByteBuffer,不幸的是有一个Integer.MAX_VALUE(?2GB)的限制.
这是一个critical issue,防止使用非常大的数据集的火花.
增加分区数量可以解决它(如OP的情况),但并不总是可行的,例如当存在大的转换链时,其中的一部分可以增加数据(flatMap等)或数据偏移的情况.
所提出的解决方案是提出像LargeByteBuffer这样的抽象,它可以支持一个块的字节缓冲区列表.这会影响整体的火花结构,所以一直没有得到解决.