Scala 如何在加入Spark之前正确应用HashPartitioner?
为了减少两个RDD连接过程中的混乱,我决定首先使用HashPartitioner对它们进行分区。我是这样做的。我做得对吗,还是有更好的方法Scala 如何在加入Spark之前正确应用HashPartitioner?,scala,apache-spark,rdd,partitioner,Scala,Apache Spark,Rdd,Partitioner,为了减少两个RDD连接过程中的混乱,我决定首先使用HashPartitioner对它们进行分区。我是这样做的。我做得对吗,还是有更好的方法 val rddA = ... val rddB = ... val numOfPartitions = rddA.getNumPartitions val rddApartitioned = rddA.partitionBy(new HashPartitioner(numOfPartitions)) val rddBpartitioned = rddB.
val rddA = ...
val rddB = ...
val numOfPartitions = rddA.getNumPartitions
val rddApartitioned = rddA.partitionBy(new HashPartitioner(numOfPartitions))
val rddBpartitioned = rddB.partitionBy(new HashPartitioner(numOfPartitions))
val rddAB = rddApartitioned.join(rddBpartitioned)
为了减少两个RDD连接期间的混洗
令人惊讶的是,人们普遍存在一种误解,即重新分区可以减少甚至消除洗牌。没有。重新划分是以最纯粹的形式洗牌。它不会节省时间、带宽或内存
使用主动分区器背后的原理是不同的——它允许您洗牌一次,并重用状态,以执行多个按键操作,而无需额外洗牌(但据我所知,不一定无需额外的网络流量,不包括在单个操作中发生洗牌的情况)
因此,您的代码是正确的,但如果您一旦加入,它不会给您带来任何好处
为了减少两个RDD连接期间的混洗
令人惊讶的是,人们普遍存在一种误解,即重新分区可以减少甚至消除洗牌。没有。重新划分是以最纯粹的形式洗牌。它不会节省时间、带宽或内存
使用主动分区器背后的原理是不同的——它允许您洗牌一次,并重用状态,以执行多个按键操作,而无需额外洗牌(但据我所知,不一定无需额外的网络流量,不包括在单个操作中发生洗牌的情况)
因此,您的代码是正确的,但如果您一旦加入,它就不会给您带来任何好处。只有一条注释,最好在
.persist()
之后附加.partitionBy
,否则,所有操作都将评估rddApartitioned
和rddBpartitioned
的整个沿袭,这将导致哈希分区一次又一次地发生
val rddApartitioned = rddA.partitionBy(new HashPartitioner(numOfPartitions)).persist()
val rddBpartitioned = rddB.partitionBy(new HashPartitioner(numOfPartitions)).persist()
如果有多个操作用于
rddApartitioned
和rddBpartitioned
,则最好在.partitionBy
之后附加.persist()
,否则,所有操作将评估rddApartitioned
和rddBpartitioned
的整个沿袭,这将导致哈希分区一次又一次地发生
val rddApartitioned = rddA.partitionBy(new HashPartitioner(numOfPartitions)).persist()
val rddBpartitioned = rddB.partitionBy(new HashPartitioner(numOfPartitions)).persist()
很好的观察:)在我的例子中,我后来也做了一个sortByKey,所以我猜它是有帮助的。如果
sortByKey
应用于rddAB
,那么它就没有任何区别了。如果它应用于rddApartitioned
/rddBpartitioned
,那么它可以提供一些好处。@user10938362它是否要求两个RDD都是分区的?如果我只为rddA
使用partitionBy
而不是rddB
,会发生什么?很好的观察:)在我的情况下,我后来也做了一个sortByKey,所以我猜它会有帮助。如果sortByKey
应用于rddAB
,那么它就没有任何区别。如果它应用于rddApartitioned
/rddBpartitioned
,那么它可以提供一些好处。@user10938362它是否要求两个RDD都是分区的?如果我只为rddA
使用partitionBy
,而不是rddB
,会发生什么情况?