4

AWS Elastic MapReduce クラスターの Pig で Python UDF を利用したいのですが、うまく動作させることができません。何を試しても、豚のジョブは失敗し、次の例外がログに記録されます。

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

Elastic MapReduce で Pig 用の Python UDF を使用するには、何をする必要がありますか?

4

4 に答える 4

4

うーん...ここで読んだことのいくつかを明確にするために、この時点でs3に保存されたEMRで実行されているPigでPython UDFを使用すると、豚スクリプトの次の行と同じくらい簡単です:

jython を mynamespace として使用して REGISTER 's3://path/to/bucket/udfs.py'

つまり、クラスパスの変更は必要ありません。私は現在これを本番環境で使用していますが、udf に追加の python モジュールを取り込んでいないことに注意してください。それは、それを機能させるために何をする必要があるかに影響する可能性があると思います。

于 2012-12-12T20:49:11.847 に答える
2

かなりの数の間違いを犯した後、少なくとも Hadoop の Elastic Map Reduce 実装では、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-runtime-3.2.jar は、Hadoop が CharStream クラスを見つけられるようにします
  • Jython のキャッシュ ディレクトリを作成します (これはJython FAQ に記載されています) 。
    • sudo mkdir /usr/share/java/cachedir/
    • sudo chmod a+rw /usr/share/java/cachedir

これは、この問題の解決策を探しているときに見つけた他のアドバイスと直接矛盾しているように見えることを指摘しておく必要があります。

  • CLASSPATH および PIG_CLASSPATH 環境変数を設定しても、何も起こらないようです。
  • UDF を含む .py ファイルを HADOOP_CLASSPATH 環境変数に含める必要はありません。
  • Pig ステートメントで使用される .py ファイルへのパスは、register相対または絶対である可能性がありますが、問題ではないようです。
于 2012-02-15T23:42:06.963 に答える
0

私は最近同じ問題に直面しました。あなたの答えは単純化することができます。jythonをインストールしたり、キャッシュディレクトリを作成したりする必要はありません。jython jarをEMRブートストラップスクリプトに含める必要があります(または同様のことを行います)。次の行を使用してEMRブートストラップスクリプトを作成しました。s3cmdをまったく使用せずに、ジョブフロー(ファイルを特定のディレクトリに配置する)を使用することで、これをさらに単純化できます。s3cmdを介してUDFを取得することは間違いなく不便ですが、EMRバージョンのpigを使用している場合、s3にudfファイルを登録できませんでした。

CharStreamを使用している場合は、そのjarもpiglibパスに含める必要があります。使用するフレームワークに応じて、これらのブートストラップスクリプトをオプションとしてジョブに渡すことができます。EMRは、elastic-mapreducerubyクライアントを介してこれをサポートします。簡単なオプションは、ブートストラップスクリプトをs3に配置することです。

ブートストラップスクリプトでs3cmdを使用している場合は、このようなことを行う別のブートストラップスクリプトが必要です。このスクリプトは、ブートストラップ順に他のスクリプトの前に配置する必要があります。私はs3cmdの使用をやめていますが、うまくやってみると、s3cmdがうまくいきました。また、s3cmd実行可能ファイルはamazonのpigイメージにすでにインストールされています(例:amiバージョン2.0およびhadoopバージョン0.20.205)。

スクリプト#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

スクリプト#2(jython jarのシード)

#!/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
于 2012-02-17T17:16:02.340 に答える
0

今日の時点で、EMR で Pig 0.9.1 を使用すると、以下で十分であることがわかりました。

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

wherescript.pigは Python スクリプトを登録しますが、登録しませんjython.jar:

register Pig-UDFs/udfs.py using jython as mynamespace;
于 2012-04-05T19:03:14.617 に答える