如何在elastic mapreduce中将python udfs与pig结合使用?

nukf8bse  于 2021-06-21  发布在  Pig
关注(0)|答案(4)|浏览(374)

我真的很想在我们的aws弹性mapreduce集群上利用pig中的python udfs,但是我不能让事情正常工作。无论我尝试什么,我的pig作业都会失败,并记录以下异常:

  1. ERROR 2998: Unhandled internal error. org/python/core/PyException
  2. java.lang.NoClassDefFoundError: org/python/core/PyException
  3. at org.apache.pig.scripting.jython.JythonScriptEngine.registerFunctions(JythonScriptEngine.java:127)
  4. at org.apache.pig.PigServer.registerCode(PigServer.java:568)
  5. at org.apache.pig.tools.grunt.GruntParser.processRegister(GruntParser.java:421)
  6. at org.apache.pig.tools.pigscript.parser.PigScriptParser.parse(PigScriptParser.java:419)
  7. at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.java:188)
  8. at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.java:164)
  9. at org.apache.pig.tools.grunt.Grunt.exec(Grunt.java:81)
  10. at org.apache.pig.Main.run(Main.java:437)
  11. at org.apache.pig.Main.main(Main.java:111)
  12. at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
  13. at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
  14. at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
  15. at java.lang.reflect.Method.invoke(Method.java:597)
  16. at org.apache.hadoop.util.RunJar.main(RunJar.java:156) Caused by: java.lang.ClassNotFoundException: org.python.core.PyException
  17. at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
  18. at java.security.AccessController.doPrivileged(Native Method)
  19. at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
  20. at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
  21. at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
  22. ... 14 more

在elastic mapreduce中使用python UDF for pig需要做什么?

qlvxas9a

qlvxas9a1#

到今天为止,在emr上使用pig 0.9.1,我发现以下内容已经足够了:

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

哪里 script.pig 做一个python脚本的寄存器,但不是 jython.jar :

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

zyfwsgd62#

经过几次错误的转变,我发现,至少在hadoop的弹性map reduce实现上,pig似乎忽略了classpath环境变量。相反,我发现我可以使用hadoop\u classpath变量来控制类路径。
一旦我实现了这一点,就可以很容易地设置使用python UDF的内容:
安装jython sudo apt-get install jython -y -qq 设置hadoop\u classpath环境变量。 export HADOOP_CLASSPATH=/usr/share/java/jython.jar:/usr/share/maven-repo/org/antlr/antlr-runtime/3.2/antlr-runtime-3.2.jar jar确保hadoop可以找到pyexception类
antlr-runtime-3.2.jar确保hadoop可以找到charstream类
为jython创建缓存目录(这在jythonfaq中有文档记录)
sudo mkdir /usr/share/java/cachedir/ sudo chmod a+rw /usr/share/java/cachedir 我应该指出,这似乎与我在寻找解决这个问题的方法时发现的其他建议直接矛盾:
设置classpath和classpath环境变量似乎没有任何作用。
包含udf的.py文件不需要包含在hadoop\u classpath环境变量中。
pig中使用的.py文件的路径 register 陈述可以是相对的,也可以是绝对的,似乎并不重要。

i7uaboj4

i7uaboj43#

嗯…为了澄清我刚才读到的一些内容,在这里使用python-udf-in-pig在存储在s3上的emr上运行,它就像pig脚本中的这行代码一样简单:
使用jython作为mynamespace注册“s3://path/to/bucket/udfs.py”
也就是说,不需要修改类路径。我现在正在生产中使用它,不过需要注意的是,我没有在我的udf中引入任何额外的python模块。我认为这可能会影响到你需要做些什么来让它发挥作用。

ztmd8pv5

ztmd8pv54#

我最近也遇到了同样的问题。你的答案可以简化。您根本不需要安装jython或创建缓存目录。您确实需要在emr引导脚本中包含jythonjar(或者做类似的事情)。我用下面几行代码编写了一个emr引导脚本。通过完全不使用s3cmd,而是使用作业流(将文件放在特定目录中),可以进一步简化这一点。通过s3cmd获取udf肯定是不方便的,但是,当使用pig的emr版本时,我无法在s3上注册udf文件。
如果您使用的是charstream,那么必须将该jar也包含到piglib路径中。根据您使用的框架,您可以将这些引导脚本作为选项传递给您的作业,emr通过其elasticmapreduceruby客户端支持这一点。一个简单的选择是将引导脚本放在s3上。
如果在引导脚本中使用s3cmd,则需要另一个执行类似操作的引导脚本。此脚本应按引导顺序放在另一个脚本之前。我正在远离使用s3cmd,但是为了我的成功尝试,s3cmd成功了。而且,s3cmd可执行文件已经安装在亚马逊的pig映像中(例如ami版本2.0和hadoop版本0.20.205)。
脚本#1(命令行)

  1. # !/bin/bash
  2. cat <<-OUTPUT > /home/hadoop/.s3cfg
  3. [default]
  4. access_key = YOUR KEY
  5. bucket_location = US
  6. cloudfront_host = cloudfront.amazonaws.com
  7. cloudfront_resource = /2010-07-15/distribution
  8. default_mime_type = binary/octet-stream
  9. delete_removed = False
  10. dry_run = False
  11. encoding = UTF-8
  12. encrypt = False
  13. follow_symlinks = False
  14. force = False
  15. get_continue = False
  16. gpg_command = /usr/local/bin/gpg
  17. gpg_decrypt = %(gpg_command)s -d --verbose --no-use-agent --batch --yes --passphrase-fd % (passphrase_fd)s -o %(output_file)s %(input_file)s
  18. gpg_encrypt = %(gpg_command)s -c --verbose --no-use-agent --batch --yes --passphrase-fd %(passphrase_fd)s -o %(output_file)s %(input_file)s
  19. gpg_passphrase = YOUR PASSPHRASE
  20. guess_mime_type = True
  21. host_base = s3.amazonaws.com
  22. host_bucket = %(bucket)s.s3.amazonaws.com
  23. human_readable_sizes = False
  24. list_md5 = False
  25. log_target_prefix =
  26. preserve_attrs = True
  27. progress_meter = True
  28. proxy_host =
  29. proxy_port = 0
  30. recursive = False
  31. recv_chunk = 4096
  32. reduced_redundancy = False
  33. secret_key = YOUR SECRET
  34. send_chunk = 4096
  35. simpledb_host = sdb.amazonaws.com
  36. skip_existing = False
  37. socket_timeout = 10
  38. urlencoding_mode = normal
  39. use_https = False
  40. verbosity = WARNING
  41. OUTPUT

脚本#2(播种jythonjar)

  1. # !/bin/bash
  2. set -e
  3. s3cmd get <jython.jar>
  4. # Very useful for extra libraries not available in the jython jar. I got these libraries from the
  5. # jython site and created a jar archive.
  6. s3cmd get <jython_extra_libs.jar>
  7. s3cmd get <UDF>
  8. PIG_LIB_PATH=/home/hadoop/piglibs
  9. mkdir -p $PIG_LIB_PATH
  10. mv <jython.jar> $PIG_LIB_PATH
  11. mv <jython_extra_libs.jar> $PIG_LIB_PATH
  12. mv <UDF> $PIG_LIB_PATH
  13. # Change hadoop classpath as well.
  14. echo "HADOOP_CLASSPATH=$PIG_LIB_PATH/<jython.jar>:$PIG_LIB_PATH/<jython_extra_libs.jar>" >> /home/hadoop/conf/hadoop-user-env.sh
展开查看全部

相关问题