RDD和PipelinedRDD类型

时间:2020-06-08 01:29:48

标签: apache-spark pyspark

我对PySpark有点陌生(更多是对Spark-Scala的了解),最近我遇到了下面的观察。当我使用parallelize()方法创建RDD时,返回类型为 RDD 类型。但是,当我使用range()方法创建RDD时,其类型为 PipelinedRDD 。例如:

>>> listRDD =sc.parallelize([1,2,3,4,5,6,7])
>>> print(listRDD.collect())
[1, 2, 3, 4, 5, 6, 7]
>>> print(type(listRDD))
<class 'pyspark.rdd.RDD'>

>>> rangeRDD =sc.range(1,8)
>>> print(rangeRDD.collect())
[1, 2, 3, 4, 5, 6, 7]
>>> print(type(rangeRDD))
<class 'pyspark.rdd.PipelinedRDD'>

我检查了两个rdds的构造和发现方式:

1)内部都只使用parallize方法。

>>> rangeRDD.toDebugString()
b'(8) PythonRDD[25] at collect at <stdin>:1 []\n |  ParallelCollectionRDD[24] at parallelize at PythonRDD.scala:195 []'
>>> listRDD.toDebugString()
b'(8) PythonRDD[26] at RDD at PythonRDD.scala:53 []\n |  ParallelCollectionRDD[21] at parallelize at PythonRDD.scala:195 []'

2)PipeLineRDD是我理解的RDD类的子类。

但是,当它的类型为PipeLineedRDD以及它的类型为RDD时,是否有任何通用逻辑? 谢谢大家。

1 个答案:

答案 0 :(得分:1)

sc.range实际上是在内部调用parallelize方法-它是here定义的。您可以看到sc.range正在使用xrange作为输入来调用sc.parallelize。并且sc.parallelize在使用xrange输入类型进行调用时有一个单独的代码分支:它以空列表作为参数调用自身,然后应用mapPartitionsWithIndex here,这是{{1}的最终输出}和sc.parallelize依次呼叫。因此,您可以看到如何像使用sc.range一样创建第一个常规对象(尽管对象是一个空列表),但是最终输出是在其之上应用映射功能的结果。

看来,此行为的主要原因是避免具体化否则会发生的数据(如果未实现len,则将对其进行迭代并立即转换为列表)。