RDD分区2GB限制

spark处理较大的数据时,遇到了分区2G限制的问题。

问题来源:

500G原数据存储在HBase上,Spark从HBase读取数据这些数据进行处理,任务资源分配如下:
--executor-memory 12G \
--executor-cores 6 \
--conf spark.yarn.driver.memoryOverhead=2048 \
--conf spark.yarn.executor.memoryOverhead=4096 \
--conf spark.shuffle.service.enabled=true \
--conf spark.dynamicAllocation.enabled=true \
--conf spark.dynamicAllocation.executorIdleTimeout=60s \
--conf spark.dynamicAllocation.initialExecutors=2 \
--conf spark.dynamicAllocation.maxExecutors=10 \
--conf spark.dynamicAllocation.minExecutors=0 \
--conf spark.memory.userLegacyMode=false \
--conf spark.memory.fraction=0.75 \
--conf spark.memory.storageFraction=0.5 

Spark抛出的日志片段:

Caused by:java.lang.IllegalArgumentException: Size exceeds Integer.MAX_VALUE
         atsun.nio.ch.FileChannelImpl.map(FileChannelImpl.java:828)
         atorg.apache.spark.storage.DiskStore$$anonfun$getBytes$2.apply(DiskStore.scala:127)
         atorg.apache.spark.storage.DiskStore$$anonfun$getBytes$2.apply(DiskStore.scala:115)
         atorg.apache.spark.util.Utils$.tryWithSafeFinally(Utils.scala:1240)
         atorg.apache.spark.storage.DiskStore.getBytes(DiskStore.scala:129)
         atorg.apache.spark.storage.DiskStore.getBytes(DiskStore.scala:136)
         atorg.apache.spark.storage.BlockManager.doGetLocal(BlockManager.scala:515)
         atorg.apache.spark.storage.BlockManager.getLocal(BlockManager.scala:430)
         atorg.apache.spark.storage.BlockManager.get(BlockManager.scala:669)
         atorg.apache.spark.CacheManager.getOrCompute(CacheManager.scala:44)
         atorg.apache.spark.rdd.RDD.iterator(RDD.scala:268)
         atorg.apache.spark.scheduler.ResultTask.runTask(ResultTask.scala:66)
         atorg.apache.spark.scheduler.Task.run(Task.scala:89)
         atorg.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:242)
         atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
         atjava.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
         atjava.lang.Thread.run(Thread.java:745)

Spark任务遇到上面的异常后就立即退出了。

解决方法

设置RDD的分区数。当前Spark任务的分区数量为60个,通过repartition设置分区数为500。任务可以执行,没有再出现上面的异常。

为什么会有2G的限制?

这个没有找到明确的说明,我个人理解是单个partition的数据里太大会导致数据处理缓慢,没有意义的。至于为什么是2G,可以参考相关的资料做进一步了解:

Address various 2G limits

create LargeByteBuffer abstraction for eliminating 2GB limit on blocks

Remote Shuffle Blocks cannot be more than 2 GB









处理亿级文本文件可能需要更大的内存来处理,16GB内存可能会有一些限制。具体取决于您的数据大小、处理任务的复杂性以及集群的配置。 在PySpark中,数据会被分布式处理,因此Spark可以在集群上并行处理数据。然而,内存仍然是一个关键因素,特别是在进行转换和聚合等操作时。 如果您的数据量非常大,可能需要使用更大的内存来容纳数据和执行计算。这有助于避免内存不足的问题,并提高处理性能。一般来说,拥有至少几十GB内存的机器或者使用集群来处理大规模数据是更好的选择。 如果您只有16GB内存的机器,可以尝试以下方法来优化处理: 1. 增加分区:通过增加数据分区的数量,可以将负载均衡在更多的节点上,减少每个节点上的内存使用量。 2. 使用适当的内存管理策略:在PySpark中,可以使用`cache()`或`persist()`方法将数据缓存在内存中,以便重复使用。同时,可以使用`unpersist()`方法手动释放缓存的数据。 3. 使用合适的数据结构:对于大型数据集,尽量使用适合内存管理的数据结构,如DataFrame或DataSet,而不是RDD。 4. 使用过滤和投影操作来减少数据量:在处理数据时,可以使用过滤操作筛选出需要的数据,并使用投影操作选择需要的列,以减少内存使用量。 5. 考虑增加机器数量或使用集群:如果可能,可以考虑在集群上进行处理,利用多台机器的资源来处理大规模数据。 总的来说,16GB内存对于处理亿级文本文件可能有些不足,但您仍然可以尝试优化处理和使用合适的技术来处理数据。具体情况还需要根据您的数据和任务需求进行评估。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值