领先一步
VMware 提供培训和认证,助您加速进步。
了解更多既然 Thomas 刚刚发布了 Spring for Apache Hadoop 的第五个里程碑版本,我想借此机会谈谈其新特性 Spring YARN 的最新进展。
我们Spring IO 平台的一个优势是其技术的互操作性。Spring Boot 和 Spring YARN 如何协同工作以创建更好的 Hadoop YARN 应用开发模型就是一个很好的例子。在这篇博客文章中,我想展示一个全新的 Spring Yarn 应用模型的示例,该模型在很大程度上基于Spring Boot。
从开发者开始工作到有人在 Hadoop 集群上实际执行应用程序,其开发生命周期比仅仅编写几行代码要复杂一些。让我们看看需要考虑什么
我们相信 Spring YARN 和 Spring Boot 提供了一个简单的编程模型,可以轻松地将应用程序测试和部署为 YARN 应用程序或传统应用程序。
从高层次来看,Spring YARN 提供了三个组件:YarnClient
、YarnAppmaster
和 YarnContainer
,它们反映了 YARN 架构中的关键过程。这三个组件共同构成了 Spring YARN 应用模型的基础。
在 Hadoop 集群上打包和执行自己的代码一直是一个繁琐的过程。需要将编译后的包放到 Hadoop 的 classpath 中,或者让 Hadoop 的工具在作业提交期间将包复制到 Hadoop 中。一旦你完成了 WordCount 之外的工作,你的代码将依赖于 Hadoop 默认 classpath 中不存在的第三方库。你应该如何打包你的依赖库?此外,如果你的依赖项与 Hadoop 默认 classpath 中已有的库发生冲突怎么办?
Spring Boot 提供了一个优雅的解决方案来解决这些构建和打包问题。你可以创建一个可执行的 jar 包(有时称为 uber 或 fat jar),它将你的应用程序代码及其所有依赖项捆绑到一个 .jar 文件中;或者创建一个 zip 文件,可以在代码执行前解压。这两种打包格式的主要区别在于,后者允许你重用 Hadoop 默认 classpath 中已有的 jar 包。
在本指南中,我们将展示如何使用 Spring Boot 将这三个组件:YarnClient
、YarnAppmaster
和 YarnContainer
打包成可执行 jar。Spring Boot 内部高度依赖应用程序的自动配置,而 Spring YARN 添加了其自身的自动配置魔法。用户可以将精力集中在自己的代码和应用程序配置上,而不是花费大量时间去理解所有组件如何相互集成。
现在我们将向您展示如何轻松地创建自定义应用程序并将其部署到 Hadoop 集群。请注意,无需使用 XML。
在这里,您将创建 ContainerApplication
和 HelloPojo
类。
@Configuration
@EnableAutoConfiguration
public class ContainerApplication {
public static void main(String[] args) {
SpringApplication.run(ContainerApplication.class, args);
}
@Bean
public HelloPojo helloPojo() {
return new HelloPojo();
}
}
在上面的 ContainerApplication
中,请注意我们如何在类级别本身添加了 @Configuration
注解,以及为 helloPojo()
方法添加了 @Bean
注解。我们之前提到了 YarnContainer
组件,它是容器中执行代码的接口。您可以定义自己的自定义 YarnContainer
来实现此接口并将所有逻辑封装在该实现中。
然而,如果未定义 YarnContainer
,Spring YARN 将默认使用 DefaultYarnContainer
,此默认实现期望找到一个具有容器应执行的实际逻辑的特定 bean。这有效地创建了一个简单的模型,其中最少只需一个简单的 POJO
即可。
@YarnContainer
public class HelloPojo {
private static final Log log = LogFactory.getLog(HelloPojo.class);
@Autowired
private Configuration configuration;
@OnYarnContainerStart
public void publicVoidNoArgsMethod() {
log.info("Hello from HelloPojo");
log.info("About to list from hdfs root content");
FsShell shell = new FsShell(configuration);
for (FileStatus s : shell.ls(false, "/")) {
log.info(s);
}
}
}
从某种意义上说,HelloPojo
类是一个简单的 POJO
,它不扩展任何 Spring YARN 基类。我们在此类中做了什么
@YarnContainer
注解。@OnYarnContainerStart
注解@Autowired
注入了 Hadoop 的 Configuration
类@YarnContainer
本身是一个 stereotype 注解,其中定义了 Spring 的 @Component
。这会自动将一个类标记为具有 @YarnContainer
功能的候选类。
在此类中,我们可以使用 @OnYarnContainerStart
注解来标记一个没有返回类型或参数的 public 方法,使其作为需要在 Hadoop 上执行的功能。
为了演示此类中确实有一些实际功能,我们简单地使用 Spring Hadoop 的 @FsShell
来列出 HDFS
文件系统的根目录下的条目。为此,我们需要访问 Hadoop 的 Configuration
,它已经为您准备好,您可以直接 autowire 注入。
在这里,您将创建一个 ClientApplication
类。
@EnableAutoConfiguration
public class ClientApplication {
public static void main(String[] args) {
SpringApplication.run(ClientApplication.class, args)
.getBean(YarnClient.class)
.submitApplication();
}
}
@EnableAutoConfiguration
告诉 Spring Boot 根据 classpath 设置、其他 bean 以及各种属性设置开始添加 bean。main()
方法使用 Spring Boot 的 SpringApplication.run()
方法启动应用程序。然后我们只需请求一个 YarnClient
类型的 bean 并执行其 submitApplication()
方法。接下来发生什么取决于应用程序配置,我们将在本指南后面介绍。
在这里,您将创建一个 AppmasterApplication
类。
@EnableAutoConfiguration
public class AppmasterApplication {
public static void main(String[] args) {
SpringApplication.run(AppmasterApplication.class, args);
}
}
用于 YarnAppmaster
的应用程序类看起来比我们为 ClientApplication
所做的还要简单。同样,main()
方法使用 Spring Boot 的 SpringApplication.run()
方法启动应用程序。
有人可能会争辩说,如果你使用这种虚拟类来基本启动你的应用程序,我们能否直接使用一个泛型类来实现?简单的答案是肯定的,我们甚至为此目的提供了一个泛型 SpringYarnBootApplication
类。你可以将其定义为可执行 jar 的主类,并在 gradle 构建过程中完成此操作。
然而,在实际应用中,您很可能需要开始为您的应用程序组件添加更多自定义功能,您可以通过添加更多 bean 来实现这一点。为此,您需要定义一个 Spring @Configuration
或 @ComponentScan
。然后 AppmasterApplication
将作为您定义更多自定义功能的主要起点。
创建一个新的 yaml
配置文件。
spring:
yarn:
appName: yarn-boot-simple
applicationDir: /app/yarn-boot-simple/
fsUri: hdfs://localhost:8020
rmAddress: localhost:8032
schedulerAddress: localhost:8030
client:
appmasterFile: yarn-boot-simple-appmaster-0.1.0.jar
files:
- "file:build/libs/yarn-boot-simple-container-0.1.0.jar"
- "file:build/libs/yarn-boot-simple-appmaster-0.1.0.jar"
appmaster:
containerCount: 1
containerFile: yarn-boot-simple-container-0.1.0.jar
应用程序的最后一部分是其运行时配置,它将所有组件粘合在一起,然后可以称为 Spring YARN 应用程序。此配置作为 Spring Boot 的 @ConfigurationProperties
的来源,并包含无法自动发现或否则需要由最终用户覆盖的相关配置属性。
然后,您可以为自己的环境编写默认配置。由于这些 @ConfigurationProperties
由 Spring Boot 在运行时解析,您甚至可以轻松地通过使用命令行选项或提供额外的配置文件来覆盖这些属性。
本博客中使用的示例代码可以在 GitHub 上的我们的spring-hadoop-samples仓库中找到。
签出我们的示例后,从 boot/yarn-boot-simple
目录发出 gradle build 命令。
$ cd boot/yarn-boot-simple
$ ./gradlew clean build
对于这个示例,我们希望保持项目结构简单。我们不会在本博客中详细介绍 gradle 构建文件,但简单来说,我们将从一个项目创建三个不同的 jar 文件。在实际应用中,可能会使用多项目模型,其中每个子项目创建自己的 jar 文件。
现在您已经成功编译并打包了您的应用程序,是时候做有趣的部分,在 Hadoop YARN 上执行它了。
下面的列表显示了成功进行 gradle 构建后的文件。
$ ls -lt build/libs/
-rw-r--r-- 1 hadoop hadoop 35975001 Feb 2 17:39 yarn-boot-simple-container-0.1.0.jar
-rw-r--r-- 1 hadoop hadoop 35973937 Feb 2 17:39 yarn-boot-simple-client-0.1.0.jar
-rw-r--r-- 1 hadoop hadoop 35973840 Feb 2 17:39 yarn-boot-simple-appmaster-0.1.0.jar
只需运行您的可执行客户端 jar。
$ java -jar build/libs/yarn-boot-simple-client-0.1.0.jar
使用 Resource Manager UI,您可以查看应用程序的状态。
要查找 Hadoop 的应用程序日志,请在配置的 userlogs 目录中进行查找。
$ find hadoop/logs/userlogs/|grep std
hadoop/logs/userlogs/application_1391348442831_0001/container_1391348442831_0001_01_000002/Container.stdout
hadoop/logs/userlogs/application_1391348442831_0001/container_1391348442831_0001_01_000002/Container.stderr
hadoop/logs/userlogs/application_1391348442831_0001/container_1391348442831_0001_01_000001/Appmaster.stdout
hadoop/logs/userlogs/application_1391348442831_0001/container_1391348442831_0001_01_000001/Appmaster.stderr
Grep HelloPojo
类记录的输出。
$ grep HelloPojo hadoop/logs/userlogs/application_1391348442831_0001/container_1391348442831_0001_01_000002/Container.stdout
[2014-02-02 17:40:38,314] boot - 11944 INFO [main] --- HelloPojo: Hello from HelloPojo
[2014-02-02 17:40:38,315] boot - 11944 INFO [main] --- HelloPojo: About to list from hdfs root content
[2014-02-02 17:40:41,134] boot - 11944 INFO [main] --- HelloPojo: FileStatus{path=hdfs://localhost:8020/; isDirectory=true; modification_time=1390823919636; access_time=0; owner=root; group=supergroup; permission=rwxr-xr-x; isSymlink=false}
[2014-02-02 17:40:41,135] boot - 11944 INFO [main] --- HelloPojo: FileStatus{path=hdfs://localhost:8020/app; isDirectory=true; modification_time=1391203430490; access_time=0; owner=jvalkealahti; group=supergroup; permission=rwxr-xr-x; isSymlink=false}
恭喜!您刚刚开发了一个 Spring YARN 应用程序!