Потоковая передача Hadoop: Mapper 'оборачивает' двоичный исполняемый файл - PullRequest
8 голосов
/ 06 ноября 2010

У меня есть конвейер, который я сейчас запускаю на большом университетском компьютерном кластере. В целях публикации я хотел бы преобразовать его в формат mapreduce, чтобы он мог запускаться кем угодно при использовании кластера hadoop, такого как amazon webservices (AWS). В настоящее время конвейер состоит из серии сценариев Python, которые обертывают различные двоичные исполняемые файлы и управляют вводом и выводом с помощью модулей подпроцесса python и tempfile. К сожалению, я не писал двоичные исполняемые файлы, и многие из них либо не принимают STDIN, либо не генерируют STDOUT «полезным» способом (например, только отправляют его в файлы). Именно из-за этих проблем я завернул большинство из них в python.

До сих пор я был в состоянии изменить свой код Python таким образом, чтобы у меня был маппер и редуктор, который я мог запускать на своей локальной машине в стандартном «тестовом формате».

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

Маппер форматирует каждую строку данных так, как того требует бинарный файл, отправляет текст в бинарный файл с помощью subprocess.popen (это также позволяет мне маскировать много ложных STDOUT), а затем собирает STOUT, который я хочу, и форматирует его в строки текста, подходящие для редуктора. Проблемы возникают, когда я пытаюсь повторить команду при локальной установке hadoop. Я могу заставить маппер работать, но он выдает ошибку, которая предполагает, что он не может найти двоичный исполняемый файл.

Файл "/Users/me/Desktop/hadoop-0.21.0/./phyml.py", строка 69, в Файл main () "/Users/me/Desktop/hadoop-0.21.0/./mapper.py", линия 66, в основном Файл phyml (отсутствует) "/Users/me/Desktop/hadoop-0.21.0/./mapper.py", строка 46, в phyml Файл ft = Popen (cli_parts, stdin = PIPE, stderr = PIPE, stdout = PIPE) "/Library/Frameworks/Python.framework/Versions/6.1/lib/python2.6/subprocess.py", строка 621, в init errread, errwrite) Файл "/Library/Frameworks/Python.framework/Versions/6.1/lib/python2.6/subprocess.py", строка 1126, в _execute_child поднять child_exception OSError: [Errno 13] В доступе отказано

Моя команда hadoop выглядит следующим образом:

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

Как я отмечал выше, мне кажется, что маппер не знает о двоичном файле - возможно, он не отправляется на вычислительный узел? К сожалению, я не могу сказать, в чем проблема. Любая помощь будет принята с благодарностью. Было бы особенно приятно увидеть некоторые потоковые преобразователи / редукторы hadoop, написанные на python, которые оборачивают двоичные исполняемые файлы. Я не могу представить, что я первый, кто попытается сделать это! На самом деле, вот еще один пост, в котором задан тот же вопрос, но на него еще не ответили ...

Hadoop / Elastic Map Reduce с двоичным исполняемым файлом?

Ответы [ 2 ]

4 голосов
/ 09 ноября 2010

После долгих поисков (и т. Д.) Я выяснил, как включить исполняемые двоичные файлы / скрипты / модули, доступные для ваших картографов / редукторов. Хитрость заключается в том, чтобы сначала загрузить все свои файлы в hadoop.

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

Затем вам нужно отформатировать вашу потоковую команду как следующий шаблон:

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

Если вы связываете модуль Python, вам нужно добавить следующий код в ваши скрипты mapper / reducer:

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

Если вы обращаетесь к двоичному файлу через подпроцесс, ваша команда должна выглядеть примерно так:

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

Надеюсь, это поможет.

2 голосов
/ 04 января 2011

Наконец-то работает

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