Hy,我对Spark中的分区有疑问,在 Learning Spark 一书中,作者说分区可能很有用,例如在第66页的 PageRank 期间他们写道:
因为链接是静态数据集,所以我们在开始时对它进行分区 partitionBy(),因此不需要在整个过程中进行混洗 网络
现在我专注于这个例子,但我的问题很普遍:
提前致谢
答案 0 :(得分:2)
为什么分区的RDD不需要改组?
当作者做的时候:
val links = sc.objectFile[(String, Seq[String])]("links")
.partitionBy(new HashPartitioner(100))
.persist()
他将数据集划分为100个分区,其中每个密钥将被散列到给定的分区(给定示例中为pageId
)。这意味着相同的密钥将存储在单个给定分区中。然后,当他执行join
:
val contributions = links.join(ranks)
具有相同pageId
的所有数据块应该已经位于同一个执行器上,从而无需在群集中的不同节点之间进行随机播放。
PartitionBy()是一个广泛的转换,所以它会产生shuffle 无论如何,对吧?
是的,partitionBy
会产生ShuffleRDD[K, V, V]
:
def partitionBy(partitioner: Partitioner): RDD[(K, V)] = self.withScope {
if (keyClass.isArray && partitioner.isInstanceOf[HashPartitioner]) {
throw new SparkException("HashPartitioner cannot partition array keys.")
}
if (self.partitioner == Some(partitioner)) {
self
} else {
new ShuffledRDD[K, V, V](self, partitioner)
}
}
有人可以说明一个具体的例子以及每个例子 partitionBy发生时的单个节点?
基本上,partitionBy
将执行以下操作:
它将对密钥模块进行哈希分区数量(在这种情况下为100),并且因为它依赖于相同密钥将始终产生相同哈希码的事实,它将打包来自给定id的所有数据(在我们的case,pageId
)到同一个分区,这样当你join
时,所有数据都已经在该分区中可用,避免了需要随机播放。