Hadoop 使用java.lang.NoClassDefFoundError在AWS EMR上运行Pig UDF:org/apache/Pig/LoadFunc

Hadoop 使用java.lang.NoClassDefFoundError在AWS EMR上运行Pig UDF:org/apache/Pig/LoadFunc,hadoop,amazon-web-services,apache-pig,amazon-emr,Hadoop,Amazon Web Services,Apache Pig,Amazon Emr,我正在开发一个应用程序,尝试读取存储在S3 bucks中的日志文件,并使用Elastic MapReduce解析它。当前日志文件的格式如下 ------------------------------- COLOR=Black Date=1349719200 PID=23898 Program=Java EOE ------------------------------- COLOR=White Date=1349719234 PID=23828 Program=Pytho

我正在开发一个应用程序,尝试读取存储在S3 bucks中的日志文件,并使用Elastic MapReduce解析它。当前日志文件的格式如下

------------------------------- 
COLOR=Black 
Date=1349719200 
PID=23898 
Program=Java 
EOE 
------------------------------- 
COLOR=White 
Date=1349719234 
PID=23828 
Program=Python 
EOE 
因此,我尝试将文件加载到我的Pig脚本中,但内置的Pig加载程序似乎无法加载我的数据,因此我必须创建自己的UDF。因为我对Pig和Hadoop还不太熟悉,所以我想在编写自己的脚本之前尝试一下其他人编写的脚本,只是想了解一下UDF是如何工作的。我在这里找到了一个,有一个SimpleTextLoader。为了编译这个SimpleTextLoader,我必须添加一些导入,如下所示

import java.io.IOException; 
import java.util.ArrayList;
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 
import org.apache.hadoop.mapreduce.InputFormat; 
import org.apache.hadoop.mapreduce.RecordReader; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
import org.apache.pig.backend.hadoop.executionengine.mapReduceLayer.PigSplit; 
import org.apache.pig.backend.executionengine.ExecException; 
import org.apache.pig.data.Tuple; 
import org.apache.pig.data.TupleFactory;
import org.apache.pig.data.DataByteArray; 
import org.apache.pig.PigException; 
import org.apache.pig.LoadFunc;
然后,我发现我需要编译这个文件。我必须下载svn和pig running

sudo apt-get install subversion 
svn co http://svn.apache.org/repos/asf/pig/trunk 
ant
现在我有了一个pig.jar文件,然后我尝试编译这个文件

javac -cp ./trunk/pig.jar SimpleTextLoader.java 
jar -cf SimpleTextLoader.jar SimpleTextLoader.class 
它编译成功,我输入了grunt,在grunt中我尝试加载文件,使用

grunt> register file:/home/hadoop/myudfs.jar
grunt> raw = LOAD 's3://mys3bucket/samplelogs/applog.log' USING myudfs.SimpleTextLoader('=') AS (key:chararray, value:chararray); 

2012-12-05 00:08:26,737 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 2998: Unhandled internal error. org/apache/pig/LoadFunc Details at logfile: /home/hadoop/pig_1354666051892.log
在pig_1354666051892.log内,它具有

Pig Stack Trace
---------------
ERROR 2998: Unhandled internal error. org/apache/pig/LoadFunc

java.lang.NoClassDefFoundError: org/apache/pig/LoadFunc
我还尝试使用来自的另一个UDF(UPPER.java),但尝试使用UPPER方法仍然会得到相同的错误。你能帮帮我吗?这里有什么问题吗?非常感谢


更新:我在/home/hadoop/lib/Pig/Pig.jar中尝试了在Pig.jar中构建EMR,但也遇到了同样的问题。

将UDF jar放在/home/hadoop/lib/Pig目录中,或者将Pig-*-amzn.jar文件复制到/home/hadoop/lib中,它就会工作


您可能会使用引导操作来执行这两个操作。

大多数Hadoop生态系统工具(如pig和hive)都会查找$Hadoop_HOME/conf/Hadoop-env.sh以查找环境变量

我通过向HADOOP_类路径添加pig-0.13.0-h1.jar(它包含UDF所需的所有类)来解决这个问题:

export HADOOP_CLASSPATH=/home/hadoop/pig-0.13.0/pig-0.13.0-h1.jar:$HADOOP_CLASSPATH

pig-0.13.0-h1.jar在pig-home目录中可用。

为什么不在EMR中使用内置的pig支持?是的,我在/home/hadoop/lib/pig/pig.jar中使用了内置的pig,但仍然得到相同的错误。我还专门在脚本中注册了这个pig.jar文件。但是仍然会出现同样的错误,只需将本地开发的Pig脚本放在S3中,就可以将其提供给EMR。所有的配置和引导都由AWS为您负责。我是在交互模式下运行的。EMR最好以规模运行。我建议您在机器上以本地模式开发脚本,并且只将最终脚本部署到EMR。无论如何,请注意,您可以在EMR集群中使用多个版本的Hadoop。可能您没有选择所需的正确版本。