设为首页 收藏本站
查看: 1031|回复: 0

[经验分享] 总结hadoop mapreduce job添加第三方依赖的方法

[复制链接]

尚未签到

发表于 2016-12-11 06:24:40 | 显示全部楼层 |阅读模式
总结hadoop mapreduce job添加第三方依赖的方法
hadoopclasspathmapreduce 

最近在开发mapreduce程序,输入有hdfs、hbase形式,输出有hdfs、mysql等形式。碰到了如何添加第三方依赖jar的问题,在网上查了很多资料,记录下来,免得再走弯路。 

下面所有方法基于hadoop-1.0.1版本实现,其它版本可能略有不同。 
总结了一下,总共有五种方法: 


      1、制作一个超级jar包,包含你的classes和所有依赖的第三方classes 



      2、和方法1差不多,只不过不是把依赖的第三方classes直接放入jar中,而是把第三方依赖的jar放在待提交jar包的lib目录下。 



      3、将jar包放在hadoop集群的各自node上,修改hadoop-env.sh中HADOOP_TASKTRACKER_OPTS 的值或者HADOOP_CLASSPATH。 



      4、将依赖的jar包拷贝事先到hdfs上,在代码中通过DistributedCache.addFileToClassPath方法,将其加入到依赖中。 



      5、使用hadoop jar的-libjars参数来设置第三方依赖的jar 



方法1和2的思想是一样的,都是把所有的依赖放入到一个jar包中。但这些方法不利于版本的维护,不推荐使用。 
方法3则需要配置集群中所有的node,而且也让hadoop本身依赖了第三方不相关的jar。 
方法4必须由代码去控制第三方的jar依赖,也不利于依赖的管理。 
方法5则没有上述问题,推荐使用。 
不过使用方法5有一些注意事项,否则你会发现即使设置了-libjars,还是找不到依赖的类。 
这个方法:如果包是在map 类,reudce类中使用没问题,如果你的依赖包在main方法或job提交之前使用中还是会找不到类
因为以下原因
conf.setClassLoader(new URLClassLoader(libjars, conf.getClassLoader()));
 Thread.currentThread().setContextClassLoader(...)

这意味着,这些包都被加载到当前classloader的子loader中,不是当前classloader中,所以,你不能在当前的job中直接使用这些包。


方法5具体使用步骤: 
1、提交jar参数设置 
Java代码   DSC0000.png


  • hadoop jar my-example.jar com.example.MyTool -libjars mysql-connector-java.jar,abc.jar  


多个jar包间使用逗号分隔。 

2、main函数的参数必须使用GenericOptionsParser解析。 
Java代码  


  • public static void main(String[] args) throws Exception {  
  •     Configuration conf = new Configuration();  
  •     String[] otherArgs = new GenericOptionsParser(conf, args).getRemainingArgs();  
  •     ....  
  • }  


或者通过ToolRunner.run去解析参数 
Java代码  


  • public static void main(final String[] args) throws Exception {  
  •   Configuration conf = new Configuration();  
  •   int res = ToolRunner.run(new MyTool(), args);  
  •   System.exit(res);  
  • }  


Java代码  


  • public class MyTool extends Configured implements Tool {  
  •   
  •   public final int run(final String[] args) throws Exception {  
  •     Job job = new Job(super.getConf());  
  •     ...  
  •     job.waitForCompletion(true);  
  •     return ...;  
  •   }  


详细代码可以参照mapreduce内的examples。 

实际上ToolRunner.run的内部也是调用了GenericOptionsParser去解析参数。跟踪源码就会发现GenericOptionsParser有这样的一段代码: 
Java代码  


  • if (line.hasOption("libjars")) {  
  •   conf.set("tmpjars",   
  •            validateFiles(line.getOptionValue("libjars"), conf));  
  •   //setting libjars in client classpath  
  •   URL[] libjars = getLibJars(conf);  
  •   if(libjars!=null && libjars.length>0) {  
  •     conf.setClassLoader(new URLClassLoader(libjars, conf.getClassLoader()));  
  •     Thread.currentThread().setContextClassLoader(  
  •         new URLClassLoader(libjars,   
  •             Thread.currentThread().getContextClassLoader()));  
  •   }  
  • }  


最终是往Configuration里设置了tmpjars的属性。 

参考文献: 
1、http://blog.cloudera.com/blog/2011/01/how-to-include-third-party-libraries-in-your-map-reduce-job/ 
2、http://grepalex.com/2013/02/25/hadoop-libjars/

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-312401-1-1.html 上篇帖子: 学习hadoop 出现的问题,以及解决方案 下篇帖子: hadoop使用中的几个小细节(二)(转自淘宝数据平台团队)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表