RDD分區2GB限制


本文目的

 

最近使用spark處理較大的數據時,遇到了分區2G限制的問題(ken)。找到了解決方法,並且在網上收集了一些資料,記錄在這里,作為備忘。

 

問題現象

 

遇到這個問題時,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

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)

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]

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數量,也就是加大並發量,最終提高計算性能。

 

以上只是一些個能思考,如果不正確,還請拍磚。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM