Apache spark Spark中分割器的使用
Hy,我对Spark中的分区有一个问题,在《学习Spark》一书中,作者说分区很有用,比如在第66页的PageRank中,他们写道: 因为links是一个静态数据集,所以我们从 partitionBy(),这样就不需要在 网络 现在我主要关注这个例子,但我的问题是一般性的:Apache spark Spark中分割器的使用,apache-spark,transformation,rdd,partitioning,shuffle,Apache Spark,Transformation,Rdd,Partitioning,Shuffle,Hy,我对Spark中的分区有一个问题,在《学习Spark》一书中,作者说分区很有用,比如在第66页的PageRank中,他们写道: 因为links是一个静态数据集,所以我们从 partitionBy(),这样就不需要在 网络 现在我主要关注这个例子,但我的问题是一般性的: 为什么分区RDD不需要洗牌? PartitionBy()是一个范围很广的转换,所以它无论如何都会产生shuffle,对吗? 有人能举例说明一个具体的例子,以及在发生分区时每个节点会发生什么情况吗? 提前谢谢 为什么分区RDD
val links = sc.objectFile[(String, Seq[String])]("links")
.partitionBy(new HashPartitioner(100))
.persist()
他将数据集划分为100个分区,其中每个键将散列到一个给定的分区(pageId
,在给定的示例中)。这意味着相同的密钥将存储在单个给定分区中。然后,当他加入时:
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
将执行以下操作:
它将按分区数(本例中为100)对键进行散列,并且由于它依赖于同一个键将始终生成相同的散列码这一事实,因此它将把给定id(在本例中为pageId
)中的所有数据打包到同一个分区,这样当您加入时,该分区中的所有数据都已可用,无需洗牌。非常感谢您的回答@Yuval。但如果要在加入过程中避免洗牌,我们需要在开始时进行洗牌,这有什么好处?也许只是在多次使用分区RDD时?或者什么?@Giorgio如果我们没有过早地对RDD进行分区并将其持久化,那么它的每次迭代都会导致一次洗牌。我们洗牌一次并多次重复使用的方式节省了我们在接下来几次迭代中的开销。我还有一个问题,你很难过,在对RDD进行分区之后,所有数据块都将在下一次迭代的执行器中可用,但当Spark应该加入时,这会导致仅对RDD进行洗牌吗?我的意思是,当发生洗牌时,秩RDD的所有数据块都将从驻留链接数据的执行器获取?Spark将在看到链接RDD已分区时进行一些优化?并且将仅为未分区的RDD洗牌数据?@Giorgio由于秩数据是从链接
RDD创建的,因此它包含的所有键(pageId
)应该已经在每个任务处理的分区中本地可用。