我最近一直在与Apache Amaterasu一起玩,这是一个了不起的项目,可帮助部署数据管道。 它仍在孵化中,并拥有一支由超级友好的工程师组成的团队。 列出了一些令人兴奋的功能。 不要相信我。 请自己检查一下 。
Amaterasu会针对数据管道中的每个阶段单独启动容器(在YARN / Mesos上)。 您只需要提供存储库和基于YAML的配置即可。
我只是对在YARN上启动容器以及API的工作方式感到好奇,因此我想自己尝试一下。 如果我们了解一小部分构造,这是非常直观的。
这篇文章是对Scala上YARN应用程序的最小示例的尝试。
注意:完整的代码可在github上找到
这个应用程式包含三个核心类别:
1. SampleYarnClient
2. ApplicationMaster
3. DummyApplication
(业务逻辑)
1. SampleYarnClient
这是程序的入口点。 请执行以下操作:
- 实例化
YarnClient
。 - 在
YarnClient
的帮助下,为ApplicationMaster容器协商资源。 它的方式是启动ApplicationSubmissionContext
,它只是Resource
,Priority
和ContainerLaunchContext
(以及其他)的包装。 让我们快速看一下代码,我们将详细介绍SubmissionContext的这三个组件。
val yarnClient = YarnClient.createYarnClient()
...
val application = yarnClient.createApplication()
...
val context = application.getApplicationSubmissionContext
context.setAMContainerSpec(amContainer)
context.setApplicationName("Scala Yarn App")
context.setResource(resource)
context.setPriority(priority)
yarnClient.submitApplication(context)
资源资源
资源是CPU和内存的简单包装
val resource = Resource.newInstance(1024, 2) //1 GB memory and 2 cores
优先
优先级只是整数–数字越大,优先级越高
val priority = Records.newRecord(classOf[Priority])
priority.setPriority(1)
ContainerLaunchContext
在此简单示例中,ContainerLaunchRequest具有三个主要参数:
- 命令(
List[String]
):引导命令(最好是java <MainClass>
) - LocalResources(
Map[String,LocalResource]
):运行命令所必需的jar和其他工件(属性,库等) - 环境(
Map[String,String]
):该程序必不可少的环境变量
(另一个重要的是安全令牌,由于我的本地集群未使用kerberized,因此此处未使用)
def createContainerContext(commands: List[String], resources: Map[String, LocalResource], environment: Map[String, String]): ContainerLaunchContext = {
val launchContext = Records.newRecord(classOf[ContainerLaunchContext])
launchContext.setCommands(commands.asJava)
launchContext.setLocalResources(resources.asJava)
launchContext.setEnvironment(environment.asJava)
launchContext
}
指令
就像我说的那样,这些命令只是您要执行以从shell运行ApplicationMaster的一系列指令。
val commands = List(
"$JAVA_HOME/bin/java " +
" -Xmx256m " +
s" com.arunma.ApplicationMaster " +
" 1> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stdout" +
" 2> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stderr"
)
本地资源
对于此程序,您不需要任何属性或配置文件。 您只需要一个jar二进制文件即可。
注意:使任何二进制文件或资源可用于YARN的方法是将二进制文件放置在HDFS位置。 这个涉及设置本地资源的特定步骤仅表示我们告诉YARN在启动时从HDFS位置下载二进制文件并将其放置在容器的本地路径中。
val localResources = Map(
"SampleYarnApp-assembly-0.1.jar" -> setUpLocalResourceFromPath(yarnPath)
)
环境
这些是自定义环境变量,或者只是需要设置以便运行包的类路径。
2. ApplicationMaster
既然我们已经讨论了SampleYarnClient
,那么我们来讨论第二个。 顾名思义,该类是您的ApplicationMaster
(Duh!)。 它负责启动预期将运行“业务逻辑”的容器。 这些步骤是:
- 所述AppMaster使用的ResourceManager客户端(
AMRMClient
)以提高用于容器的请求-ContainerRequest
。 此示例使用客户端的异步版本AMRMClientAsync
来实现一系列回调–onContainersAllocated
,onContainersCompleted
,onError
等。 - 当RM为应用程序分配容器时,将调用
onContainersAllocated
回调。 - 在
onContainersAllocated
(现在我们有容器的句柄)内,AppMaster然后使用NMClientAsync
启动“业务”容器(DummyApplication
)。 这是通过构造另一个ContainerLaunchContext
(包装命令,本地资源和环境变量的ContainerLaunchContext
)来实现的。
override def onContainersAllocated(containers: util.List[Container]): Unit = {
val commands = List(
"$JAVA_HOME/bin/java " +
" -Xmx256m " +
s" com.arunma.DummyApplication " +
" 1> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stdout" +
" 2> " + ApplicationConstants.LOG_DIR_EXPANSION_VAR + "/stderr"
)
val localResources = Map(
"SampleYarnApp-assembly-0.1.jar" -> setUpLocalResourceFromPath(FileSystem.get(conf).makeQualified(new Path(sys.env("ARUN_JAR_PATH"))))
)
val containerLaunchContext = createContainerContext(commands, localResources, buildEnvironment(Map()))
containers.asScala.foreach { container =>
nmClient.startContainerAsync(container, containerLaunchContext)
}
}
3. DummyApplication
这就是“业务逻辑”。 从最纯粹的意义上讲,并不是Scala
,但它可以帮助我们查看日志。 请注意,由于这是一个无限循环,因此我们必须强制终止该应用程序。
object DummyApplication extends App {
while(true) {
println("Niceeeeeeeeee !!! This is the core application that is running within the container that got negotiated by from Application Master !!!")
Thread.sleep(1000)
}
}
用法:
$ hadoop jar /Users/arun/IdeaProjects/SampleYarnApp/target/scala-2.11/SampleYarnApp-assembly-0.1.jar com.arunma.SampleYarnClient /Users/arun/IdeaProjects/SampleYarnApp/target/scala-2.11/SampleYarnApp-assembly-0.1.jar
另外,您也可以
sbt assembly
然后从您的IDE中运行SampleYarnClient
,并将程序集jar的绝对路径作为第一个参数。
翻译自: https://www.javacodegeeks.com/2018/05/creating-a-yarn-application-using-scala.html