PySpark加入混洗共同分区的RDD

时间:2016-07-24 18:52:33

标签: join apache-spark pyspark partitioning

from pyspark import SparkContext

sc = SparkContext()

rdd1 = sc.parallelize([('a', 1), ('b', 2), ('c', 3), ('d', 4)], numSlices=8)
rdd2 = rdd1.mapValues(lambda x: x)

这些RDD具有相同的分区:

rdd1.keys().glom().collect()
>>> [[], ['a'], [], ['b'], [], ['c'], [], ['d']]

rdd2.keys().glom().collect()
>>> [[], ['a'], [], ['b'], [], ['c'], [], ['d']]

这里有多个答案表明加入共分区数据不会导致混乱,这对我来说很有意义。示例:Does a join of co-partitioned RDDs cause a shuffle in Apache Spark?

然而,当我使用PySpark加入这些共同分区的RDD时,数据被混洗到一个新的分区中:

rdd1.join(rdd2).keys().glom().collect()
>>> [['a'], [], ['c'], ['b'], [], ['d'], [], [], [], [], [], [], [], [], [], []]

即使我将新分区的数量设置为原始分区,分区也会更改:

rdd1.join(rdd2, numPartitions=8).keys().glom().collect()
>>> [['a'], [], ['c'], ['b'], [], ['d'], [], []]

为什么我不能避免使用这些共同分区的RDD进行洗牌?

我正在使用Spark 1.6.0。

1 个答案:

答案 0 :(得分:6)

在这种情况下,rdd1rdd2都没有分区

rdd1 = sc.parallelize([('a', 1), ('b', 2), ('c', 3), ('d', 4)])
rdd2 = rdd1.mapValues(lambda x: x)

rdd1.partitioner is None
## True

rdd2.partitioner is None
# True

因此根据定义,没有共同分区。虽然您可以对数据进行分区并加入:

n = rdd1.getNumPartitions()
rdd1part = rdd1.partitionBy(n)
rdd2part = rdd2.partitionBy(n)

rdd1part.join(rdd2part)  # rdd1part and rdd2part are co-partitioned

这只会重新安排DAG并且不会阻止随机播放。

另见Default Partitioning Scheme in Spark