Apache Hadoop:map reduce作业中的类路径错误

Apache Hadoop:map reduce作业中的类路径错误,apache,hadoop,mapreduce,hbase,cloudera,Apache,Hadoop,Mapreduce,Hbase,Cloudera,我正在3台虚拟机中运行cloudera群集,并尝试通过map reduce作业执行hbase批量加载。但我总是犯错误: error: Class org.apache.hadoop.hbase.mapreduce.HFileOutputFormat not found 因此,map进程似乎找不到类。所以我试了一下: 1) 将hbase.jar添加到每个节点上的HADOOP_类路径 2) 将TableMapReduceUtil.addDependencyJars(作业)/TableMapRedu

我正在3台虚拟机中运行cloudera群集,并尝试通过map reduce作业执行hbase批量加载。但我总是犯错误:

error: Class org.apache.hadoop.hbase.mapreduce.HFileOutputFormat not found
因此,map进程似乎找不到类。所以我试了一下:

1) 将hbase.jar添加到每个节点上的HADOOP_类路径

2) 将TableMapReduceUtil.addDependencyJars(作业)/TableMapReduceUtil.addDependencyJars(myConf,HFileOutputFormat.class)添加到源代码中

什么都没用。我完全不知道为什么找不到这个类,因为jar/类在类路径中肯定是可用的

如果查看job.xml,我会看到以下条目:

name=tmpjars    value=file:/C:/Users/Thomas/.m2/repository/org/apache/zookeeper/zookeeper/3.4.5-cdh4.3.0/zookeeper-3.4.5-cdh4.3.0.jar,file:/C:/Users/Thomas/.m2/repository/org/apache/hbase/hbase/0.94.6-cdh4.3.0/hbase-0.94.6-cdh4.3.0.jar,file:/C:/Users/Thomas/.m2/repository/org/apache/hadoop/hadoop-core/2.0.0-mr1-cdh4.3.0/hadoop-core-2.0.0-mr1-cdh4.3.0.jar,file:/C:/Users/Thomas/.m2/repository/com/google/guava/guava/11.0.2/guava-11.0.2.jar,file:/C:/Users/Thomas/.m2/repository/com/google/protobuf/protobuf-java/2.4.0a/protobuf-java-2.4.0a.jar
这对我来说似乎有点奇怪,这些是我在windows系统上的本地JAR。也许这应该是hdfs罐子?如果是,如何更改“tmpjars”的值

以下是我尝试执行的java代码:

        configuration = new Configuration(false);
        configuration.set("mapred.job.tracker", "192.168.2.41:8021");
        configuration.set("fs.defaultFS", "hdfs://192.168.2.41:8020/");
        configuration.set("hbase.zookeeper.quorum", "192.168.2.41");
        configuration.set("hbase.zookeeper.property.clientPort", "2181");

        Job job = new Job(configuration, "HBase Bulk Import for "
                + tablename);
        job.setJarByClass(HBaseKVMapper.class);

        job.setMapperClass(HBaseKVMapper.class);
        job.setMapOutputKeyClass(ImmutableBytesWritable.class);
        job.setMapOutputValueClass(KeyValue.class);
        job.setOutputFormatClass(HFileOutputFormat.class);
        job.setPartitionerClass(TotalOrderPartitioner.class);
        job.setInputFormatClass(TextInputFormat.class);
        HFileOutputFormat.configureIncrementalLoad(job, hTable);

        FileInputFormat.addInputPath(job, new Path("myfile1"));
        FileOutputFormat.setOutputPath(job, new Path("myfile2"));

        job.waitForCompletion(true);

        LoadIncrementalHFiles loader = new LoadIncrementalHFiles(
                configuration);
        loader.doBulkLoad(new Path("myFile3"), hTable);
编辑:

我又试了一点,感觉很奇怪。我在java代码中添加了以下行:

job.setJarByClass(HFileOutputFormat.class);
执行此操作后,错误消失,但出现另一个未找到的类异常:

java.lang.RuntimeException: java.lang.ClassNotFoundException: Class mypackage.bulkLoad.HBaseKVMapper not found
HBaseKVMapper是我想要执行的自定义映射器类。因此,我尝试用“job.setJarByClass(HBaseKVMapper.class)”添加它,但它不起作用,因为它只是一个类文件,没有jar。因此,我生成了一个包含HBaseKVMapper.class的jar文件。在那之后,我再次执行它,现在又得到了HFileOutputFormat.class not found异常

调试一点之后,我发现setJarByClass方法只将本地jar文件复制到HDFS上的.staging/job#number/job.jar。因此,这个setJarByClass()方法只适用于一个jar文件,因为它在用另一个jar再次执行setJarByClass()后会覆盖job.jar

在搜索eRoom时,我在job staging目录中看到以下结构:

在libjars目录中,我看到了相关的jar文件

因此,hbase jar位于libjars目录中,但是jobtracker不使用它来执行作业。为什么?

我发现了一个“黑客”解决方案,它对我很有效,但我不满意,因为它实际上不可行

我的“黑客”解决方案:

  • 创建一个包含所有必要类文件的大Jar,我称之为“big.Jar”,并将其添加到本地(eclipse)类路径中
  • 添加行:job.setJarByClass(MyMapperClass.class)。。。MyMapperClass必须在big.jar中
  • 当我执行这个命令时,每个作业的big.jar都会被复制到文件系统中。没有错误了。问题是,jar的大小是80mb,每次都必须复制

    如果有人知道更好的方法,如果他能告诉我怎么做,我会很高兴

    编辑:

    现在我尝试使用ApachePig执行作业,但遇到了完全相同的问题。我的黑客软件在这种情况下不起作用,因为猪会自动创造工作。以下是清管器错误:

    java.lang.ClassNotFoundException: Class org.apache.hadoop.hbase.mapreduce.TableSplit not found
    

    我会尝试使用Cloudera Manager(免费版),因为它可以为您解决这些问题。否则,请注意以下事项:

    您自己的类和HBase类HFileOutputFormat都需要在本地和远程的类路径上可用

    提交作业

    这意味着在驱动程序运行时在本地获得正确的类路径:

    $ env HADOOP_CLASSPATH=$(hbase classpath) hadoop jar path/to/jar class....
    
    在服务器上

    在hadoop-env.sh中

    export HADOOP_CLASSPATH=$(hbase claspath)
    
    或使用

    TableMapReduceUtil.addDependencyJars
    

    尝试删除以下行:
    configuration.set(“mapred.job.tracker”,“192.168.2.41:8021”)configuration.set(“fs.default.name”hdfs://192.168.2.41:8020/");
    指定它是dfs群集。“设置haddop客户端”=在类路径中创建core-site.xml/hbase-site.xml?如果是的,我以前也这么做过,但我也犯了同样的错误如果你删除我说的那行,你会有任何错误吗?我的评论太长了,请看上面我的回答