前言
当我们实现了一个Hadoop MapReduce Job以后,而这个Job可能又依赖很多外部的jar文件,在Hadoop集群上运行时,有时会出现找不到具体Class的异常。出现这种问题,基本上就是在Hadoop Job执行过程中,没有从执行的上下文中找到对应的jar文件(实际是unjar的目录,目录里面是对应的Class文件)。所以,我们自然而然想到,正确配置好对应的classpath,MapReduce Job运行时就能够找到。有两种方式可以更好地实现,一种是设置HADOOP_CLASSPATH,将Job所依赖的jar文件加载到HADOOP_CLASSPATH,这种配置只针对该Job生效,Job结束之后HADOOP_CLASSPATH会被清理;另一种方式是,直接在构建代码的时候,将依赖jar文件与Job代码打成一个jar文件,这种方式可能会使得最终的jar文件比较大,但是结合一些代码构建工具,如Maven,可以在依赖控制方面保持一个Job一个依赖的构建配置,便于管理。下面,我们分别说明这两种方式。
![62f68e57a93d8e140c33b9e5e1274d0a.png](https://i-blog.csdnimg.cn/blog_migrate/c1771699180cf6fa2794a6ed58f39519.jpeg)
设置HADOOP_CLASSPATH
比如,我们有一个使用HBase的应用,操作HBase数据库中表,肯定需要ZooKeeper,所以对应的jar文件的位置都要设置正确,让运行时Job能够检索并加载。Hadoop实现里面,有个辅助工具类org.apache.hadoop.util.GenericOptionsParser,能够帮助我们加载对应的文件到classpath中,操作比较容易一些。下面我们是我们实现的一个例子,程序执行入口的类,代码如下所示:
package org.shirdrn.kodz.inaction.hbase.job.importing; import java.io.IOException;import java.net.URISyntaxException; import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.Path;import org.apache.hadoop.hbase.HBaseConfiguration;import org.apache.hadoop.hbase.client.Put;import org.apache.hadoop.hbase.io.ImmutableBytesWritable;import org.apache.hadoop.hbase.mapreduce.TableOutputFormat;import org.apache.hadoop.mapreduce.Job;import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;import org.apache.hadoop.util.GenericOptionsParser; /*** Table DDL: create 't_sub_domains', 'cf_basic', 'cf_status'*
* cf_basic:domain cf_basic:len* cf_status:status cf_status:live*
** @author shirdrn*/public class DataImporter { public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException, URISyntaxException { Configuration conf = HBaseConfiguration.create(); String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs(); assert(otherArgs.length == 2); if(otherArgs.length < 2) { System.err.println("Usage: " + " ImportDataDriver -libjars
[,...[,]] "); System.exit(1); } String tableName = otherArgs[0].trim(); String input = otherArgs[1].trim(); // set table columns conf.set("table.cf.family", "cf_basic"); conf.set("table.cf.qualifier.fqdn", "domain"); conf.set("table.cf.qualifier.timestamp", "create_at"); Job job = new Job(conf, "Import into HBase table"); job.setJarByClass(DataImporter.class); job.setMapperClass(ImportFileLinesMapper.class); job.setOutputFormatClass(TableOutputFormat.class); job.getConfiguration().set(TableOutputFormat.OUTPUT_TABLE, tableName); job.setOutputKeyClass(ImmutableBytesWritable.class); job.setOutputValueClass(Put.class); job.setNumReduceTasks(0); FileInputFormat.addInputPath(job, new Path(input)); int exitCode = job.waitForCompletion(true) ? 0 : 1; System.exit(exitCode); } }
可以看到,我们可以通过-libjars选项来指定该Job运行所依赖的第三方jar文件,具体使用方法,说明如下:
- 第一步:设置环境变量
我们修改.bashrc文件,增加如下配置内容:
export HADOOP_HOME=/opt/stone/cloud/hadoop-1.0.3export PATH=$PATH:$HADOOP_HOME/binexport HBASE_HOME=/opt/stone/cloud/hbase-0.94.1export PATH=$PATH:$HBASE_H