2010-11-06 40 views
8

J'ai un pipeline que je dirige actuellement sur un grand cluster d'ordinateurs universitaires. À des fins de publication, je voudrais le convertir en format mapreduce afin qu'il puisse être utilisé par n'importe qui sur l'utilisation d'un cluster Hadoop tel que Amazon Webservices (AWS). Le pipeline consiste actuellement en une série de scripts python qui enveloppent différents exécutables binaires et gèrent l'entrée et la sortie à l'aide des sous-processus python et des modules tempfile. Malheureusement, je n'ai pas écrit les exécutables binaires et beaucoup d'entre eux ne prennent pas STDIN ou n'émettent pas STDOUT de manière "utilisable" (par exemple, ils ne l'ont envoyé qu'aux fichiers). Ces problèmes sont la raison pour laquelle j'ai enveloppé la plupart d'entre eux en python.Hadoop Streaming: Mapper 'encapsulant' un exécutable binaire

Jusqu'à présent, je suis en mesure de modifier mon code Python tel que j'ai un cartographe et un réducteur que je peux courir sur ma machine locale dans la norme « format test. »

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

Le mappeur formate chaque ligne de données de la façon dont le binaire qu'il enveloppe le veut, envoie le texte au binaire en utilisant subprocess.popen (cela me permet aussi de masquer beaucoup de STDOUT), puis recueille le STOUT que je veux, et le met en forme en lignes de texte approprié pour le réducteur. Les problèmes surviennent lorsque j'essaie de répliquer la commande sur une installation hadoop locale. Je peux obtenir le mapper à exécuter, mais il donne une erreur qui suggère qu'il ne peut pas trouver l'exécutable binaire.

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

Ma commande Hadoop se présente comme suit:

./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 

Comme je l'ai mentionné ci-dessus, il me semble que le cartographe ne connaît pas le binaire - peut-être ce n'est pas envoyé au nœud de calcul ? Malheureusement, je ne peux pas vraiment dire quel est le problème. Toute aide serait grandement appréciée. Il serait particulièrement intéressant de voir des mappeurs/réducteurs de flux hadoop écrits en python qui enveloppent les exécutables binaires. Je ne peux pas imaginer que je suis le premier à essayer de faire ça! En fait, voici un autre poste demandant en substance la même question, mais il n'a pas été encore répondu ...

Hadoop/Elastic Map Reduce with binary executable?

+0

On dirait qu'il peut être un problème d'autorisations. Apparemment, hadoop-streaming.jar 'perd' les autorisations de fichiers lorsqu'il les empaquette dans les fichiers .jar qu'il envoie aux noeuds de traitement. Aucune suggestion? –

+0

Ok. Il y a «quelques» informations sur la façon de le faire sur amazon.http://developer.amazonwebservices.com/connect/thread.jspa?messageID=130482🶲 –

Répondre

4

Après beaucoup de googler (etc.) j'ai compris comment inclure les fichiers binaires/scripts exécutables/modules accessibles à vos mappeurs/réducteurs. L'astuce consiste à télécharger tous vos fichiers sur hadoop en premier.

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

Ensuite, vous devez formater vous commande de streaming comme le modèle suivant:

$ ./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 

Si vous liez un module python vous devez ajouter le code suivant à vos Mapper/scripts réducteur :

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

Si vous accédez à un fichier binaire via votre commande devrait sous-traitance ultérieure ressembler à ceci:

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

Espérons que cela aide.

+0

Aussi, je n'ai pas essayé cela, mais je pense que la commande de streaming peut être simplifiée en compressant tout et en utilisant la commande -cacheArchive. –

2

Got it courir enfin

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

J'ai le même problème mais j'ai du mal à suivre votre solution, pourriez-vous clarifier s'il vous plaît? – AlexIIP