打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
Mapreduce部署与第三方依赖包管理

    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之后,问题解决!!

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Hadoop集群(第7期)_Eclipse开发环境设置
hadoop2x-eclipse插件编译与安装
精通HADOOP(五) - 初识Hadoop - 执行和测试Hadoop样例程序
数据导入HBase最惯用的三种方式及实践分析(3)
shell编程实例
Hadoop的安装以及分布式环境的搭建
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服