我正在3个虚拟机中运行cloudera集群,并尝试通过map reduce作业执行hbase批量加载。但我总是犯错误:
error: Class org.apache.hadoop.hbase.mapreduce.HFileOutputFormat not found
所以,map进程似乎找不到类。所以我试了这个:
1) 将hbase.jar添加到每个节点上的hadoop\u类路径
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。也许这应该是hdfsjar?如果是,如何更改“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);
执行此操作后,错误消失,但出现另一个类not found异常:
java.lang.RuntimeException: java.lang.ClassNotFoundException: Class mypackage.bulkLoad.HBaseKVMapper not found
hbasekvmapper是我想要执行的自定义Map器类。因此,我尝试将其添加为“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不使用它来执行作业。为什么?
2条答案
按热度按时间2wnc66cl1#
我会尝试使用clouderamanager(免费版本),因为它可以为您解决这些问题。否则请注意以下事项:
您自己的类和hbase类hfileoutputformat都需要在本地和远程的类路径上可用。
提交作业
这意味着在驱动程序运行时在本地获得正确的类路径:
在服务器上
在hadoop-env.sh中
或使用
iecba09b2#
我发现了一个“黑客”的解决方案,对我来说很有效,但我不满意,因为它不是真正可行的。
我的“黑客”解决方案:
创建一个包含所有必需类文件的大jar,我称之为“big.jar”,并将其添加到本地(eclipse)类路径
添加行:job.setjarbyclass(mymapperclass.class)。。。mymapperclass必须在big.jar中
当我执行这个命令时,每个作业的big.jar都会被复制到文件系统中。再也没有错误了。问题是,jar的大小是80mb,每次都要复制。
如果有人知道更好的方法,如果他能告诉我怎么做,我会很高兴的。
编辑:
现在我尝试用apache pig执行作业,遇到了完全相同的问题。在这种情况下,我的黑客解决方案不起作用,因为Pig自动创造工作岗位。以下是清管器错误: