我正在3个虚拟机中运行cloudera集群,并尝试通过map reduce作业执行hbase批量加载。但我总是得到错误:
error: Class org.apache.hadoop.hbase.mapreduce.HFileOutputFormat not found
因此,似乎地图流程找不到类。所以我尝试了这个:
1)将hbase.jar添加到每个节点上的HADOOP_CLASSPATH
2)将TableMapReduceUtil.addDependencyJars(job)/ 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系统上的本地罐子。也许这应该是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是我想要执行的自定义Mapper类。所以,我试图用“job.setJarByClass(HBaseKVMapper.class)”添加它,但它不起作用,因为它只有一个类文件而且没有jar。所以我生成了一个包含HBaseKVMapper.class的Jarfile。之后,我再次执行它,现在又找到了HFileOutputFormat.class未找到的异常。
稍微调试之后,我发现setJarByClass Methode只将本地jar文件复制到HDFS上的.staging / job_#number / job.jar。因此,这个setJarByClass()方法只适用于一个jar文件,因为它在用另一个jar再次执行setJarByClass()之后会覆盖job.jar。
在寻找eroor的过程中,我在工作中找到了以下结构:
在libjars direcotry中我看到了相关的jar文件
所以,hbase jar在libjars目录中,但是jobtracker不使用它来执行作业。为什么呢?
答案 0 :(得分:1)
我会尝试使用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
答案 1 :(得分:0)
我找到了一个适用于我的“黑客”解决方案,但我对此并不满意,因为它并不是真的可行。
我的“黑客”解决方案:
当我执行此操作时,big.jar将被复制为每个作业到文件系统。没有错误了。问题是,罐子的大小是80mb,每次都要复制。
如果有人知道一个更好的方法,如果他能告诉我如何,我会感到尴尬。
编辑:
现在我尝试使用Apache Pig执行作业并遇到完全相同的问题。在这种情况下,我被黑的灵魂不起作用,因为猪自动创造了工作。这是猪的错误:
java.lang.ClassNotFoundException: Class org.apache.hadoop.hbase.mapreduce.TableSplit not found