web-dev-qa-db-fra.com

Différence d'étincelle entre reductionByKey vs groupByKey vs aggregByKey vs combineByKey

Quelqu'un peut-il expliquer la différence entre reductionbykey, groupbykey, aggregbykey et combinebykey? J'ai lu les documents à ce sujet, mais je ne pouvais pas comprendre les différences exactes?

Si vous pouvez l'expliquer avec des exemples, ce serait formidable.

36
Arun S

groupByKey:

Syntaxe: 

sparkContext.textFile("hdfs://")
                    .flatMap(line => line.split(" ") )
                    .map(Word => (Word,1))
                    .groupByKey()
                    .map((x,y) => (x,sum(y)) )

groupByKey peut provoquer des problèmes de disque car les données sont envoyées sur le réseau et collectées sur les postes de travail réduits.

reductionByKey:

Syntaxe: 

sparkContext.textFile("hdfs://")
                    .flatMap(line => line.split(" "))
                    .map(Word => (Word,1))
                    .reduceByKey((x,y)=> (x+y))

Les données sont combinées sur chaque partition, une seule sortie pour une clé sur chaque partition étant envoyée sur le réseau . reductionByKey est nécessaire pour combiner toutes vos valeurs dans une autre valeur du même type.

aggregByKey:

idem que reductionByKey, qui prend une valeur initiale.

3 paramètres en entrée I. valeur initiale ii. Logique du combinateur iii. logique de séquence

*Example:* `

val keysWithValuesList = Array("foo=A", "foo=A", "foo=A", "foo=A", "foo=B", "bar=C", "bar=D", "bar=D")
    val data = sc.parallelize(keysWithValuesList)
    //Create key value pairs
    val kv = data.map(_.split("=")).map(v => (v(0), v(1))).cache()
    val initialCount = 0;
    val addToCounts = (n: Int, v: String) => n + 1
    val sumPartitionCounts = (p1: Int, p2: Int) => p1 + p2
    val countByKey = kv.aggregateByKey(initialCount)(addToCounts, sumPartitionCounts)

`

ouput: Agréger par somme de résultats Résultatsbar -> 3foo -> 5

combineByKey:

3 paramètres en entrée 

  1. Valeur initiale: contrairement à aggregByKey, il n'est pas nécessaire de toujours passer une constante, nous pouvons transmettre à une fonction une fonction qui renverra une nouvelle valeur.
  2. fonction de fusion
  3. combiner la fonction

Exemple: `

val result = rdd.combineByKey(
                        (v) => (v,1),
                        ( (acc:(Int,Int),v) => acc._1 +v , acc._2 +1 ) ,
                        ( acc1:(Int,Int),acc2:(Int,Int) => (acc1._1+acc2._1) , (acc1._2+acc2._2)) 
                        ).map( { case (k,v) => (k,v._1/v._2.toDouble) })
        result.collect.foreach(println)

`

reductionByKey, aggregByKey, combineByKey préféré sur groupByKey

Référence:Eviter groupByKey

40

Tandis que les commandes de réduction de clé et de groupe permettent de produire la même réponse, le Réduire exemple exemple fonctionne mieux sur un grand ensemble de données. C'est car Spark sait qu’il peut combiner la sortie avec une clé commune sur chaque partitionner avant de mélanger les données.

Par ailleurs, lorsque vous appelez groupByKey, toutes les paires clé-valeur sont mélangés. Cela fait beaucoup de données inutiles à être transféré sur le réseau.

pour plus de détails, consultez ce lien ci-dessous

https://databricks.gitbooks.io/databricks-spark-knowledge-base/content/best_practices/prefer_reducebykey_over_groupbykey.html

11
yoga
  • groupByKey() consiste simplement à grouper votre jeu de données en fonction d'une clé. Cela entraînera un brassage des données lorsque le RDD n’est pas déjà partitionné. 
  • reduceByKey() est quelque chose comme grouper + agrégation. Nous pouvons dire réducteur équivalent () à dataset.group (...). Réduire (...). Il mélangera moins de données contrairement à groupByKey()
  • aggregateByKey() est logiquement identique à reductionByKey () mais vous permet de renvoyer le résultat dans un type différent. En d'autres termes, il vous permet d'avoir une entrée de type x et d'agréger le résultat de type y. Par exemple (1,2), (1,4) en entrée et (1, "six") en sortie. Il faut aussi zero-value qui sera appliqué au début de chaque touche.

Remarque: Une similitude est qu'ils sont tous des opérations larges.

8
Balaji Reddy

Bien que les deux obtiennent les mêmes résultats, il existe une différence significative dans les performances des deux fonctions. reduceByKey() fonctionne mieux avec des jeux de données plus volumineux par rapport à groupByKey().

Dans reduceByKey(), les paires d'un même ordinateur possédant la même clé sont combinées (à l'aide de la fonction passée à reduceByKey()) avant que les données ne soient mélangées. Ensuite, la fonction est appelée à nouveau pour réduire toutes les valeurs de chaque partition afin de produire un résultat final.

Dans groupByKey(), toutes les paires clé-valeur sont mélangées. Cela représente beaucoup de données inutiles à transférer sur le réseau.

3
Sumanth Sai

ReduceByKeyreduceByKey(func, [numTasks])-

Les données sont combinées de manière à ce qu'il y ait au moins une valeur pour chaque clé sur chaque partition .

GroupByKey - groupByKey([numTasks])

Il ne fusionne pas les valeurs de la clé, mais directement le processus de mélange a lieu Ici, de nombreuses données sont envoyées à chaque partition, presque identiques aux données initiales.

Et la fusion des valeurs pour chaque clé est effectuée après la lecture aléatoire . Ici, de nombreuses données stockées sur le noeud de travail final entraînent un problème de mémoire insuffisante.

AggregateByKey - aggregateByKey(zeroValue)(seqOp, combOp, [numTasks])Il ressemble à reductionByKey, mais vous pouvez fournir des valeurs initiales lors de l'agrégation.

Utilisation de reduceByKey

  • reduceByKey peut être utilisé lorsque nous exécutons de grands ensembles de données. 

  • reduceByKey lorsque les types de valeur d'entrée et de sortie sont du même type sur aggregateByKey

De plus, il est recommandé de ne pas utiliser groupByKey et de préférer reduceByKey. Pour plus de détails, vous pouvez consulter ici .

Vous pouvez également consulter cette question pour comprendre plus en détail comment reduceByKey et aggregateByKey.

1
Rajat Mishra

Alors en dehors de ces 4, nous avons 

foldByKey qui est identique à reductionByKey mais avec une valeur zéro définie par l'utilisateur.

AggregateByKey prend 3 paramètres en entrée et utilise 2 fonctions pour la fusion (une pour la fusion sur les mêmes partitions et une autre pour la fusion de valeurs sur plusieurs partitions. Le premier paramètre est ZeroValue).

tandis que

RéduireBykey prend 1 paramètre seulement qui est une fonction pour la fusion.

CombineByKey prend 3 paramètres et tous les 3 sont des fonctions. Semblable à aggregBykey sauf qu'il peut avoir une fonction pour ZeroValue.

GroupByKey ne prend aucun paramètre et regroupe tout. En outre, il s'agit d'une surcharge pour le transfert de données entre partitions.

0
Swaraj Shekhar