RDD分区2GB限制

本文目的 java

 

最近使用spark处理较大的数据时,遇到了分区2G限制的问题(ken)。找到了解决方法,而且在网上收集了一些资料,记录在这里,做为备忘。 apache

 

问题现象 并发

 

遇到这个问题时,spark日志会报以下的日志, 框架

片断1 函数

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)
性能

 

片断2 spa

15/04/16 14:19:45 INFO scheduler.TaskSetManager: Starting task 20.2 in stage 6.0 (TID 146, 10.196.151.213, PROCESS_LOCAL, 1666 bytes) .net

15/04/16 14:19:45 INFO scheduler.TaskSetManager: Lost task 20.2 in stage 6.0 (TID 146) on executor 10.196.151.213: java.lang.IllegalArgumentException (Size exceeds Integer.MAX_VALUE) [duplicate 1] scala

15/04/16 14:19:45 INFO scheduler.TaskSetManager: Starting task 20.3 in stage 6.0 (TID 147, 10.196.151.213, PROCESS_LOCAL, 1666 bytes) 日志

15/04/16 14:19:45 INFO scheduler.TaskSetManager: Lost task 20.3 in stage 6.0 (TID 147) on executor 10.196.151.213: java.lang.IllegalArgumentException (Size exceeds Integer.MAX_VALUE) [duplicate 2]

15/04/16 14:19:45 ERROR scheduler.TaskSetManager: Task 20 in stage 6.0 failed 4 times; aborting job

15/04/16 14:19:45 INFO cluster.YarnClusterScheduler: Cancelling stage 6

15/04/16 14:19:45 INFO cluster.YarnClusterScheduler: Stage 6 was cancelled

15/04/16 14:19:45 INFO scheduler.DAGScheduler: Job 6 failed: collectAsMap at DecisionTree.scala:653, took 239.760845 s

15/04/16 14:19:45 ERROR yarn.ApplicationMaster: User class threw exception: Job aborted due to stage failure: Task 20 in stage 6.0 failed 4 times, most recent failure: Lost task 20.3 in stage 6.0 (TID 147, 10.196.151.213): java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE

at sun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:828)

 

注意红色高亮部分,异常就是某个partition的数据量超过了Integer.MAX_VALUE(2147483647 = 2GB)。

 

解决方法

 

手动设置RDD的分区数量。当前使用的Spark默认RDD分区是18个,后来手动设置为1000个,上面这个问题就迎刃而解了。能够在RDD加载后,使用RDD.repartition(numPart:Int)函数从新设置分区数量。

 

为何2G限制

 

目前spark社区对这个限制有不少讨(tu)论(cao),spark官方团队已经注意到了这个问题,可是直到1.2版本,这个问题仍是没有解决。由于牵涉到整个RDD的实现框架,因此改进成本至关大!

 

下面是一些相关的资料,有兴趣的读者能够进一步的阅读:

 

我的思(yu)考(jian)

 

这个限制有必定合理性。由于RDD中partition的操做是并发执行的,若是partition量过少,致使并发数过少,会限制计算效率。因此,基于这个限制,spark应用程序开发者会主动扩大partition数量,也就是加大并发量,最终提升计算性能。

 

以上只是一些个能思考,若是不正确,还请拍砖。

相关文章
相关标签/搜索