web-dev-qa-db-fra.com

Dans Apache Spark, pourquoi RDD.union ne conserve-t-il pas le partitionneur?

Comme tout le monde connaît les partitionneurs en Spark ont un impact énorme sur les performances de toutes les opérations "larges", il est donc généralement personnalisé dans les opérations. J'expérimentais avec le code suivant:

val rdd1 =
  sc.parallelize(1 to 50).keyBy(_ % 10)
    .partitionBy(new HashPartitioner(10))
val rdd2 =
  sc.parallelize(200 to 230).keyBy(_ % 13)

val cogrouped = rdd1.cogroup(rdd2)
println("cogrouped: " + cogrouped.partitioner)

val unioned = rdd1.union(rdd2)
println("union: " + unioned.partitioner)

Je vois que par défaut cogroup() donne toujours un RDD avec le partitionneur personnalisé, mais union() ne le fait pas, il reviendra toujours à défaut. Ceci est contre-intuitif car nous supposons généralement qu'un PairRDD devrait utiliser son premier élément comme clé de partition. Existe-t-il un moyen de "forcer" Spark pour fusionner 2 PairRDD pour utiliser la même clé de partition?

24
tribbloid

union est une opération très efficace, car elle ne déplace aucune donnée. Si rdd1 A 10 partitions et rdd2 A 20 partitions alors rdd1.union(rdd2) aura 30 partitions: les partitions des deux RDD mises l'une après l'autre. Ce n'est qu'un changement de comptabilité, il n'y a pas de remaniement.

Mais il rejette nécessairement le partitionneur. Un partitionneur est construit pour un nombre donné de partitions. Le RDD résultant a un certain nombre de partitions différentes de rdd1 Et rdd2.

Après avoir pris l'union, vous pouvez exécuter repartition pour mélanger les données et les organiser par clé.


Il y a une exception à ce qui précède. Si rdd1 Et rdd2 Ont le même partitionneur (avec le même nombre de partitions), union se comporte différemment. Il joindra les partitions des deux RDD par paire, ce qui lui donnera le même nombre de partitions que chacune des entrées. Cela peut impliquer le déplacement de données (si les partitions n'étaient pas colocalisées) mais n'impliquera pas de lecture aléatoire. Dans ce cas, le partitionneur est conservé. (Le code pour cela est dans PartitionerAwareUnionRDD.scala .)

42
Daniel Darabos

Ce n'est plus vrai. Si deux RDD ont exactement le même partitionneur et le même nombre de partitions, le RDD unioned aura également ces mêmes partitions. Cela a été introduit dans https://github.com/Apache/spark/pull/4629 et incorporé dans Spark 1.3.

2
Joel Croteau