我是hadoop / java世界的新手,所以请保持温和,随时纠正错误的错误。 我正在尝试使用在本地运行Hadoop的ubuntu机器上编译的本机库(独立模式)。除了我编译的.jar之外,我还尝试使用外部.jar。我尝试使fatjar失败,并决定尝试通过命令行将外部jar和本机库传递给hadoop。这些库用于我创建的自定义记录阅读器中。我可以通过hadoop命令运行没有外部库的mapreduce作业。当我设置LD_LIBRARY_PATH类变量时,我也能够在eclipse中运行该程序。我不确定需要设置为在hadoop中成功运行此作业的变量,所以请告诉我是否有必要,尽管我已经尝试设置$ HADOOP_CLASSPATH。
即。
./bin/hadoop jar ~/myjar/cdf-11-16.jar CdfInputDriver -libjars cdfjava.jar -files libcdf.so,libcdfNativeLibrary.so input output
我尝试从本地访问jar等文件并将它们复制到HDFS。
我从工作中得到以下错误:
Exception in thread "main" java.lang.NoClassDefFoundError: gsfc/nssdc/cdf/CDFConstants
at java.lang.ClassLoader.defineClass1(Native Method)
at java.lang.ClassLoader.defineClass(ClassLoader.java:800)
at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:142)
at java.net.URLClassLoader.defineClass(URLClassLoader.java:449)
at java.net.URLClassLoader.access$100(URLClassLoader.java:71)
at java.net.URLClassLoader$1.run(URLClassLoader.java:361)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:274)
at org.apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.java:1844)
at org.apache.hadoop.conf.Configuration.getClassByName(Configuration.java:1809)
at org.apache.hadoop.conf.Configuration.getClass(Configuration.java:1903)
at org.apache.hadoop.mapreduce.task.JobContextImpl.getInputFormatClass(JobContextImpl.java:174)
at org.apache.hadoop.mapreduce.JobSubmitter.writeNewSplits(JobSubmitter.java:490)
at org.apache.hadoop.mapreduce.JobSubmitter.writeSplits(JobSubmitter.java:510)
at org.apache.hadoop.mapreduce.JobSubmitter.submitJobInternal(JobSubmitter.java:394)
at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1285)
at org.apache.hadoop.mapreduce.Job$10.run(Job.java:1282)
at java.security.AccessController.doPrivileged(Native Method)
at javax.security.auth.Subject.doAs(Subject.java:415)
at org.apache.hadoop.security.UserGroupInformation.doAs(UserGroupInformation.java:1614)
at org.apache.hadoop.mapreduce.Job.submit(Job.java:1282)
at org.apache.hadoop.mapreduce.Job.waitForCompletion(Job.java:1303)
at CdfInputDriver.run(CdfInputDriver.java:45)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:70)
at org.apache.hadoop.util.ToolRunner.run(ToolRunner.java:84)
at CdfInputDriver.main(CdfInputDriver.java:50)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at org.apache.hadoop.util.RunJar.main(RunJar.java:212)
Caused by: java.lang.ClassNotFoundException: gsfc.nssdc.cdf.CDFConstants
at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
... 36 more
我已经尝试查看文件是否使用以下代码加载到缓存中,并且“缓存文件:”打印为null:
public class CdfInputDriver extends Configured implements Tool{
@Override
public int run(String[] args) throws Exception {
Job job = Job.getInstance(getConf());
System.out.println("cache files:" + getConf().get("mapreduce.job.cache.files"));
Path[] uris = job.getLocalCacheFiles();
for(Path uri: uris){
System.out.println(uri.toString());
System.out.println(uri.getName());
}
job.setJarByClass(getClass());
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(LongWritable.class);
job.setInputFormatClass(CdfInputFormat.class);
job.setOutputFormatClass(TextOutputFormat.class);
FileInputFormat.setInputPaths(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setMapperClass(CdfMapper.class);
//job.setReducerClass(WordCount.IntSumReducer.class);
return job.waitForCompletion(true) ? 0 : 1;
}
public static void main(String[] args) throws Exception,
InterruptedException, ClassNotFoundException {
int exitCode = ToolRunner.run(new CdfInputDriver(), args);
System.exit(exitCode);
}
}
另外,我只是测试它,以便在Amazon EMR上不可避免地运行这项工作。将.so和.jar存储在S3上并使用类似的方法理论上可以工作吗?
感谢任何帮助!
答案 0 :(得分:0)
我认为这对于有这个问题的人来说是这样的。对于我的场景,这是一系列问题。
./bin/hadoop jar ~/myjar/cdf-11-16.jar CdfInputDriver -libjars cdfjava.jar -files libcdf.so,libcdfNativeLibrary.so input output
有几件事让我陷入困境。这是我检查的一些事情。如果有人知道为什么这些有助于它的工作,我们将不胜感激。
(对于linux新手)如果你使用sudo运行hadoop,请确保包含-E以包含环境变量。
确保第三方.jar库位于您的masternode上。 (似乎是必要的,但没有用文件确认......也许我的环境变量不正确,否则)
我能够使用Amazon EMR运行它。我将.so文件和.jars上传到s3,ssh进入群集的主节点,通过http://blog.adaptovate.com/2013/06/installing-s3cmd-on-ec2-so-that-yum.html安装了s3cmd,复制了cdf-11-16.jar(mapreduce jar)和cdfjava.jar(第三方) jar)用s3cmd get到masternode,然后运行这个工作。我能够在S3上引用.so文件。