6

Wenn der Scala Standard lib verwendet, kann ich ungefähr wie folgt tun:Warum aggregieren und falten zwei verschiedene APIs in Spark?

scala> val scalaList = List(1,2,3) 
scalaList: List[Int] = List(1, 2, 3) 

scala> scalaList.foldLeft(0)((acc,n)=>acc+n) 
res0: Int = 6 

Machen ein Int aus vielen Ints.

Und ich kann so etwas tun:

scala> scalaList.foldLeft("")((acc,n)=>acc+n.toString) 
res1: String = 123 

Machen ein String aus vielen Ints.

Also, foldLeft könnte entweder homogen oder heterogen sein, was immer wir wollen, es ist in einer API.

Während in Spark, wenn ich aus vielen Ints ein Int will, kann ich dies tun:

scala> val rdd = sc.parallelize(List(1,2,3)) 
rdd: org.apache.spark.rdd.RDD[Int] = ParallelCollectionRDD[1] at parallelize at <console>:12 
scala> rdd.fold(0)((acc,n)=>acc+n) 
res1: Int = 6 

Die Falte API foldLeft ähnlich ist, aber es ist nur homogen, ein RDD [Int] können produziere nur Int mit Falte.

Es ist ein Aggregat API in Funken zu:

scala> rdd.aggregate("")((acc,n)=>acc+n.toString, (s1,s2)=>s1+s2) 
res11: String = 132 

Es ist heterogen, ein RDD [Int] jetzt einen String erzeugen kann.

Warum werden Falte und Aggregat als zwei verschiedene APIs in Spark implementiert?

Warum sind sie nicht wie foldLeft konzipiert, die sowohl homogen als auch heterogen sein könnten?

(Ich bin sehr neu für Zündkerzen, mich bitte entschuldigen, wenn dies eine dumme Frage.)

Antwort

1

fold kann effizienter durchgeführt werden, da es auf einer festen Reihenfolge der Auswertung hängt nicht. So kann jeder Cluster-Knoten fold sein eigenes Stück parallel, und dann ein kleines Gesamt fold am Ende. Während mit foldLeft jedes Element in der Reihenfolge eingeklappt werden muss und nichts parallel gemacht werden kann.

(Auch ist es schön, eine einfachere API für den gemeinsamen Fall für Bequemlichkeit zu haben. Der Standard-lib reduce sowie foldLeft aus diesem Grunde hat)

+0

Um genauer zu sein, 'fold' in Spark erfordert sowohl die Assoziativität als auch die Kommutativität, während "falten" in Scala und anderen nicht verteilten Frameworks keine Kommutativität erfordert. Weitere Informationen finden Sie in der Spark-Dokumentation [hier] (https://spark.apache.org/docs/latest/api/java/org/apache/spark/rdd/RDD.html#fold (T,% 20scala.Function2)) – FuzzY

2

Insbesondere in Spark, wird die Berechnung verteilt und parallel durchgeführt, So kann foldLeft nicht implementiert werden, wie es in der Standardbibliothek ist. Stattdessen erfordert das Aggregat zwei Funktionen, eine, die eine Operation ähnlich fold auf jedem Element des Typs T, produziert einen Wert vom Typ U, und ein anderer, der die U von jeder Partition in dem Endwert kombiniert ausführt:

def aggregate[U: ClassTag](zeroValue: U)(seqOp: (U, T) => U, combOp: (U, U) => U): U 
0

foldLeft, foldRight, reduceLeft, reduceRight, scanLeft und scanRight sind Operationen, bei denen der akkumulierte Parameter von den Eingangsparametern ((A, B) -> B) abweichen kann und diese Operationen nur sequentiell ausgeführt werden können.

fold ist eine Operation, bei der der akkumulierte Parameter vom gleichen Typ der Eingangsparameter sein muss ((A, A) -> A). Dann kann es parallel ausgeführt werden.

aggregation ist eine Operation, bei der der akkumulierte Parameter von einem anderen Typ als die Eingabeparameter sein kann, aber dann müssen Sie eine zusätzliche Funktion bereitstellen, die definiert, wie die kumulierten Parameter im Endergebnis aggregiert werden können. Diese Operation ermöglicht eine parallele Ausführung. Die Operation aggregation ist eine Kombination aus foldLeft und fold.

Für weitere Informationen, können Sie einen Blick auf die Coursera Videos für die "Parallel-Programmierung" Natürlich haben: