2016-03-23 6 views
0

In Python, kann ich dies zum Beispiel tun:pyspark bestehen Änderungen Variable außerhalb von Mapper Umfang

lRet = [] 
llData = [range(3) for i in range(5)] 
def func(l): 
    lRet.append(l[0]) 
    return l 

map(func, llData) 
print(lRet) 

-> [0, 0, 0, 0, 0] 

Jetzt will ich etwas ähnliches in PySpark tun. Mein Grund ist, dass ich etwas außerhalb meiner RDD von Daten schaffen muss, die in meiner RDD sind. Lässt das Gleiche tun:

lRet = [] 
#rddData.collect() is of form llData above 
def func(l): 
    lRet.append(l[0]) 
    return l 

rddData.map(func).collect() 
print lRet 

-> [] 

Ich habe auch bemerkt nur, dass in einem import pdb; pdb.set_trace() auf einem lokalen pyspark Instanz das erste Beispiel tut das gleiche Ergebnis lRet unverändert bleiben gibt, obwohl es intern Spur von lRet hält.

Irgendwelche Ideen?

+0

Wenn Sie 'lRet' erstellen, fügen Sie nur hinzu/anhängen? Ist die Reihenfolge wichtig, wenn Sie hinzufügen/anhängen? –

+0

@KatyaHandler Nun, im wirklichen Leben möchte ich zu einer spärlichen Matrix lesen/schreiben. Ich dachte, das Konzept sollte das gleiche sein, also habe ich viel einfacheren Beispielcode erstellt. Zu Ihrer Frage: Ich benutze Indezes, um auf die Matrix zuzugreifen (Analogie kommt von llData), also ist die Reihenfolge egal – Roman

+0

Also ist das Problem bei der Parallelverarbeitung das, was passiert, wenn zwei verschiedene Aufgaben geändert werden müssen (das ist nicht additiv) am Ort (x, y) in Ihrer spärlichen Matrix? Vielleicht denkt Knoten 1 Matrix (x, y) = 1, während Knoten 7 Matrix (x, y) = 0 denkt. Was ist richtig? Dies kann nicht parallel gemacht werden, weil es inhärent Ordnung gibt. Einzige Möglichkeit sind additive Eigenschaften, die mit [Akkumulatoren] (http://spark.apache.org/docs/latest/programming-guide.html#accumulators) erreicht werden können. –

Antwort

1

Die kurze Antwort ist es ist nicht möglich. Die Spark-Programmierung deckt nicht die Werkzeuge ab, die erforderlich sind, um den gemeinsamen veränderlichen Zustand aufrechtzuerhalten. Wenn Sie Ihren Code ausführen, erhält jeder Executor-Interpreter eine eigene Kopie der lRet-Variablen, die lokal modifiziert und später verworfen wird.

Wie Katya Handler in the comments Funken erwähnt bietet accumulators aber diese sind schreib nur, bietet keine Garantie für konsistente Ergebnisse, wenn sie außerhalb Aktionen verwendet werden, und der Fahrer Zustand Update pro Aufgabe fold wie Logik.

Es gibt Projekte, die lange laufende Aufgaben und externe Synchronisierung Primitiven auf Spark verwenden, aber es ist ein völlig anderes Modell.

Verwandte Themen