spark RDD分区2GB限制(Size exceeds Integer.MAX_VALUE)

本文介绍了在使用Spark处理大数据文件时遇到的2GB限制问题及其解决办法。通过手动设置RDD分区数量为500,成功避免了因文件大小超过整型最大值导致的任务丢失警告。

最近使用spark处理较大的数据文件,遇到了分区2G限制的问题,spark日志会报如下的日志:
WARN scheduler.TaskSetManager: Lost task 19.0 in stage 6.0 (TID 120, 10.111.32.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)

解决方法:
手动设置RDD的分区数量。当前使用的Spark默认RDD分区是18个,后来手动设置为500个,上面这个问题就迎刃而解了。可以在RDD加载后,使用RDD.repartition(numPart:Int)函数重新设置分区数量。
val data_new = data.repartition(500)


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


### Apache Spark MLlib ALS 输入数据类型 在 Apache Spark 的 MLlib 库中,ALS(Alternating Least Squares)是一种常用的协同过滤算法,用于构建推荐系统。该算法的主要目的是通过对用户-物品交互矩阵进行低秩近似分解,从而预测未观测到的评分值[^1]。 对于 ALS 算法而言,其输入数据类型是一个由 `(user, product, rating)` 组成的三元组集合。MLlib 提供了一个专门的数据结构 `Rating` 来表示这种关系,其中每个 `Rating` 对象包含了三个字段:用户 ID (`user`)、物品 ID (`product`) 和对应的评分值 (`rating`)。因此,在 MLlib 中,ALS 的输入数据类型应为 `RDD[Rating]` 或者 DataFrame 表示的表格形式,包含相同的列名和含义[^4]。 以下是创建 `RDD[Rating]` 并将其传递给 ALS 训练方法的一个简单例子: ```scala import org.apache.spark.mllib.recommendation.{ALS, Rating} // 假设加载了原始数据文件,并映射为 RDD[Rating] val data = sc.textFile("path/to/ratings/file") val ratings = data.map { line => val fields = line.split(",") Rating(fields(0).toInt, fields(1).toInt, fields(2).toDouble) } // 使用 ALS 进行训练 val rank = 10 // 隐含特征数 val numIterations = 10 // 迭代次数 val model = ALS.train(ratings, rank, numIterations) ``` --- ### RDD 的默认存储级别 关于 RDD 的默认存储级别,默认情况下,当开发者调用诸如 `.cache()` 方法时,Spark 将会把 RDD 存储在一个内存优先的存储策略下,具体来说就是使用 `MEMORY_ONLY` 模式[^2]。这意味着如果足够的空间可用,则整个 RDD 数据会被序列化并保存至 JVM 堆上的内存区域;然而一旦内存不足,某些分区可能会被驱逐掉以便释放资源。 不过需要注意的是,尽管这是默认行为,但开发人员也可以显式指定其他更合适的持久化选项以满足不同的应用场景需求。例如可以通过如下方式改变默认设置: ```scala rdd.persist(org.apache.spark.storage.StorageLevel.MEMORY_AND_DISK) ``` 这里展示了如何将存储级别改为既尝试存入内存又允许溢写磁盘的方式。这样即使发生内存耗尽的情况,仍能保证所有数据不会丢失而只是速度变慢而已[^3]。 --- ####
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值