RDD a un ordre significatif (par opposition à un ordre aléatoire imposé par le modèle de stockage) s'il a été traité par sortBy()
, comme expliqué dans ce réponse .
Maintenant, quelles opérations préservent cet ordre?
Par exemple, est-ce garanti que (après a.sortBy()
)
a.map(f).Zip(a) ===
a.map(x => (f(x),x))
Que diriez-vous
a.filter(f).map(g) ===
a.map(x => (x,g(x))).filter(f(_._1)).map(_._2)
qu'en est-il de
a.filter(f).flatMap(g) ===
a.flatMap(x => g(x).map((x,_))).filter(f(_._1)).map(_._2)
Ici "égalité" ===
s'entend comme une "équivalence fonctionnelle", c'est-à-dire qu'il n'y a aucun moyen de distinguer le résultat à l'aide d'opérations au niveau de l'utilisateur (c'est-à-dire sans lire les journaux & c).
Toutes les opérations conservent l'ordre, à l'exception de celles qui ne le sont pas explicitement. L'ordre est toujours "significatif", pas seulement après un sortBy
. Par exemple, si vous lisez un fichier (sc.textFile
) les lignes du RDD seront dans l'ordre où elles se trouvaient dans le fichier.
Sans essayer de donner une liste complète, map
, filter
, flatMap
et coalesce
(avec shuffle=false
) conserve l'ordre. sortBy
, partitionBy
, join
ne conserve pas l'ordre.
La raison en est que la plupart des opérations RDD fonctionnent sur les Iterator
à l'intérieur des partitions. Donc map
ou filter
n'a tout simplement aucun moyen de gâcher la commande. Vous pouvez jeter un œil au code pour voir par vous-même.
Vous pouvez maintenant demander: et si j'ai un RDD avec un HashPartitioner
. Que se passe-t-il lorsque j'utilise map
pour changer les clés? Eh bien, ils resteront en place, et maintenant le RDD n'est pas partitionné par la clé. Vous pouvez utiliser partitionBy
pour restaurer le partitionnement avec un shuffle.