【问题标题】:PySpark join shuffles co-partitioned RDDsPySpark join 对共同分区的 RDD 进行洗牌
【发布时间】:2016-11-28 01:53:18
【问题描述】:
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'], [], [], [], [], [], [], [], [], [], []]

即使我将新分区的数量设置为原来的 8 个,分区也会发生变化:

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

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

我使用的是 Spark 1.6.0。

【问题讨论】:

    标签: join apache-spark pyspark partitioning


    【解决方案1】:

    在这种情况下,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,不会阻止 shuffle。

    另见Default Partitioning Scheme in Spark

    【讨论】:

    • 谢谢,这可能只是解决我面临的问题。不过,我很惊讶numSlices 的设置并不意味着明确的分区。 (我想现在我明白为什么它不像其他函数那样被称为numPartitions。)
    • 当我们谈论 Spark 中的分区时,我们指的是两个不同的概念。您可以查看我对stackoverflow.com/q/34491219/1560062 的回答以获得一些解释。
    猜你喜欢
    • 2015-04-08
    • 2016-04-12
    • 2014-08-31
    • 1970-01-01
    • 1970-01-01
    • 2015-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多