我必须在Hadoop集群中运行一些不能用Map/Reduce表示的东西。我想为它编写一个 YARN 应用程序。我发现了用于弹簧靴的Spring Yarn,并遵循了入门(见链接)。到目前为止,这有效,但存在一些缺陷:
- 在本教程中,生成了三个 JAR(一个用于客户端,一个用于应用程序管理员,一个用于容器),提交应用程序时,它们必须位于特定的文件夹结构中
- 我必须在 application.yml 中对 HDFS URI 和资源管理器主机/端口进行硬编码,或者将它们作为命令行参数提供
- 由于它基于Spring Boot,并且应用程序是用
java -jar
启动的,因此创建的JAR文件非常大,其中基本上有一个完整的Hadoop堆栈 - JAR文件的确切名称必须在application.yml中提及
我想要什么:
- 单个 JAR,其中包含用于应用程序管理员和容器
- 的 JAR,其中打包了应用程序管理员和容器
- 可使用
hadoop jar
从命令行运行 - 使用使用
hadoop jar
运行时可用的配置(对于 MR2,这可以通过启动扩展Configured
类并使用ToolRunner.run()
实现Tool
来实现,这使得Configuration
在工具的run
方法中可用)
我想到的方法是:
- 编写容器和AppMaster,将YARN和Hadoop依赖项设置为在其POM中提供,将它们与maven-shade-plugin打包在一起,就像我对MR作业所做的那样
- 编写客户端,添加 AppMaster 和容器作为依赖项,使用 maven-assembly-plugin 打包以防止 JAR 被提取
我尝试了Twill,但无济于事。我得到
java.lang.NoSuchMethodError: com.google.common.collect.Sets.newCopyOnWriteArraySet()Ljava/util/concurrent/CopyOnWriteArraySet;
因为我的Hadoop安装使用番石榴11,而斜纹需要13。即使番石榴 13 被阴影放入罐子中,它也会被忽略。
我发现了一种我称之为"解决方法"的东西,它足以满足我的用例:
- 我使用 Spring YARN 构建我的应用程序,从而为客户端、容器和应用程序管理员生成单独的 JAR。
- 我将它们作为模块添加到控制版本号的主 POM 中(每当我在前三个项目之一中更改任何内容时,我都会递增主 POM 的版本)
- 这个主 POM 本身就是一个模块,带有我的整个项目范围的大型父 POM
- 主 POM 的父级不是大型项目范围的 POM,而是
spring-boot-starter-parent
当由 Jenkins 构建时,这会创建上述三个 JAR,我目前手动将它们打包到一个文件夹中,旁边有一个启动脚本。这只是一个临时解决方案,因为此应用程序包含一个长时间运行的任务,稍后将由用户从Web应用程序(也基于Spring)启动。我仍然需要弄清楚如何从那里提交申请。
我的想法如下,这类似于我目前为 MR 工作所做的:
- 将 JAR 作为依赖项添加到 Web 应用程序的 pom 中.xml
- 在三个 JAR 中包含一个没有 YARN 和 JAR 信息的基本
application.yml
- 使用与
Job.setJarByClass()
相同的技术来定位应用程序管理员和容器 JAR - 通过命令行传入连接属性和 JAR 文件的解析位置
SpringApplication.run()
(args
变量)调用客户端的主类
有人能给我一个提示,如果这是一个可行的情况,请告诉我。
我进一步挖掘了这个问题,发现从其他Spring Boot应用程序中打包和生成Spring Boot应用程序并不容易。对于我的用例,从不使用 YARN 的 Spring 引导应用程序调用 Spring YARN 应用程序,以下方法有效:
- 在"单文件模式"下创建 Spring YARN 应用程序,如本教程所示
- 将生成的 JAR 打包到要从中部署它的应用程序中
- 例如,在使用Maven时,您可以将其添加为依赖项
- 确保部署应用程序排除
YarnClientAutoConfiguration
如下所示:@EnableAutoConfiguration(exclude = YarnClientAutoConfiguration.class)
- 确保打包插件将 JAR 打包为整个存档,就像
maven-assembly-plugin
或spring-boot-maven-plugin
一样(不是maven-shade-plugin
) - 将部署应用程序的大 JAR 解压缩到临时目录
- 使用
ProcessBuilder
在 Spring-YARN 应用程序上运行java -jar
运行,并在命令行传递正确的配置选项
这有点笨拙,Hadoop肯定需要类似于MR作业Job
的东西,它只是在YARN上运行东西。