2012-02-15 2 views
4

Я действительно хочу использовать UDF Python в Pig на нашем AWS Elastic MapReduce кластере, но я не могу заставить все нормально работать. Независимо от того, что я стараюсь, моя свинья работа не терпит неудачу за исключением следующего после входа:Как вы используете Python UDF с Pig в Elastic MapReduce?

ERROR 2998: Unhandled internal error. org/python/core/PyException 

java.lang.NoClassDefFoundError: org/python/core/PyException 
     at org.apache.pig.scripting.jython.JythonScriptEngine.registerFunctions(JythonScriptEngine.java:127) 
     at org.apache.pig.PigServer.registerCode(PigServer.java:568) 
     at org.apache.pig.tools.grunt.GruntParser.processRegister(GruntParser.java:421) 
     at org.apache.pig.tools.pigscript.parser.PigScriptParser.parse(PigScriptParser.java:419) 
     at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.java:188) 
     at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.java:164) 
     at org.apache.pig.tools.grunt.Grunt.exec(Grunt.java:81) 
     at org.apache.pig.Main.run(Main.java:437) 
     at org.apache.pig.Main.main(Main.java:111) 
     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) 
     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 
     at java.lang.reflect.Method.invoke(Method.java:597) 
     at org.apache.hadoop.util.RunJar.main(RunJar.java:156) Caused by: java.lang.ClassNotFoundException: org.python.core.PyException 
     at java.net.URLClassLoader$1.run(URLClassLoader.java:202) 
     at java.security.AccessController.doPrivileged(Native Method) 
     at java.net.URLClassLoader.findClass(URLClassLoader.java:190) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:306) 
     at java.lang.ClassLoader.loadClass(ClassLoader.java:247) 
     ... 14 more 

Что вам нужно сделать, чтобы использовать Python UDF, для Свиньи в Elastic MapReduce?

ответ

2

После нескольких неправильных поворотов я обнаружил, что, по крайней мере, на эластичной карте уменьшает реализацию Hadoop, Pig, похоже, игнорирует переменную среды CLASSPATH. Вместо этого я обнаружил, что я мог бы контролировать путь класса, используя вместо этого переменную HADOOP_CLASSPATH.

После того, как я сделал, что реализация, это было довольно легко получить настройки вещи, чтобы использовать Python UDFS:

  • Установите Jython
    • sudo apt-get install jython -y -qq
  • Установить переменную HADOOP_CLASSPATH среды.
    • export HADOOP_CLASSPATH=/usr/share/java/jython.jar:/usr/share/maven-repo/org/antlr/antlr-runtime/3.2/antlr-runtime-3.2.jar
      • jython.jar гарантирует, что Hadoop может найти класс PyException
      • ANTLR-среда-3.2.jar гарантирует, что Hadoop может найти класс поток символов
  • Создать кэш каталог для Jython (это documented in the Jython FAQ)
    • sudo mkdir /usr/share/java/cachedir/
    • sudo chmod a+rw /usr/share/java/cachedir

Я должен отметить, что это, кажется, прямо противоречат другой совет я нашел в поисках решения этой проблемы:

  • Установка CLASSPATH и PIG_CLASSPATH переменные окружения не похоже, что-то делают.
  • Файл .py, содержащий UDF, не обязательно должен быть включен в переменную среды HADOOP_CLASSPATH.
  • Путь к файлу .py, используемому в инструкции Pig register, может быть относительным или абсолютным, это, похоже, не имеет значения.
0

Я столкнулся с той же проблемой в последнее время. Ваш ответ можно упростить. Вам вообще не нужно устанавливать jython или создавать каталог кеша. Вам нужно включить jython jar в сценарий начальной загрузки EMR (или сделать что-то подобное). Я написал сценарий начальной загрузки EMR со следующими строками. Это можно упростить, даже не используя s3cmd, но используя ваш поток заданий (чтобы поместить файлы в определенный каталог). Получение UDF через s3cmd определенно неудобно, однако мне не удалось зарегистрировать файл udf на s3 при использовании версии EMR свиньи.

