使用显式和默认分区程序在转换链中进行Spark分区

时间:2017-08-19 22:09:14

标签: scala apache-spark partitioning

假设我从一开始就对数据进行分区开始:

即:

val rdd: RDD[Int, String] = ...;
val data = rdd.partitionBy(new RangePartitioner(8, rdd)).persist()

然后我说我做了:

val groupedData = data.groupByKey() // what is the partitioner here?

通常,groupByKey具有使用HashPartitioner的默认分区逻辑 - 在这种情况下,它会继续使用父分区程序,还是会根据默认值重新分区数据?

我查看了Partitioner#defaultPartitioner,这似乎就是这种情况(只有在未指定显式分区时才使用默认分区逻辑),但我认为我会做一个完整性检查

作为一个额外的问题,除了#map,#flatMap等关键变换转换之外,对于所有保存键的转换,它们是否都保持并传播明确定义的分区器?如果我从未对数据进行分区,那么它们是否会传播先前级别的默认值?

即:

rdd.groupByKey() // hash-partitioner by default
.mapValues(_.head)
.sortByKey //range-partitioner by default, but does it use the hash-partitioner from before?

1 个答案:

答案 0 :(得分:0)

在第一种情况下,将保留分区程序。这很容易检查

for {
  p1 <- groupedData.partitioner
  p2 <- data.partitioner
} yield p1 == p2

// Some(true)

在第二种情况下,分区程序为inherent part of the transformation,因此HashPartitioner将被丢弃:

val grouped = rdd.groupByKey

for {
  p1 <- grouped.partitioner
  p2 <- grouped.sortByKey().partitioner
} yield p1 == p2

// Some(false)