2010-11-06 10 views
8

Ho una pipeline che attualmente eseguo su un cluster di computer universitari di grandi dimensioni. Per scopi di pubblicazione mi piacerebbe convertirlo in un formato mapreduce in modo che possa essere eseguito da chiunque sull'utilizzo di un cluster hadoop come Amazon Webservices (AWS). La pipeline attualmente consiste in serie di script python che racchiudono diversi eseguibili binari e gestiscono l'input e l'output utilizzando i moduli subprocess python e tempfile. Sfortunatamente non ho scritto gli eseguibili binari e molti di loro non prendono STDIN o non emettono STDOUT in modo 'utilizzabile' (ad esempio, lo hanno inviato solo ai file). Questi problemi sono il motivo per cui ho spostato la maggior parte di essi in Python.Hadoop Streaming: Mapper 'wrapping' un eseguibile binario

Finora sono stato in grado di modificare il mio codice Python in modo tale che ho un mapper e un riduttore che posso correre sulla mia macchina locale nella norma 'formato di prova.'

$ cat data.txt | mapper.py | reducer.py 

Il mapper formatta ogni riga di dati nel modo in cui il file binario lo vuole, invia il testo al binario usando subprocess.popen (questo mi permette anche di mascherare un sacco di spurito STDOUT), quindi raccoglie lo STOUT che voglio e lo formatta in linee di testo appropriato per il riduttore. I problemi sorgono quando provo a replicare il comando su un'installazione locale di hadoop. Posso ottenere il mapper da eseguire, ma dà un errore che suggerisce che non riesce a trovare l'eseguibile binario.

File "/Users/me/Desktop/hadoop-0.21.0/./phyml.py", line 69, in main() File "/Users/me/Desktop/hadoop-0.21.0/./mapper.py", line 66, in main phyml(None) File "/Users/me/Desktop/hadoop-0.21.0/./mapper.py", line 46, in phyml ft = Popen(cli_parts, stdin=PIPE, stderr=PIPE, stdout=PIPE) File "/Library/Frameworks/Python.framework/Versions/6.1/lib/python2.6/subprocess.py", line 621, in init errread, errwrite) File "/Library/Frameworks/Python.framework/Versions/6.1/lib/python2.6/subprocess.py", line 1126, in _execute_child raise child_exception OSError: [Errno 13] Permission denied

mio comando Hadoop è simile al seguente:

./bin/hadoop jar /Users/me/Desktop/hadoop-0.21.0/mapred/contrib/streaming/hadoop-0.21.0-streaming.jar \ 
-input /Users/me/Desktop/Code/AWS/temp/data.txt \ 
-output /Users/me/Desktop/aws_test \ 
-mapper mapper.py \ 
-reducer reducer.py \ 
-file /Users/me/Desktop/Code/AWS/temp/mapper.py \ 
-file /Users/me/Desktop/Code/AWS/temp/reducer.py \ 
-file /Users/me/Desktop/Code/AWS/temp/binary 

Come ho già detto che mi sembra il mapping non è a conoscenza del binario - forse non è stato inviato al nodo di elaborazione ? Sfortunatamente non so davvero quale sia il problema. Qualsiasi aiuto sarebbe molto apprezzato. Sarebbe particolarmente bello vedere alcuni mappatori/riduttori di streaming hadoop scritti in python che eseguono binari eseguibili binari. Non riesco a immaginare di essere il primo a provare a farlo! In realtà, qui è un altro post che chiede in sostanza la stessa domanda, ma non ha ancora ricevuto risposta ...

Hadoop/Elastic Map Reduce with binary executable?

+0

Sembra può essere un problema di autorizzazioni. Apparentemente hadoop-streaming.jar 'perde' i permessi dei file quando li impacchetta nei file .jar che invia ai nodi di calcolo. Eventuali suggerimenti? –

+0

Ok. Ci sono "alcune" informazioni su come farlo su Amazon.http://developer.amazonwebservices.com/connect/thread.jspa?messageID=130482🶲 –

risposta

4

Dopo molto googling (etc.) ho capito come includere eseguibili binari/scripts/moduli accessibili ai tuoi mappatori/riduttori. Il trucco è caricare prima tutti i file su hadoop.

$ bin/hadoop dfs -copyFromLocal /local/file/system/module.py module.py 

allora avete bisogno di formato che in streaming comando come il seguente modello:

$ ./bin/hadoop jar /local/file/system/hadoop-0.21.0/mapred/contrib/streaming/hadoop-0.21.0-streaming.jar \ 
-file /local/file/system/data/data.txt \ 
-file /local/file/system/mapper.py \ 
-file /local/file/system/reducer.py \ 
-cacheFile hdfs://localhost:9000/user/you/module.py#module.py \ 
-input data.txt \ 
-output output/ \ 
-mapper mapper.py \ 
-reducer reducer.py \ 
-verbose 

Se stai collegando un modulo Python è necessario aggiungere il seguente codice ai tuoi script Mapper/riduttore :

import sys 
sys.path.append('.') 
import module 

Se accedi un binario tramite subprocessing vostro comando dovrebbe essere simile a questo:

0.123.
cli = "./binary %s" % (argument) 
cli_parts = shlex.split(cli) 
mp = Popen(cli_parts, stdin=PIPE, stderr=PIPE, stdout=PIPE) 
mp.communicate()[0] 

Spero che questo aiuti.

+0

Inoltre, non ho provato questo, ma penso che il comando di streaming possa essere semplificato comprimendo tutto e usando il comando -cacheArchive. –

2

Got in esecuzione finalmente

$pid = open2 (my $out, my $in, "./binary") or die "could not run open2"; 
+0

Ho lo stesso problema ma ho problemi a seguire la tua soluzione, potresti chiarire? – AlexIIP

Problemi correlati