2013-08-09 2 views
10

У меня есть работа MapReduce, определенная в main.py, который импортирует lib модуля из lib.py. Я использую Hadoop Streaming представить эту работу в кластер Hadoop следующим образом:Как импортировать пользовательский модуль в задание MapReduce?

hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar -files lib.py,main.py 
    -mapper "./main.py map" -reducer "./main.py reduce" 
    -input input -output output 

В моем понимании, это должно поместить как main.py и lib.py в распределенной папкукэша на каждой вычислительной машине и, таким образом, сделать модуль lib доступны до main. Но этого не происходит: из журнала я вижу, что файлы действительно скопированы в тот же каталог, но main не может импортировать lib, метать ImportError.

Почему это происходит и как я могу это исправить?

UPD. Добавление текущего каталога в пути не работал:

import sys  
sys.path.append(os.path.realpath(__file__)) 
import lib 
# ImportError 

хотя, загружая модуль вручную сделал трюк:

import imp 
lib = imp.load_source('lib', 'lib.py') 

Но это не то, что я хочу. Итак, почему интерпретатор Python видит другие файлы .py в том же каталоге, но не может их импортировать? Обратите внимание, что я уже пытался добавить пустой файл __init__.py в тот же каталог без эффекта.

+0

Вы проверили 'sys.path' в' main.py', чтобы убедиться, что рабочий каталог включен? – lmjohns3

+0

@ lmjohns3: да, рабочий каталог находится на пути к классам. BTW, разве он не включен автоматически для запуска скрипта? (просто любопытно) – ffriend

+0

Я считаю, что это верно для скриптов Python, запущенных в командной строке, но потоковая передача Hadoop может запускать интерпретатор Python по-другому (не совсем уверен). В любом случае, я все еще думаю, что это звучит как проблема пути. См. Http://www.litfuel.net/plush/?postid=195 за одну возможность распространять свои модули по-другому. В качестве альтернативы попробуйте написать свои команды в сценарий оболочки и передать это для аргументов командной строки '-mapper' и' -reducer'. – lmjohns3

ответ

12

Я отправил вопрос в список пользователей Hadoop и, наконец, нашел ответ. Оказывается, Hadoop на самом деле не копирует файлы в место, где выполняется команда, а вместо этого создает символические ссылки. Python, в свою очередь, не может работать с символическими ссылками и поэтому не распознает lib.py как модуль Python.

Простой обходной путь здесь поставить как main.py и lib.py в тот же каталог, так что символическая в каталог помещается в рабочий каталог MR рабочих мест, в то время как оба файла находятся физически в том же каталоге. Так что я сделал следующее:

  1. Помещенный main.py и lib.py в app каталог.
  2. В main.py я lib.py непосредственно, то есть строка импорта только

    импорт Lib

  3. app Загрузил каталог с -files опцией.

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

hadoop jar /usr/lib/hadoop-mapreduce/hadoop-streaming.jar -files app 
     -mapper "app/main.py map" -reducer "app/main.py reduce" 
     -input input -output output 
+0

Использование опции -files для загрузки десятков файлов не работало в моей среде hadoop. –

3

Когда Hadoop-Streaming запускает скрипты питона, путь вашего Python скрипта, где файл сценария на самом деле. Однако hadoop запускает их в './', а ваш lib.py (это символическая ссылка) также находится на './'. Так, попробуйте добавить 'sys.path.append ("./")', прежде чем импортировать lib.py как это: import sys sys.path.append('./') import lib

+0

Я использую пряжу, которая, кажется, не поддерживает -файлы, как выбранный ответ. Это отлично поработало, спасибо! – bkribbs

1

В -files и -archive переключатели просто ярлыки Hadoop в distributed cache (DC), более общий механизм, который также позволяет загружать и автоматически распаковывать архивы в форматах zip, tar и tgz/tar.gz. Если вместо одного модуля ваша библиотека реализуется структурированным пакетом Python, последняя функция - это то, что вы хотите.

Мы непосредственно поддерживать это в Pydoop начиная с версии 1.0.0-rc1, где вы можете просто построить mypkg.tgz архив и запустить программу как:

pydoop submit --upload-archive-to-cache mypkg.tgz [...] 

Соответствующие документы находятся на http://crs4.github.io/pydoop/self_contained.html и вот полный рабочий пример (требуется wheel): https://github.com/crs4/pydoop/tree/master/examples/self_contained.

Смежные вопросы