我在群集上使用Spark,我正在与其他用户共享。因此,基于运行时间来判断我的哪个代码运行效率是不可靠的。因为当我运行更高效的代码时,其他人可能正在运行大量数据,并使我的代码执行的时间更长。
我可以在这里问两个问题:
我正在使用join
函数加入2 RDDs
,我在使用groupByKey()
之前尝试使用join
,如下所示:
rdd1.groupByKey().join(rdd2)
似乎需要更长的时间,但我记得当我使用Hadoop Hive时,该组使我的查询运行得更快。由于Spark正在使用延迟评估,我想知道groupByKey
join
是否会让事情变得更快
我注意到Spark有一个SQL模块,到目前为止我真的没有时间去尝试它,但是我可以问一下SQL模块和RDD SQL之间的区别是什么?
答案 0 :(得分:4)
我主要同意zero323的回答,但我认为 有理由期望join
在groupByKey
之后更快。 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
答案 1 :(得分:3)
groupByKey
后跟join
仅比join
更快,没有充分的理由。如果rdd1
和rdd2
没有分区符或分区符号不同,则限制因素只是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)
VS。仅join
:
rdd1.join(rdd2)
最后这两个计划甚至不等同,为了获得相同的结果,您必须在第一个计划中添加额外的flatMap
。
这是一个相当广泛的问题,但要强调主要区别:
PairwiseRDDs
是任意Tuple2
元素的同类集合。对于默认操作,您希望密钥以有意义的方式可以清除,否则对类型没有严格的要求。相比之下,DataFrames展示了更多动态类型,但每列只能包含来自supported set of defined types的值。可以定义UDT,但仍然必须使用基本的表达。
DataFrame使用Catalyst Optimizer生成逻辑和物理执行计划,可以生成高度优化的查询,而无需应用手动低级优化。基于RDD的操作仅遵循依赖性DAG。这意味着没有自定义优化会带来更差的性能,但可以更好地控制执行,并且可以进行精细分级调整。
其他一些要阅读的内容: