Mapreduce部署是总会涉及到第三方包依赖问题,这些第三方包配置的方式不同,会对mapreduce的部署便捷性有一些影响,有时候还会导致脚本出错。本文介绍几种常用的配置方式:

1. HADOOP_CLASSPATH

在hadoop的相关配置文件中,添加CLASSPATH路径,那么在hadoop的各个进程启动时都会载入这些包,因此对于mapreduce-job jar中则不需要额外的引入这些jars,所以mapreduce-job jar会比较小[瘦jar],便于传输;但它的问题也比较明显,如果mapreduce-job中新增了其他引用jar,则必须重新启动hadoop的相关进程。

我们可以在hadoop-env.sh中,增加如下配置:

export HADOOP_CLASSPATH=$HADOOP_CLASSPATH:/path/customer/jars

其中“/path/customer/jars”路径为自己的第三方jar所在的本地路径,我们需要在集群中所有的hadoop机器上都同步这些jar。

瘦jar的打包方式(maven):

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
<mainClass>com.app.script.Main</mainClass>
</manifest>
</archive>
</configuration>
</plugin>

使用了copy-dependencies插件,当使用“mvn package”命令打包之后,第三方引用包会被copy到打包目录下的lib文件中(并非mapreduce-job jar内部的lib文件中),开发者只需要把这些jars上传到所有hadoop集群即可。

2. mapred.child.env

我们可以指定mapreduce的task子进程启动时加载第三方jars,而不是让所有的hadoop子进程都加载。通过在mapred-site.xml中增加如下配置:

<property>
<name>mapred.child.env</name>
<value>LD_LIBRARY_PATH=/path/customer/jars</value>
<!--
LD_LIBRARY_PATH=$HADOOP_HOME/mapred-lib/thirdparty
-->
</property>

这种方式和1)类似,不过更加便捷,每个mapper或者reducer子进程启动时都会重新加载第三方jars,所以当jars有变动时,只需要直接覆盖它们即可,而无需重启hadoop或者yarn。

3. -libjars选项

我们可以在使用“hadoo jar”命令时,向启动的job传递“libjars”选项参数,同时配合ToolRunner工具来解析参数并运行Job,这种方式是推荐的用法之一,因为它可以简单的实现job的依赖包和hadoop classpath解耦,可以为每个job单独设置libjars参数。这些jars将会在job提交之后复制到hadoop“共享文件系统中”(hdfs,/tmp文件夹中),此后taskTracker即可load到本地并在任务子进程中加载。

libjars中需要指定job依赖的所有的jar全路径,并且这些jars必须在当前本地文件系统中(并非集群中都需要有此jars),暂时还不支持hdfs。对于在HADOOP_CLASSPATH或者mapred.child.env中已经包含了jars,则不需要再-libjars参数中再次指定。因为libjars需要指定jar的全路径名,所以如果jars特别多的话,操作起来非常不便,所以我们通常将多个job共用的jars通过HADOOP_CLASSPATH或者mapred.child.end方式配置,将某个job依赖的额外的jars(少量的)通过-libjars选项指定。

hadoop jar statistic-mr.jar com.statistic.script.Main -libjars /path/cascading-core-2.5.jar,/path/cascading-hadoop-2.5.jar

4. Fatjar

胖jar,即将mapreduce-job jar所依赖的所有jar都“shade”到一个jar中,最终package成一个“独立”的可运行的jar;当然hadoop并不需要这个jar是“可运行的”,它只需要这个jar在运行时不需要额外的配置“--classpath”即可。此外Fatjar仍然可以使用HADOOP_CLASSPATH或者map.child.env所加载的jars,因为我们在打包时可以将这些jars排除,以减少fatjar的大小。

fatjar只不过是一种打包的方式,也仍然可以和“-libjars”选项配合。不过从直观上来说,fatjar确实是解决“-libjars”不方便的技巧。

此例中,我们使用cascading来开发一个mapreduce job,但是我们又不希望cascading的相关依赖包被放入HADOOP_CLASSPATH中,因为其他的job可能不需要或者其他的job有可能使用其他版本的cascading;所以就使用Fatjar,把job程序和cascading的依赖包全部“shade”在一起。

使用maven assambly插件来完成fatjar的打包工作:

1) pom.xml

<build>
<finalName>statistic-mapred</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptors>
<descriptor>src/assembly.xml</descriptor>
</descriptors>
<archive>
<!-- optional -->
<!--
<manifest>
<mainClass>com.script.Main</mainClass>
<addClasspath>true</addClasspath>
</manifest>
-->
</archive>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>

    2) assambly.xml

<assembly>
<id>cascading</id>
<formats>
<format>jar</format>
</formats>
<includeBaseDirectory>false</includeBaseDirectory>
<dependencySets>
<dependencySet>
<unpack>true</unpack>
<scope>runtime</scope>
<!--
<excludes>
<exclude>org.apache.hadoop:*</exclude>
</excludes>
-->
<!-- very small jar -->
<includes>
<include>cascading:*</include>
<include>thirdparty:*</include>
</includes>
</dependencySet>
</dependencySets>
<fileSets>
<fileSet>
<directory>${project.build.outputDirectory}</directory>
<outputDirectory>/</outputDirectory>
</fileSet>
</fileSets>
</assembly>

在assambly.xml中我们通过<include>标签来包含需要被“shade”的第三方依赖包,并且采用了unpack(解压)方式,此例中我们只将cascading的jar打进fatjar中,对于其他包将会被忽略,因为这些包已经在hadoop中存在(比如hadoop,hdfs,mapreduce,已经其他的常用包,都可以共用hadoop的),最终我们的打包结果如下:

有了fatjar,确实大大的减少了开发工程师部署mapreduce的复杂度和出错的可能性,如果你有即备的maven环境,建议使用fatjar的方式。将fatjar直接放在hadoop中使用“hadoop jar”指令即可执行,几乎无需关心依赖包遗漏的问题。

此外,需要备注一下,在使用cascading时,如果采用了HADOOP_CLASSPATH或者mapred.child.env方式管理依赖时,会偶尔抛出:

Split class cascading.tap.hadoop.MultiInputSplit not found

尽管cascading的所有依赖包都在CLASSPATH中,也无法解决这个问题,不确定究竟发生了什么!!后来采用了fatjar之后,问题解决!!

【转】Mapreduce部署与第三方依赖包管理的更多相关文章

  1. Mapreduce部署与第三方依赖包管理

    Mapreduce部署是总会涉及到第三方包依赖问题,这些第三方包配置的方式不同,会对mapreduce的部署便捷性有一些影响,有时候还会导致脚本出错.本文介绍几种常用的配置方式: 1. HADOOP_ ...

  2. flutter如何使用配置文件pubspec.yaml(位于项目根目录)来管理第三方依赖包

    官方文档 在软件开发中,很多时候有一些公共的库或SDK可能会被很多项目用到,因此,将这些代码单独抽到一个独立模块,然后哪个项目需要使用时再直接集成这个模块,便可大大提高开发效率.很多编程语言或开发工具 ...

  3. Java基础-Eclipse第三方安装包管理工具之Maven

    Java基础-Eclipse第三方安装包管理工具之Maven 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 玩过Linux的小伙伴应该都知道yum吧,我们只要把搭建好的yum仓库配 ...

  4. go依赖包管理工具vendor基础

    go依赖包管理工具vendor基础 vendor是go的依赖包管理工具,主要用于管理项目中使用到的一些依赖. 它将项目依赖的包,特指外部包,复制到当前工程下的vendor目录下,这样go build的 ...

  5. bower一个强大的前端依赖包管理工具

    在介绍之前,你必须的知道bower是基于nodejs开发的,所以你首先必须得有个nodejs环境,至于这么安装nodejs网上一大堆教程,对了使用bower还需要安装git,这里就不多说了. #### ...

  6. Maven 手动添加第三方依赖包及编译打包和java命令行编译JAVA文件并使用jar命令打包

    一,实例:新建了一个Maven项目,在eclipse中通过 build path –> configure path-.将依赖包添加到工程中后,eclipse不报错了.但是用Maven命令 mv ...

  7. 安装CDH第三方依赖包

    安装CDH第三方依赖包: yum install chkconfig python bind-utils psmisc libxslt zlib sqlite cyrus-sasl-plain cyr ...

  8. SAE 安装未包含的第三方依赖包

    如何使用virtualenv管理依赖关系 当你的应用依赖很多第三方包时,可以使用virtualenv来管理并导出这些依赖包,流程如下: 首先,创建一个全新的Python虚拟环境目录ENV,启动虚拟环境 ...

  9. eclipse打jar包解决第三方依赖包

    在项目根目录下手动MANIFEST.MF(eclipse无法自动生成) MANIFEST.MF Manifest-Version: 1.0 Class-Path: lib/kafka-clients- ...

随机推荐

  1. 一个还算简单的微信消息SDK(基于.Net Standard 2.0)

    虽然微信公众号出现了好久,不过在SDK这件事情上感觉并没有多少人把它当成一个有技术含量的事情来做,很多SDK做的事情就是一个代码的堆叠,当然也可能写的好的并没有开源出来.所以在某个翻遍Github而无 ...

  2. 题目1522:包含min函数的栈

    #include <iostream> #include <cstdio> #include <stack> using namespace std; int ma ...

  3. php 数据访问练习:租房查询页面

    <html> <head> <title></title> <meta charset="UTF-8"/> <li ...

  4. django全文检索

    -------------------linux下配置操作1.在虚拟环境中依次安装包 1.pip install django-haystack haystack:django的一个包,可以方便地对m ...

  5. Java filter拦截器的使用

    1.web.xml配置 <!-- 验证是否登录 拦截功能 --> <filter> <filter-name>isLogin</filter-name> ...

  6. IBM与麻省理工学院联合建立AI实验室 承诺投资2.4亿美元

         IBM和麻省理工学院将通过今天宣布的一个新的联合实验室共同努力,对人工智能进行广泛的研究.麻省理工学院IBM沃森AI实验室将重点关注四个研究支柱:开发AI算法,使用物理学来创建AI计算的新硬 ...

  7. Jquery的入门学习

    jQuery API中文文档地址 http://www.jquery123.com/ Jquery w3school教程 http://www.w3school.com.cn/jquery/index ...

  8. AT&T汇编语言学习:利用c库、文件读写

    AT&T汇编.调用C库函数.读/写文件 d0321:更新读文件代码(图片)以后会更新代码版. d0329:汇编文本读取.简单动画. ============================== ...

  9. K好数--蓝桥杯

    JAVA版K好数--蓝桥杯 历经千辛万苦,也算是研究出来了这道题了. 这道题主要运用了动态规划(Dynamic Planning)的思想,何谓动态规划?其实就是将一个大问题分成一个个小问题,然后先通过 ...

  10. 软工+C(2017第3期) 超链接

    // 上一篇:分数和checklist // 下一篇:Alpha/Beta换人 注:平常看文章,总有能和构建之法,软件工程相关的链接,增量记录,也可以通过在其他人博客的交流中使用相关的超链接,在使用中 ...