Kan iemand het verschil uitleggen tussen reduceByKey
, groupByKey
, aggregateByKey
en combineByKey
? Ik heb de documenten hierover gelezen, maar kon de exacte verschillen niet begrijpen.
Een uitleg met voorbeelden zou geweldig zijn.
Antwoord 1, autoriteit 100%
groupByKey:
Syntaxis:
sparkContext.textFile("hdfs://")
.flatMap(line => line.split(" ") )
.map(word => (word,1))
.groupByKey()
.map((x,y) => (x,sum(y)))
groupByKey
kan schijfproblemen veroorzaken, aangezien gegevens over het netwerk worden verzonden en verzameld op de verminderde werknemers.
reduceByKey:
Syntaxis:
sparkContext.textFile("hdfs://")
.flatMap(line => line.split(" "))
.map(word => (word,1))
.reduceByKey((x,y)=> (x+y))
Gegevens worden op elke partitie gecombineerd, met slechts één uitvoer voor één sleutel op elke partitie om over het netwerk te verzenden. reduceByKey
vereist het combineren van al uw waarden in een andere waarde met exact hetzelfde type.
aggregateByKey:
hetzelfde als reduceByKey
, dat een beginwaarde aanneemt.
3 parameters als invoer
- beginwaarde
- Combiner-logica
- volgorde op logica
Voorbeeld:
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)
output:
Samenvoegen op basis van resultaten
balk -> 3
foo -> 5
combineByKey:
3 parameters als invoer
- Initiële waarde: in tegenstelling tot
aggregateByKey
, hoeft constant niet altijd te worden doorgegeven, we kunnen een functie doorgeven die een nieuwe waarde retourneert. - samenvoegfunctie
- functie combineren
Voorbeeld:
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)
reduceByKey
,aggregateByKey
,combineByKey
voorkeur bovengroupByKey
Referentie:
Vermijd groupByKey
Antwoord 2, autoriteit 29%
groupByKey()
is alleen bedoeld om uw dataset te groeperen op basis van een sleutel. Het zal resulteren in het verschuiven van gegevens wanneer RDD nog niet is gepartitioneerd.reduceByKey()
is zoiets als groeperen + aggregatie. We kunnen zeggenreduceByKey()
equivalent aan dataset.group(…).reduce(…). Het schudt minder gegevens in tegenstelling totgroupByKey()
.aggregateByKey()
is logisch gezien hetzelfde alsreduceByKey()
maar je kunt er een ander type resultaat mee teruggeven. Met andere woorden, het laat je een invoer hebben als type x en een geaggregeerd resultaat als type y. Bijvoorbeeld (1,2),(1,4) als invoer en (1,”zes”) als uitvoer. Er is ook nulwaardenodig die aan het begin van elke sleutel wordt toegepast.
Opmerking:Een overeenkomst is dat het allemaal brede operaties zijn.
Antwoord 3, autoriteit 19%
Hoewel zowel reducebykey als groupbykey hetzelfde antwoord geven, is de
reduceByKey werkt bijvoorbeeld veel beter op een grote dataset. dat is
omdat Spark weet dat het output kan combineren met een gemeenschappelijke toets op elke
partitie voordat u de gegevens in willekeurige volgorde schuift.Aan de andere kant, bij het aanroepen van groupByKey – alle sleutel-waardeparen
worden heen en weer geschud. Dit zijn veel onnodige gegevens om te zijn
overgedragen via het netwerk.
Kijk voor meer informatie op deze onderstaande link
Antwoord 4, autoriteit 11%
Hoewel beide dezelfde resultaten zullen opleveren, is er een significant verschil in de prestaties van beide functies. reduceByKey()
werkt beter met grotere datasets in vergelijking met groupByKey()
.
In reduceByKey()
worden paren op dezelfde machine met dezelfde sleutel gecombineerd (met behulp van de functie die is doorgegeven aan reduceByKey()
) voordat de gegevens worden geschud. Vervolgens wordt de functie opnieuw aangeroepen om alle waarden van elke partitie te verminderen om één eindresultaat te produceren.
In groupByKey()
worden alle sleutel-waardeparen door elkaar geschud. Dit zijn veel onnodige gegevens die via het netwerk moeten worden overgedragen.
Antwoord 5, autoriteit 6%
ReduceByKeyreduceByKey(func, [numTasks])
–
Gegevens worden gecombineerd zodat er op elke partitie minstens één waarde voor elke sleutel moet zijn.
En dan gebeurt er shuffle en wordt het via het netwerk naar een bepaalde uitvoerder gestuurd voor een actie, zoals verminderen.
GroupByKey– groupByKey([numTasks])
Het voegt de waarden voor de sleutel niet samen, maar het shuffle-proces vindt direct plaats
en hier wordt veel data naar elke partitie gestuurd, bijna hetzelfde als de initiële data.
En het samenvoegen van waarden voor elke toets gebeurt na de shuffle.
Hier worden veel gegevens opgeslagen op het laatste werkknooppunt, wat resulteert in een probleem met onvoldoende geheugen.
AggregateByKey– aggregateByKey(zeroValue)(seqOp, combOp, [numTasks])
Het is vergelijkbaar met reduceByKey, maar u kunt initiële waarden opgeven bij het uitvoeren van aggregatie.
Gebruik van reduceByKey
-
reduceByKey
kan worden gebruikt wanneer we op grote datasets werken. -
reduceByKey
wanneer de invoer- en uitvoerwaardetypen van hetzelfde type zijn
viaaggregateByKey
Bovendien wordt aanbevolen om groupByKey
niet te gebruiken en liever reduceByKey
te gebruiken. Voor details kun je hierraadplegen.
Je kunt ook deze vraagraadplegen voor meer informatie hoe reduceByKey
en aggregateByKey
.
Antwoord 6
Afgezien van deze 4 hebben we
foldByKey wat hetzelfde is als reduceByKey maar met een door de gebruiker gedefinieerde nulwaarde.
AggregateByKey neemt 3 parameters als invoer en gebruikt 2 functies voor het samenvoegen (een voor het samenvoegen op dezelfde partities en een andere om waarden over verschillende partities samen te voegen. De eerste parameter is ZeroValue)
terwijl
ReduceBykey gebruikt slechts 1 parameter, wat een functie is om samen te voegen.
CombineByKey heeft 3 parameters en alle 3 zijn functies. Vergelijkbaar met aggregateBykey, behalve dat het een functie kan hebben voor ZeroValue.
GroupByKey neemt geen parameter en groepeert alles. Het is ook een overhead voor gegevensoverdracht tussen partities.