Spark 中分组 PairRDD 中的最佳分区数

Optimal number of partitions in a grouped PairRDD in Spark

我有两对结构为 RDD[String, Int] 的 RDD,称为 rdd1 和 rdd2。

这些 RDD 中的每一个都按其键分组,我想对其值执行一个函数(因此我将使用 mapValues 方法)。 方法 "GroupByKey" 是否为每个键创建一个新分区,或者我是否需要使用 "partitionBy" 手动指定?

我知道如果我不执行更改键的操作,RDD 的分区不会改变,所以如果我对每个 RDD 执行 mapValues 操作,或者如果我在前两个 RDD 之间执行连接操作RDD,结果 RDD 的分区不会改变。 是真的吗?

这里有一个代码示例。请注意 "function" 未定义,因为它在这里并不重要。

val lvl1rdd=rdd1.groupByKey()
val lvl2rdd=rdd2.groupByKey()
val lvl1_lvl2=lvl1rdd.join(lvl2rdd)
val finalrdd=lvl1_lvl2.mapValues(value => function(value))

如果我加入之前的 RDD 并对结果 RDD (mapValues) 的值执行一个函数,所有的工作都在一个 worker 中完成,而不是将不同的任务分布在 RDD 的不同 worker 节点上簇。我的意思是,期望的行为应该是并行执行作为参数传递给 mapValues 方法的函数,在集群允许的尽可能多的节点中。

1) 避免 groupByKey 操作,因为它们会成为网络 I/O 和执行性能的瓶颈。 在这种情况下更喜欢 reduceByKey 操作,因为数据混洗相对少于 groupByKey,如果它是更大的数据集,我们可以更好地看到差异。

val lvl1rdd = rdd1.reduceByKey(x => function(x)) 
val lvl1rdd = rdd2.reduceByKey(x => function(x))
//perform the Join Operation on these resultant RDD's

单独在 RDD 上应用函数并加入它们远比加入 RDD 并使用 groupByKey() 应用函数要好得多

这也将确保任务在不同的执行者之间分配并并行执行

Refer this link

2) 底层分区技术是 Hash partitioner。如果我们假设我们的数据最初位于 n 个分区中,那么 groupByKey 操作将遵循 Hash 机制。

partition = key.hashCode() % numPartitions

这将创建固定数量的分区,当您使用 groupByKey 时,可以超过初始数量 Operation.we 也可以自定义要制作的分区。例如

val result_rdd = rdd1.partitionBy(new HashPartitioner(2))

这将创建2个分区,这样我们就可以设置分区的数量。 要确定 最佳分区数 请参考此答案