Ich habe Funken an der Dokumentation gesucht und es erwähnt dies:Was ist der richtige Weg, um ein statisches Objekt auf allen Arbeitnehmern haben
Spark API stützt sich stark auf Funktionen im Treiberprogramm vorbei zu auf dem Cluster ausführen. Es gibt zwei empfohlene Methoden:
Anonyme Funktionssyntax, die für kurze Codeabschnitte verwendet werden kann. Statische Methoden in einem globalen Singleton-Objekt. Zum Beispiel können Sie Objekt MyFunctions definieren und dann MyFunctions.func1 passieren, wie folgt:
object MyFunctions { def func1(s: String): String = { ... } }
myRdd.map(MyFunctions.func1)
Beachten Sie, dass, während es auch möglich, ist eine Referenz auf eine Methode in einer Klasse-Instanz übergeben (Im Gegensatz zu einem Singleton-Objekt) erfordert dies das Senden des Objekts, das die Klasse zusammen mit der Methode enthält. Betrachten wir zum Beispiel:
class MyClass {
def func1(s: String): String = { ... }
def doStuff(rdd: RDD[String]): RDD[String] = { rdd.map(func1) }
}
Hier wird, wenn wir eine neue MyClass und rufen doStuff darauf, die Karte im Inneren gibt verweist auf die func1 Methode dieses MyClass Instanz, so dass die gesamte Objekt Bedürfnisse erstellen an den Cluster gesendet werden. Es ähnelt dem Schreiben
rdd.map(x => this.func1(x))
.
Jetzt ist mein Zweifel, was passiert, wenn Sie Attribute auf dem Singleton-Objekt haben (die statisch äquivalent sein sollen). Dasselbe Beispiel mit einer kleinen Änderung:
object MyClass {
val value = 1
def func1(s: String): String = { s + value }
}
myRdd.map(MyClass.func1)
So ist die Funktion noch statisch verwiesen, aber wie Funken weit geht geht indem man versucht, alle referenzierten Variablen zu serialisiert? Wird es value
serialisiert oder wird es in den Remote-Arbeitern wieder initialisiert?
Darüber hinaus ist dies alles in dem Zusammenhang, dass ich einige schwere Modelle in einem Singleton-Objekt habe und ich möchte die richtige Möglichkeit finden, sie an Arbeiter zu serialisieren, während die Fähigkeit, sie aus dem Singleton überall statt zu referenzieren übergibt sie als Funktionsparameter über einen Call-Stack mit ziemlich tiefer Funktion.
Jede eingehende Informationen über was/wie/wann Spark Daten serialisieren würde geschätzt.
Da die Anfangswerte von statischen Feldern in einer Java-Klasse im Jar gespeichert sind, können Worker sie direkt verwenden. Wenn Sie jedoch den Wert eines statischen Felds im Treiber ändern, können Worker nur den Anfangswert anzeigen. Bitte testen Sie es nicht im lokalen Modell, da der lokale Modus denselben Prozess wieder verwendet. – zsxwing
Das ist sehr aufschlussreich, aber ich bin immer noch verwirrt. Singletons in Scala sollen in Ihrem Beispiel eine Instanzvariable erzeugen (http://stackoverflow.com/questions/5721046/singletons-as-synthetic-classes-in-scala). Irgendwelche solche Referenzkräfte Spark ["so dass das ganze Objekt an den Cluster gesendet werden muss"] (https://spark.apache.org/docs/latest/programming-guide.html#passing-functions-to-spark). Außerdem habe ich erwähnt, dass [Spark ein paar Extras macht] (https://www.quora.com/What-does-Closure-cleaner-func-mean-in-Spark) von dem, was von der Scala erwartet werden kann Compiler: -S –
Singletons in Scala werden immer noch in einer statischen Variable gehalten (in meinem Beispiel wäre das "foo $ .MODULE $"), und statische Variablen werden niemals serialisiert. Spark hat Code, um Schließungen zu bereinigen, aber das gilt nicht für Singletons, da es in diesem Fall keine Serialisierung gibt. – vanza