假设我从一开始就对数据进行分区开始:
即:
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?
答案 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)