2014-11-16 1 views
0

저는 hadoop/java 세계를 처음 사용하기 때문에 심각한 오류를 바로 잡으십시오. Hadoop을 로컬로 실행하는 우분투 컴퓨터에서 컴파일 된 네이티브 라이브러리를 사용하려고합니다 (독립 실행 형 모드). 또한 컴파일 한 .jar 외에도 외부 .jar를 사용하려고합니다. fatjar을 성공적으로 만들지 못했지만 명령 줄을 통해 외부 항아리와 기본 라이브러리를 hadoop에 전달하려고했습니다. 라이브러리는 내가 만든 사용자 정의 레코드 판독기에서 사용됩니다. hadoop 명령을 통해 외부 라이브러리없이 mapreduce 작업을 실행할 수 있습니다. 나는 또한 LD_LIBRARY_PATH 클래스 변수를 설정할 때 이클립스에서이 프로그램을 실행할 수있다. 내가 hadoop에서이 작업을 성공적으로 수행하도록 설정해야 할 변수가 확실하지 않으므로 필요한 경우 몇 가지 사항을 알려주십시오. $ HADOOP_CLASSPATH를 설정하려고했지만 말하십시오.Hadoop MapReduce와 외부 네이티브 라이브러리 (.so) 및 외부 jar를 사용하십시오.

./bin/hadoop jar ~/myjar/cdf-11-16.jar CdfInputDriver -libjars cdfjava.jar -files libcdf.so,libcdfNativeLibrary.so input output 

나는 단지 내 지역에서 이렇게 파일에 액세스하고 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에서 작업을 실행하도록 테스트하고 있습니다. S3에 .so와 .jar를 저장하고 비슷한 방법을 사용하면 이론적으로 작동합니까?

감사합니다.

답변

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 라이브러리가 마스터 노드에 있는지 확인하십시오. (필요한 것 같지만 문서로 확인하지 않은 것 같습니다 ... 그렇지 않으면 내 환경 변수가 잘못되었을 수 있습니다.)

아마존 EMR을 사용하여 실행할 수있었습니다. .so 파일과 .jars를 s3에 업로드하고, 클러스터의 마스터 노드에 ssh'd, http://blog.adaptovate.com/2013/06/installing-s3cmd-on-ec2-so-that-yum.html을 통해 s3cmd를 설치하고, cdf-11-16.jar (mapreduce jar) 및 cdfjava.jar (third party jar)를 s3cmd를 가진 masternode는 얻고, 직업을 달렸다. S3에서 .so 파일을 참조 할 수있었습니다.

관련 문제