Spark RDD groupByKey + join vs join performance

时间:2015-10-24 21:13:30

标签: apache-spark pyspark rdd pyspark-sql

我在群集上使用Spark,我正在与其他用户共享。因此,基于运行时间来判断我的哪个代码运行效率是不可靠的。因为当我运行更高效的代码时,其他人可能正在运行大量数据,并使我的代码执行的时间更长。

我可以在这里问两个问题:

  1. 我正在使用join函数加入2 RDDs,我在使用groupByKey()之前尝试使用join,如下所示:

    rdd1.groupByKey().join(rdd2)
    

    似乎需要更长的时间,但我记得当我使用Hadoop Hive时,该组使我的查询运行得更快。由于Spark正在使用延迟评估,我想知道groupByKey join是否会让事情变得更快

  2. 我注意到Spark有一个SQL模块,到目前为止我真的没有时间去尝试它,但是我可以问一下SQL模块和RDD SQL之间的区别是什么?

2 个答案:

答案 0 :(得分:4)

我主要同意zero323的回答,但我认为 有理由期​​望joingroupByKey之后更快。 groupByKey减少了数据量并通过密钥对数据进行分区。这两项都有助于后续join的表现。

我认为前者(数据量减少)并不重要。要获得后者(分区)的好处,您需要以相同的方式对其他RDD进行分区。

例如:

val a = sc.parallelize((1 to 10).map(_ -> 100)).groupByKey()
val b = sc.parallelize((1 to 10).map(_ -> 100)).partitionBy(a.partitioner.get)
a.join(b).collect

DAG visualization

答案 1 :(得分:3)

  1. groupByKey后跟join仅比join更快,没有充分的理由。如果rdd1rdd2没有分区符或分区符号不同,则限制因素只是HashPartitioning所需的随机播放。

    通过使用groupByKey,您不仅可以通过保留分组所需的可变缓冲区来增加总成本,而且更重要的是使用额外的转换会导致更复杂的DAG。 groupByKey + join

    rdd1 = sc.parallelize([("a", 1), ("a", 3), ("b", 2)])
    rdd2 = sc.parallelize([("a", 5), ("c", 6), ("b", 7)])
    rdd1.groupByKey().join(rdd2)
    

    enter image description here

    VS。仅join

    rdd1.join(rdd2)
    

    enter image description here

    最后这两个计划甚至不等同,为了获得相同的结果,您必须在第一个计划中添加额外的flatMap

  2. 这是一个相当广泛的问题,但要强调主要区别:

    • PairwiseRDDs是任意Tuple2元素的同类集合。对于默认操作,您希望密钥以有意义的方式可以清除,否则对类型没有严格的要求。相比之下,DataFrames展示了更多动态类型,但每列只能包含来自supported set of defined types的值。可以定义UDT,但仍然必须使用基本的表达。

    • DataFrame使用Catalyst Optimizer生成逻辑和物理执行计划,可以生成高度优化的查询,而无需应用手动低级优化。基于RDD的操作仅遵循依赖性DAG。这意味着没有自定义优化会带来更差的性能,但可以更好地控制执行,并且可以进行精细分级调整。

  3. 其他一些要阅读的内容: