Samza在YARN上的启动过程 =》 之一
运行脚本,提交job
往YARN提交Samza job要使用run-job.sh这个脚本。
samza-example/target/bin/run-job.sh --config-factory=samza.config.factories.PropertiesConfigFactory --config-path=file://$PWD/config/hello-world.properties
这脚本的内容是什么呢?
exec $(dirname $0)/run-class.sh org.apache.samza.job.JobRunner $@
它是调用run-class这个脚本。
run-class.sh会根据环境变量HADOOP_CONF_DIR和HADOOP_YARN_HOME获取YARN的配置文件位置,把它加入CLASSPATH。同时会把samza job根目录下的lib文件夹里的jar或war都加进CLASSPATH。只所以需要yarn的配置文件,目的是得到Resource Manager的地址。而lib目录下的包,是运行job必须的。
run-class.sh也会通过环境变量$SAMZA_LOG_DIR获知samza的log应存放的位置,通过$SAMZA_CONTAINER_NAME决定container的名字,然后把它们用-D设在JAVA_OPTS中。然后在lib目录下查找log4j.xml文件,存在的话,就把-Dlog4j.configuration设为log4j.xml的路径。
通过以上动作,构造好了调用java所需的classpath和任务运行时需要的一些配置项,然后调用
exec $JAVA $JAVA_OPTS -cp $CLASSPATH $@
启动虚拟机。
可以,在调用run-job.sh时,会运行org.apache.samza.job.JobRunner这个类。在samza的官方指南中简要介绍了一下这个类的作用。Samza自带了两种StreamJobFactory :LocalJobFactory 和 YarnJobFactory 。 StreamJobFactory的作用就是把给JobRunner提供一个可以执行的job
public interface StreamJobFactory {
StreamJob getJob(Config config);
}
而StreamJob就是一个可以执行的job, JobRunner会调用它的submit方法
public interface StreamJob {
StreamJob submit();
StreamJob kill();
ApplicationStatus waitForFinish(long timeoutMs);
ApplicationStatus waitForStatus(ApplicationStatus status, long timeoutMs);
ApplicationStatus getStatus();
}
下边来看JobRunner这个类。程序入口在JobRunner这个类的伴生对象里
object JobRunner extends Logging {
def main(args: Array[String]) {
val cmdline = new CommandLine
val options = cmdline.parser.parse(args: _*)
val config = cmdline.loadConfig(options)
new JobRunner(config).run
}
}
在配置参数以后,会走到JobRunner的run方法, 下边是它的主要逻辑
val jobFactoryClass = conf.getStreamJobFactoryClass match {
case Some(factoryClass) => factoryClass
case _ => throw new SamzaException("no job factory class defined")
}
val jobFactory = Class.forName(jobFactoryClass).newInstance.asInstanceOf[StreamJobFactory]
// Create the actual job, and submit it.
val job = jobFactory.getJob(conf).submit //提交job
info("waiting for job to start")
// Wait until the job has started, then exit.
Option(job.waitForStatus(Running, 500)) match {
case Some(appStatus) => {
if (Running.equals(appStatus)) {
info("job started successfully")
} else {
warn("unable to start job successfully. job has status %s" format (appStatus))
}
}
case _ => warn("unable to start job successfully.")
}
首先,它会去conf里找到是否设置了job.factory,即有没有指定StreamJobFactory的实现,没有就抛出异常退出。否则就通过这个StreamJobFactory提交job。在提交后,等待500毫秒,如果任务的状态不是Running就退出。这里的Running并不代表任务已经在跑了,比如在使用YARN时,只要成功提交给Resource Manager,就算是running了,所以这里的running是“任务提交成功“的意思。
YarnJob的实现
当提交给YARN时,我们使用YarnJobFactory这个StreamJobFactory的实现。
class YarnJobFactory extends StreamJobFactory {
def getJob(config: Config) = {
// TODO fix this. needed to support http package locations.
//这里会读yarn-site.xml。前提是yarn-site.xml必须在classpath里 在run-class.sh里,HADOOP_CONF_DIR路径被写进了classpath里
val hConfig = new YarnConfiguration
hConfig.set("fs.http.impl", classOf[HttpFileSystem].getName)
new YarnJob(config, hConfig)
}
}
” hConfig.set("fs.http.impl", classOf[HttpFileSystem].getName)“ 这一句是使得可以在job里调用http文件系统,如把文件路径写成"http://xxx.xx.xx.xx:8080/xx/xx"这种。Samza自带了一个HTTP filsystem的实现。或许是LinkedIn的人需要这么用?
YarnJobFactory,主要就是构造了一个YarnConfiguration,和以前的commandLine参数一起作为config来构造一个YarnJob. YarnConfiguration是YARN自己的类,它会从classpath里读yarn-site.xml这个配置文件。
YarnJob这个才是要被提交给Yarn的任务,它实现了StreamJob这个接口。这里主要关心它的submit方法。
val client = new ClientHelper(hadoopConfig)
var appId: Option[ApplicationId] = None
//提交job,注意会有AppMaster所需的内存和cpu数目。但不包括container数目
def submit: YarnJob = {
appId = client.submitApplication( //注意submitApplication的返回值是appId
new Path(config.getPackagePath.getOrElse(throw new SamzaException("No YARN package path defined in config."))),
config.getAMContainerMaxMemoryMb.getOrElse(DEFAULT_AM_CONTAINER_MEM),
1,
List(
"export SAMZA_LOG_DIR=%s && ln -sfn %s logs && exec ./__package/bin/run-am.sh 1>logs/%s 2>logs/%s"
format (ApplicationConstants.LOG_DIR_EXPANSION_VAR, ApplicationConstants.LOG_DIR_EXPANSION_VAR, ApplicationConstants.STDOUT, ApplicationConstants.STDERR)),
Some(Map(
ShellCommandConfig.ENV_CONFIG -> Util.envVarEscape(JsonConfigSerializer.toJson(config)),
ShellCommandConfig.ENV_CONTAINER_NAME -> Util.envVarEscape("application-master"),
ShellCommandConfig.ENV_JAVA_OPTS -> Util.envVarEscape(config.getAmOpts.getOrElse("")))),
Some("%s_%s" format (config.getName.get, config.getJobId.getOrElse(1)))) this
}
submit方法来提交任务的过程交给了ClientHelper的submitAppliation来实现。
这个方法才是提交YARN任务的关键。
首先,我们知道要提交任务给YARN一定实现YARN指定的接口。那么来揣摩一下YARN需要我们提供给它什么东西,它才能调度一个job的执行。
来猜猜看(实际上我已经知道了一些,看能不能想得更全一点,重要是理清思路)
- 首先,被提交的是什么?我已经知道YARN程序的执行过程是,先向YARN申请资源来运行一个 application master, 再由application master申请后续的资源。因此,这里提交的是一个请求,请求的内容是:RM,我要启动一个AM,给我分个container吧
- RM在什么时候才会同意一个application master的申请呢? 如果系统里的资源不足,有很多任务在运行,它会给拒了吗?
- 假如,RM批准了请求,给分了一个container。那么,那么……它只是一个container,毕竟没人使用它来执行程序。那么,谁来使用这个container来跑程序呢?那就是NodeManager了。那们在提交对AM的申请时,我们就需要告诉Yarn说我”需要NodeManager在这个container里这样……这样……这样做”
- 或许我们还该告诉Yarn这个AM需要的资源数量。毕竟运行这个AM也需要一个container,而一个container的核心就是它对应着一些资源。实际上,瞅一眼下边的方法签名,就会看到cpu和memory这两个大字。
先看它的签名
def submitApplication(packagePath: Path, memoryMb: Int, cpuCore: Int, cmds: List[String], env: Option[Map[String, String]], name: Option[String]): Option[ApplicationId]
下边介绍一下各个参数的含义,有助于我们了解这个方法都干了啥事。
- packagePath 这个机制之前没有想到。我们实际上提交任务时,只需要告诉yarn这个任务所需要资源(文件资源)的地址,由NodeManager去down下来这个资源,做本地化。而不是把这个job package整个传输给yarn。这样设计使得获取任务资源更灵活,比如job package可以在http文件系统里,像Samza的例子里一样,也可以在HDFS里(这个得需要配一下,在Samza工程里所有以.md结尾里的文件里搜hdfs,就会找到使用HDFS存放job package的指南),当然也可以在本地(在没有成功搞在http和hdfs两种方式之前,曾经试过这样……)。好吧,这样起码不会给RM在存储上造成压力。
- memoryMb 这个是想要给运行AM的container分配的内存大小
- cpuCore 需要几个core,这个是虚拟的,具体怎么实现,有待研究……
- cmds 这个就是NodeManage要执行命令吧
- env 环境变量,这个是配给运行AM的虚拟机的
- name 这个是这个job的名字,就是YARN job的名字,就是在RM的web UI上看到的名字。同时,Samza在bin目录下有个脚本,可以到当前在执行samza job。
返回值是ApplicationId。这是一个Option,所以提交失败时,返回值就是None。
再写下去submitApplication这个方法的实现,就有些太长,换下一篇
Samza在YARN上的启动过程 =》 之一的更多相关文章
- Samza在YARN上的启动过程 =》 之二 submitApplication
首先,来看怎么构造一个org.apache.hadoop.yarn.client.api.YarnClient class ClientHelper(conf: Configuration) exte ...
- Linux运维面试题:请简要说明Linux系统在目标板上的启动过程?
Linux运维面试题:请简要说明Linux系统在目标板上的启动过程? 该问题是Linux运维面试最常见的问题之一,问题答案如下: 1.用户打开PC的电源,BIOS开机自检,按BIOS中设置的启动设备( ...
- Linux X Window System运行原理和启动过程
本文主要说明X Window System的基本运行原理,其启动过程,及常见的跨网络运行X Window System. 一) 基本运行原理 X Window System采用C/S结构,但和我们常见 ...
- Hadoop 系列文章(三) 配置部署启动YARN及在YARN上运行MapReduce程序
这篇文章里我们将用配置 YARN,在 YARN 上运行 MapReduce. 1.修改 yarn-env.sh 环境变量里的 JAVA_HOME 路径 [bamboo@hadoop-senior ha ...
- CentOS7 Tomcat 启动过程很慢,JVM上的随机数与熵池策略
1. CentOS7 Tomcat 启动过程很慢 在centos启动官方的tomcat时,启动过程很慢,需要几分钟,经过查看日志,发现耗时在这里:是session引起的随机数问题导致的: <co ...
- 如何在ARM上运行k3s? 窥探k3s启动过程!,内附容器多平台包构建
开始之前 最近在对华为云鲲鹏服务器(一种ARM服务器arm64)运行容器可行性做验证,顺便了解了很多ARM和容器相关的知识.一提到arm运行容器首先想到的是k3s,下面是用k3s快速搭建一个kuber ...
- VxWorks启动过程详解(上)
vxworks有三种映像: VxWorks Image的文件类型有三种 Loadable Images:由Boot-ROM引导通过网口或串口下载到RAM ROM-based Images(压缩/没有压 ...
- VxWorks启动过程的详细解释(上)
vxworks有三个图像: VxWorks Image有三种类型的文件 Loadable Images:由Boot-ROM引导通过网口或串口下载到RAM ROM-based Images(压缩/没有压 ...
- 运行在YARN上的MapReduce应用程序(以MapReduce为例)
client作用:提交一个应用程序查看一个应用程序的运行状态(通过application master) 第一步:提交MR程序到ResourceManager,ResourceManager为这个应用 ...
随机推荐
- windows7下系统保护中出现错误“文件名、目录名或卷标语法不正确。(0x8007007B)“ 以及保护设置列表中出现“Windows7_os(c:)(找不到)”选项时的解决方法
windows7下系统保护功能很是鸡肋,有事会出现一下两个问题: 1.出现错误“文件名.目录名或卷标语法不正确.(0x8007007B) 2.保护设置列表中出现“Windows7_os(c:)(找不到 ...
- JAVA 基础加强学习笔记
一.面向对象 (一)继承 1.继承的好处: (1) 提高了代码的复用性. (2) 让类与类之间产生了关系,提供了另一个特征多态的前提. 注意: 子类中所有的构造函数都会默认访问父类中的空参数的构造函 ...
- PHP之HMVC
HMVC(Hierarchical-Model-View-Controller),也可以叫做 Layered MVC.顾名思义,就是按等级划分的 MVC 模式,简单的解释就是把MVC又细分成了多个子 ...
- mysql 强制走索引
查询是数据库技术中最常用的操作.查询操作的过程比较简单,首先从客户端发出查询的SQL语句,数据库服务端在接收到由客户端发来的SQL语句后, 执行这条SQL语句,然后将查询到的结果返回给客户端.虽然过程 ...
- 如何管好.net的内存(托管堆和垃圾回收)
一:C#标准Dispose模式的实现 需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CL ...
- linux 常用软件安装-目录
nginx apache php mysql oracle tomcat memcached mongodb sqlserver
- php 实现 mysql数据表优化与修复
<?php $link = mysql_connect("localhost", "root", "") or die("e ...
- angular $q服务的用法
Promise是一种和callback有类似功能却更强大的异步处理模式,有多种实现模式方式,比如著名的Q还有JQuery的Deffered. 什么是Promise 以前了解过Ajax的都能体会到回调的 ...
- 开源 侧滑 和 Tab滑动翻页 控件
侧滑 https://github.com/jfeinstein10/SlidingMenu Tab滑动翻页 https://github.com/astuetz/PagerSlidingTabStr ...
- jquery nicescroll 配置参数
jQuery滚动条插件兼容ie6+.手机.ipad http://www.areaaperta.com/nicescroll/ jQuery(function($){ $("#scrollI ...