Если вы используете CharStream, вы должны включить эту банку также в путь piglib.В зависимости от используемой структуры вы можете передать эти сценарии начальной загрузки в качестве параметров вашей работы, EMR поддерживает это посредством своего рубинового клиента с эластичным mapreduce. Простой вариант - разместить сценарии начальной загрузки на s3.

Если вы используете s3cmd в сценарии начальной загрузки, вам нужен другой скрипт начальной загрузки, который делает что-то вроде этого. Этот сценарий должен быть размещен перед другим в порядке начальной загрузки. Я отхожу от использования s3cmd, но для моей успешной попытки s3cmd сделал трюк. Кроме того, s3cmd исполняемым уже установлен в образе свиньи для амазонки (например, AMI версии 2.0 и Hadoop версии 0.20.205.

Script # 1 (Посев s3cmd)

#!/bin/bash 
cat <<-OUTPUT > /home/hadoop/.s3cfg 
[default] 
access_key = YOUR KEY 
bucket_location = US 
cloudfront_host = cloudfront.amazonaws.com 
cloudfront_resource = /2010-07-15/distribution 
default_mime_type = binary/octet-stream 
delete_removed = False 
dry_run = False 
encoding = UTF-8 
encrypt = False 
follow_symlinks = False 
force = False 
get_continue = False 
gpg_command = /usr/local/bin/gpg 
gpg_decrypt = %(gpg_command)s -d --verbose --no-use-agent --batch --yes --passphrase-fd % (passphrase_fd)s -o %(output_file)s %(input_file)s 
gpg_encrypt = %(gpg_command)s -c --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s 
gpg_passphrase = YOUR PASSPHRASE 
guess_mime_type = True 
host_base = s3.amazonaws.com 
host_bucket = %(bucket)s.s3.amazonaws.com 
human_readable_sizes = False 
list_md5 = False 
log_target_prefix = 
preserve_attrs = True 
progress_meter = True 
proxy_host = 
proxy_port = 0 
recursive = False 
recv_chunk = 4096 
reduced_redundancy = False 
secret_key = YOUR SECRET 
send_chunk = 4096 
simpledb_host = sdb.amazonaws.com 
skip_existing = False 
socket_timeout = 10 
urlencoding_mode = normal 
use_https = False 
verbosity = WARNING 
OUTPUT 

Script # 2 (высева Jython банки)

#!/bin/bash 
set -e 

s3cmd get <jython.jar> 
# Very useful for extra libraries not available in the jython jar. I got these libraries from the 
# jython site and created a jar archive. 
s3cmd get <jython_extra_libs.jar> 
s3cmd get <UDF> 

PIG_LIB_PATH=/home/hadoop/piglibs 

mkdir -p $PIG_LIB_PATH 

mv <jython.jar> $PIG_LIB_PATH 
mv <jython_extra_libs.jar> $PIG_LIB_PATH 
mv <UDF> $PIG_LIB_PATH 

# Change hadoop classpath as well. 
echo "HADOOP_CLASSPATH=$PIG_LIB_PATH/<jython.jar>:$PIG_LIB_PATH/<jython_extra_libs.jar>" >> /home/hadoop/conf/hadoop-user-env.sh 
0

на сегодняшний день, используя Свинью 0.9.1 на ОМ, я обнаружил следующее достаточно:

env HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/path/to/jython.jar pig -f script.pig 

где script.pig делает регистр сценария Python, но не jython.jar:

register Pig-UDFs/udfs.py using jython as mynamespace; 
4

Хм ... прояснить некоторые, что я только что прочитал здесь, в этом месте с помощью питона UDF в Pig работает на ОМ, хранящееся на s3, это столь же просто, как и строки в вашем скрипте свинки:

REGISTER «s3: //path/to/bucket/udfs.py» с помощью Jython, как mynamespace

то есть, нет необходимости изменения пути к классам. Я использую это в производстве прямо сейчас, хотя с предостережением, что я не занимаюсь дополнительными модулями python в моем udf. Я думаю, что это может повлиять на то, что вам нужно сделать, чтобы он работал.

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

  • Нет связанных вопросов^_^