[英]Does spark's distinct() function shuffle only the distinct tuples from each partition
据我所知,distinct()散列分区RDD以识别唯一键。 但它是否优化了每个分区只移动不同的元组?
想象一下具有以下分区的RDD
在这个RDD的一个独特的地方,所有重复的密钥(分区1中的2s和分区2中的5s)是否会被混洗到它们的目标分区,或者只有每个分区的不同密钥被洗牌到目标?
如果所有键都被洗牌,那么带有set()操作的aggregate()将减少shuffle。
def set_update(u, v):
u.add(v)
return u
rdd.aggregate(set(), set_update, lambda u1,u2: u1|u2)
unique
是通过(element, None)
对上的reduceByKey
实现的。 因此,它每个分区只会刷新唯一值。 如果重复数量很少,那么仍然是相当昂贵的操作。
有些情况下使用set
可能很有用。 特别是如果你在PairwseRDD
上调用distinct
,你可能更喜欢使用aggregateByKey
/ combineByKey
来同时实现重复数据删除和按键分区。 特别考虑以下代码:
rdd1 = sc.parallelize([("foo", 1), ("foo", 1), ("bar", 1)])
rdd2 = sc.parallelize([("foo", "x"), ("bar", "y")])
rdd1.distinct().join(rdd2)
它有洗牌rdd1
两次-一次distinct
了,一旦join
。 相反,您可以使用combineByKey
:
def flatten(kvs):
(key, (left, right)) = kvs
for v in left:
yield (key, (v, right))
aggregated = (rdd1
.aggregateByKey(set(), set_update, lambda u1, u2: u1 | u2))
rdd2_partitioned = rdd2.partitionBy(aggregated.getNumPartitions())
(aggregated.join(rdd2_partitioned)
.flatMap(flatten))
注意 :
join
逻辑在Scala中有点不同于Python(PySpark使用union
后跟groupByKey
,请参阅Spark RDD groupByKey +连接vs连接性能,用于Python和Scala DAG),因此我们必须在调用join之前手动分区第二个RDD
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.