概述:

   大数据处理是现在炙手可热的一个话题,目前流行的处理技术有很多,其中比较流行的要属Hadoop了。他自从诞生以来一直被社会各界人士关注,并被应用于不同行业的大数据处理中。
    从Hadoop 2.0 有了YARN 之后,让我们实现多种应用使用同一套资源管理框架成为了一种可能。
     对于公司内部使用同一个资源管理框架有很多优势,如资源最大利用,维护成本降低。公司内只需要一套技术栈就能解决业务问题,大大减少了人员学习成本。
   下面将介绍如何开发一个可以在YARN上运行的APP。
   本例开发的App功能很单一,具体功能是程序执行时会根据用户指定的节点个数(节点随机选择),执行一条命令。(这条命令被写死在worker的启动脚本里),其实现思路如下:
    1. 使用submit 脚本提交作业,脚本会将一些依赖文件复制到集群上,如jar 包, 配置信息等。
    2. Yarn 启动Container 时会将依赖文件复制下来,然后调用一个统一的脚本(run.sh),  这个run.sh 根据启动角色调用不同的类进行初始化。(AppMaster, Worker)
    3. 每个节点只运行一个Worker, 在请求资源时会做记录
   本例源码在:https://github.com/Yiran-wu/YARN-APP
YARN APP 组成
  一个完整的YARN App,需要以下几个部分:
Client: 用户提交程序,它负责
     1. 与用户交互接受用户传入的参数
     2. 负责上传或更新App依赖的Jar 包和依赖程序
     3. 创建AppMaster启动环境 和启动参数
     4.将YARN application 应用程序提交到集群上,并监控程序执行完成。
 ApplicationMaster: YARN APP 的Master服务,它负责
      1.资源申请与释放
      2.设置Container的启动环境与命令
      3.负责启动Container
      4.同时监控Container的运行情况,并对失败的进行重试。
 Container(worker): YARN APP 的计算服务,一个App可以有一个或多个Container节点。主要负责处理AppMaster分来的task。
1

创建项目

使用idea 创建一个maven 项目
1) File->Project…->选择 maven 项目
2
2) 添加maven工程的标识
3
4
3) 填写项目名称,点击完成, 点击完成之后,就会生成项目结构。 我们之后写的程序将会放在java 目录中
5
4) 增加项目依赖,修改pom.xml 文件,增加如下内容

Client实现

根据前面的分析描述,Client 需要与RM通讯并且要负责创建AM的环境和依赖.
主入口程序如下,在这里会解析用户输入参数,并通过参数初始化App:

 

Client 主要提交逻辑如下:

设置AppMaster Env 的代码如下,主要封装AppMaster启动时依赖的环境信息:

 

设置Application 的提交信息,如作业名,资源请求量、优先级、队列等信息

 

 

AppMaster实现

 创建ApplicationMaster类并继承AMRMClientAsync.CallbackHandler类。
这时我们会得到一个基本框架如下图, 继承AMRMClientAsync.CallbackHandler类之后需要自己实现相关接口,其接口会在相应事件发生时被调用。接口功能与触发条件如下:
 
onContainersCompleted:  当有Container完成时方法被调用,完成的Container会以参数的方式传入。可以在这个方法中实现Container完成后的操作
 
onContainersAllocated:申请Container成功之后被调用,申请成功的Container会以参数方式传入。在这个方法中我们要实现启动Worker操作
 
onShutdownRequest: 如果AM接收到了关闭请求,则此方法被调用。我们可以在这里实现AM关闭时的清理操作。
 
onNodesUpdated:如果运行过程中发现有些节点的状态改变了,此方法会被调用。在这里可以实现Node状态改变之后的处理逻辑
 
getProgress: 获取App 执行进度
6
有了框架之后,第一步我们要写一个启动main 函数, 在这个main 函数里,接收launchContainer.sh 传入的参数

如上面代码所示,main函数中调用的 runApplicationMaster 会做如下几件事:

1.  解析参数,并初始化ApplicationMaster

2. 启动ApplicationMaster,

3. 请求Worker Container

4. 等待执行完成

主要请求Worker Container 的逻辑如下

当获得请求的资源之后,我们就需要启动Worker了,在这里我们会给Worker配置环境,启动参数和依赖文件。这些都做完之后会使用nnClient 通知NM启动Container。

对于AppMaster 的编写还有很多东西要考虑,如容错,重试,超时处理等。其他细节请参考上文给出的github 地址。

 

运行

当代码写完之后,我们可以使用
mvn package -DskipTests 编译这个项目
提交命令如下:
submit.sh 2 hdfs://cluster/tmp
执行结果如下(因为程序比较简单,所以只能通过日志来看执行结果,如果获得失败请先用yarn application -kill ):

 

总结

YARN Application 的编写还是比较繁琐的,这里写的Application Demo 程序只能是入门级的一个实现,有很多的不足之处。

欢迎指正讨论。

如果要实现一个复杂的Application ,建议将资源请求独立成一个服务异步请求资源。同时将Container释放也独立成一个服务异步释放,提升Application执行效率。