转换后我可以将分区器放回PairRDD吗?

时间:2016-06-18 01:21:08

标签: apache-spark pyspark

似乎在大多数转换(例如values()toDF())之后,pairRDD的“分区器”被重置为无。但是我的理解是,对于这些转换,可能并不总是改变分区。

由于cogroup和其他示例在已知分区被共同分区时执行效率更高,我想知道是否有办法告诉spark rdd仍然是共同分区的。

请参阅下面的简单示例,其中我创建了两个共同分区的rdd,然后将它们转换为DF并在生成的rdds上执行cogroup。可以使用值完成类似的示例,然后重新添加正确的对。

虽然这个例子很简单,但实际情况可能是我加载了两个具有相同分区的镶木地板数据帧。

这是否可行,在这种情况下是否会带来性能优势?

data1 = [Row(a=1,b=2),Row(a=2,b=3)]
data2 = [Row(a=1,c=4),Row(a=2,c=5)]
rdd1 = sc.parallelize(data1)
rdd2 = sc.parallelize(data2)

rdd1 = rdd1.map(lambda x: (x.a,x)).partitionBy(2)
rdd2 = rdd2.map(lambda x: (x.a,x)).partitionBy(2)

print(rdd1.cogroup(rdd2).getNumPartitions()) #2 partitions

rdd3 = rdd1.toDF(["a","b"]).rdd
rdd4 = rdd2.toDF(["a","c"]).rdd

print(rdd3.cogroup(rdd4).getNumPartitions()) #4 partitions (2 empty)

1 个答案:

答案 0 :(得分:1)

scala api中,大多数转换包括

preservesPartitioning=true

选项。 python RDD api的一些保留了这种能力:但是例如

groupBy

是一个重要的例外。就Dataframe API而言,分区方案似乎主要在最终用户控制范围之外 - 即使在scala端。

那么您可能需要:

  • 限制自己使用rdds - 即避免使用DataFrame / Dataset方法
  • 选择您选择的RDD转换:看一下那些允许的转换

    • 保留父级的分区方案
    • 使用preservesPartitioning = true