Spark RDD collect与collectPartitions

确切的应该说是RDD collect^_^

1.collect的作用    

    Spark内有collect方法,是Action操作里边的一个算子,这个方法可以将RDD类型的数据转化为数组,你可以随时val arr = data.collect(),将RDD类型数据转化为数组来存放并参与后续运算。

2.已知的弊端

    首先,从时间上来讲,前边已经说过了,collect是Action里边的,根据RDD的惰性机制,真正的计算发生在RDD的Action操作。那么,一次collect就会导致一次Shuffle,而一次Shuffle调度一次stage,然而一次stage包含很多个已分解的任务碎片Task。这么一来,会导致程序运行时间大大增加,属于比较耗时的操作,即使是在local模式下也同样耗时。

    其次,从环境上来讲,本机local模式下运行并无太大区别,可若放在分布式环境下运行,一次collect操作会将分布式各个节点上的数据汇聚到一个driver节点上,而这么一来,后续所执行的运算和操作就会脱离这个分布式环境而相当于单机环境下运行,这也与Spark的分布式理念不合。

    最后,将大量数据汇集到一个driver节点上,并且像这样val arr = data.collect(),将数据用数组存放,占用了jvm堆内存,可想而知,是有多么轻松就会内存溢出。

3.如何规避 

    若需要遍历RDD中元素,大可不必使用collect,可以使用foreach语句;

    若需要打印RDD中元素,可用take语句,data.take(1000).foreach(println),这点官方文档里有说明;

    若需要查看其中内容,可用saveAsTextFile方法。

扫描二维码关注公众号,回复: 2151423 查看本文章

总之,单机环境下使用collect问题并不大,但分布式环境下尽量规避,如有其他需要,手动编写代码实现相应功能就好。

补充:

    collectPartitions:同样属于Action的一种操作,同样也会将数据汇集到Driver节点上,与collect区别并不是很大,唯一的区别是:collectPartitions产生数据类型不同于collect,collect是将所有RDD汇集到一个数组里,而collectPartitions是将各个分区内所有元素存储到一个数组里,再将这些数组汇集到driver端产生一个数组;collect产生一维数组,而collectPartitions产生二维数组。

例:

   RDD类型data,数据类型为[labeledPoint],labeledPoint为(label,features)

   那么 val collectArr = data.collect();(collectArr内数组元素为labeledPoint[label,features]) 

   而val collectPArr= data.collectPartitions();(collectPArr内数组元素为Array[label,features],即为二维数组)

猜你喜欢

转载自blog.csdn.net/fortuna_i/article/details/80851775
今日推荐