Spark的RDD(弹性分布式数据集)返回大结果集

34 篇文章 2 订阅
14 篇文章 1 订阅

(一)过大的结果集导致Driver端OOM错误

很早之前🔗《从零开始学习大数据平台》就提到了这个问题。
通过collect()返回结果集,数据量太大就会报driver端内存错误。
比如我这里,返回千万数据,就导致Out of memory,或者GC overhead limit exceeded

Spark的核心弹性分布式数据集,对于rdd.collect()是这么描述的:

java.util.List collect() //Python版本差不多的
返回一个数组包含RDD中所有的元素
.
备注
.
这个方法只能在结果集较小的情况下使用,因为所有的数据都会加载到driver的内存中。

(二)各种解决方案

如果结果集大怎能办?
网上查了一圈,大家的说法有:

  1. 大的数据集用rdd写入HDFS文件的方法,比如rdd.saveAsTextFilerdd.saveAsNewAPIHadoopFile各个节点将结果写入到HDFS的目录中(一大堆文件)。
  2. 不传到driver上而是rdd.foreachrdd.foreachPartition打印到屏幕上。
  3. 通过可序列化的类型,发送到数据库等等。

(三)分批返回结果集

不过我比较懒,希望整个流程和以前无缝切换,
所以我采用了collectPartitions分批返回数据。

Java代码如下:

...
        if (ColBatch < out_2.getNumPartitions()) {//如果设置了批量值,并小于分区数,则分批collect
            int[] Par = new int[ColBatch];
            for (int i = 0; i < out_2.getNumPartitions(); i += Par.length) {
                int ParLen = 0;
                for (int j = 0; j < Par.length; j++) {
                    if (i + j < out_2.getNumPartitions()) {
                        Par[j] = i + j;
                        ParLen++;
                    }
                }
                TmpLine = String.format("当前: %d - %d\n", i, i + ParLen - 1);
                System.out.print(TmpLine);
                List<Tuple2<String, String>>[] output2 = out_2.collectPartitions(Par);
                for (int j = 0; j < ParLen; j++) {
                    for (Tuple2<String, String> tuple : output2[j]) {
                        oF002.write(String.format("%s|%s\n", tuple._1(), tuple._2()));
                        g002++;
                    }
                }
            }
        } else {
            List<Tuple2<String, String>> output1 = out_2.collect();
            for (Tuple2<String, String> tuple : output1) {
                oF002.write(String.format("%s|%s\n", tuple._1(), tuple._2()));
                g002++;
            }
        }
...

PS:但Python中没有找到collectPartitions方法啊???肿么办!!! 💔 😫。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值