2012-04-16 11 views
5

Ich frage mich, ob es möglich ist, ein Mitgliedsobjekt hinzuzufügen, das über mehrere map() -Aufruf verwendet werden kann. Zum Beispiel kann ein String:Ist das Mapper-Objekt von Hadoop für mehrere Threads freigegeben?

private StringBuilder builder; 

public void map(...){ 
    ... 

    builder.setLength(0); 
    builder.append(a); 
    builder.append(b); 
    builder.append(c); 
    d = builder.toString(); 

    ... 
} 

Offensichtlich wenn das Mapper Objekt über mehrere Threads gemeinsam genutzt wird, verhält sich der Bauherr Objekt oben nicht wie erwartet aufgrund gleichzeitigen Zugriff von mehreren Threads.

Meine Frage ist also: Ist sichergestellt, dass jeder Thread in Hadoop ein eigenes Mapper-Objekt für sich selbst verwendet? Oder ist es ein konfigurierbares Verhalten?

Dank

Antwort

2

Solange Sie nicht die MultithreadedMapper Klasse, aber Ihre eigenen verwenden, wird es kein Problem geben. map() heißt sequenziell und nicht parallel.

Es ist üblich, eine StringBuilder oder andere Datenstrukturen zu verwenden, um ein paar Objekte zwischen den Aufrufen zu puffern. Aber stellen Sie sicher, dass Sie die Objekte aus Ihren Eingabeobjekten klonen, es gibt nur ein Objekt und es wird immer und immer wieder gefüllt, um viele GC zu vermeiden.

Es ist also nicht notwendig, die Rennbedingungen zu synchronisieren oder zu berücksichtigen.

+0

Das möchte ich wissen. Vielen Dank. – JRaSH

+1

Sie müssen die Objekte nur klonen, wenn Sie das gesamte Key/Value-Objekt benötigen. Wenn Sie nur einen Teil des Inhalts benötigen, den Sie zum StringBuffer hinzufügen, ist alles in Ordnung. Vergessen Sie nicht, die Bereinigungsmethode hinzuzufügen (ich vergesse den zu überschreibenden Namen), um den Reducer zu bündeln/zu schreiben, was auch immer Sie zwischen Mapaufrufen puffern, sonst werden Sie am Ende einige Daten erhalten, die niemals an die Reducers gesendet werden. – Drizzt321

0

Ich glaube nicht, das möglich ist. Der Grund dafür ist, dass jeder Mapper in einer eigenen JVM ausgeführt wird (sie werden auf verschiedenen Rechnern verteilt), so dass Sie Variablen oder Objekte nicht problemlos über mehrere Mapper oder Reducer hinweg gemeinsam nutzen können.

Nun, wenn alle Mapper auf demselben Knoten laufen, glaube ich, eine Konfiguration für JVM Wiederverwendung irgendwo gibt es, aber ehrlich gesagt würde ich nicht mit, dass die Mühe, vor allem, wenn alles, was Sie brauchen, ist ein StringBuilder ist :)

Ich habe diese Frage schon einmal gesehen, und sie könnte sehr leicht gelöst werden, wenn man das Design der Anwendung ändert. Vielleicht kannst du mehr darüber erzählen, was du damit erreichen willst, um zu sehen, ob das wirklich nötig ist. Wenn Sie es wirklich brauchen, können Sie Ihr Objekt immer noch serialisieren, in HDFS ablegen, es dann mit jedem Mapper lesen, deserialisieren, aber das scheint rückwärts zu sein.

+0

Hallo, ich möchte nicht eine Variable über mehrere Mapper teilen. Soweit ich weiß, heißt die Map() -Methode jedes Mappers mehrere Male, das ist, wo ich denke, dass ich ein paar Ressourcen sparen kann. Wenn Sie also ein Member-Objekt in die Mapper-Instanz einfügen, kann dieses Objekt über mehrere map() - Aufrufe hinweg ohne Init und De-Init aufgerufen werden. Meine Sorge ist: Wenn map() gleichzeitig aufgerufen wird, kann es ein Problem für die Verwendung von Memeber-Objekt auftreten. – JRaSH

Verwandte Themen