有什么权威的YARN 什么是认证中心心么

  运行在独立的节点上的ResourceManager和NodeManager一起组成了yarn的核心,构建了整个平台。ApplicationMaster和相应的container一起组成了一个Yarn的应用系统。
  ResourceManager提供应用程序的调度,每个应用程序由一个ApplicationMaster管理,以Container的形式请求每个任务的计算资源。Container由ResourceMangaer调度,由每个节点的NodeManager上进行本地的管理。
ResourceManager 组件
  弄了一个大大的ResourceManager,醒目吧哈哈- -,扯淡到此为止,ResourceManager是Master,仲裁集群所有的可用资源,从而帮助管理运行在Yarn平台上的分布式应用程序。与其他组建的协作包括:接收ApplicationMaster的资源请求,每个节点的NodeManager从ResourceManager中获取指令,管理单个节点上的可用资源。(ApplicationMaster的职责就是向ResourceManager申请资源并且和NodeManager一起工作、启动、监控和停止Container。
一、客户端和ResourceManager交互
  这里细说Client端的话,ResourceManager主要是通过Client Service、Admininistration Service、Application ACL Manager ResourceManager Web Application及Web Service组件与客户端交互。
  1、Client Service &
  这个服务实现了基本的客户端到ResourceManager的接口ApplicationClientProtocol.该组件处理所有来自客户端到ResourceManager的远程过程调用(RPC)通信。包括:应用程序提交、应用程序终止、获取应用程序,队列,集群统计,用户ACL及更多信息。在安全模式下,Client Service确保所来自用户的请求都已经认证过(比如通过Kerberos),对于不能直接通过Kerberos认证的客户端,ClientRMService也提供了API,包括ResourceManager代理令牌,代理令牌是Kerberos认证客户端的一种特殊对象,能够第一次安全的与ResourceManager通信并传递给它自己额非认证的进程。
  2、Administration Service
  既然Client Service是负责处理一般用户应用程序的提交或终止,为了确保管理员的请求不会被一般用户的请求饿死,提供了搞优先级的操作命令,这里就多分离出了一个接口供管理员使用。通过ResourceManagerAdministrationProtocol来实现的通信协议。包含的主要操作有:刷新队列,重新分配队列或改变队列的属性、刷新ResourceManager处理的节点列表,例如:增加新安装的节点或退役现有节点等。
  3、Application ACL Manager
  类似客户端和管理员等的请求这样面向用户的API,ResourceManager可以通过设置配置属性yarn.acl.enable为true来启动应用程序的ACL。查看访问的ACL决定谁可以通过RPC接口查看一些货所有应用程序的相关细节,WEB UI服务及WEB服务,修改的ACL决定着哪些用户可以"修改"应用程序(杀死程序等)
  当相同的ACL信息传递给ApplicationMaster,这样ApplicationMaster可以使用该信息让用户访问ApplicationMaster内部运行的一些服务,作为ContainerLaunchContext的一部分,当拉起一个容器时NodeManager也接收相同的ACL信息,然后使用它们控制针对应用程序/container的请求,主要包括它们的状态、应用日志等。
  4、ResourceManager Web Application 和 Web Service
  这个就是ResourceManager的一个web应用程序来输出集群的状态信息、指标、节点活跃列表等,指向ApplicationMaster Web接口的超链接及一个调度的专用接口。(就是我们在集群配置中加入的web.address)
二、应用程序与ResourceManager的通信
  一旦应用程序通过ResourceManager中的面向客户端的服务,它就会穿过ResourceManager的内部,负责拉起ApplicationMaster的状态机。主要包括以下几个通信方面:
  1、ApplicationMaster Service
  该组件相应所有来自ApplicationMaster的请求,实现了ApplicationMasterProtocol协议,这是ApplicationMaster与ResourceManager通信的唯一协议。主要包括以下任务:注册新的ApplicationMaster、来自任意正在结束的ApplicationMaster的终止/取消注册请求、认证来自不同ApplicaitonMaster的所有请求,确保合法的ApplicationMaster发送的请求传递给ResourceManager中的应用程序对象、获取来自所有运行ApplicationMaster的Container的分配和释放请求、异步的转发给Yarn调度器.
  ApplicaitonMaster Service确保了任意时间点、任意ApplicaitionMaster只有一个线程可以发送请求给ResourceManager,因为在ResourceManager上所有来自ApplicaitonMaster的RPC请求都串行化了。
  2、ApplicationMaster 存活监控
  这个监控器跟踪每个ApplicationMaster以及它的最后的心跳时间。可在配置文件中配置时间,在配置时间内没有产生心跳的ApplicationMaster会被标记为死亡,ResourceManager会重新调度这个应用程序,在一个新的container上运行一个新的ApplicaitonMaster实例,默认情况下,最多允许两次这样的尝试。
三、节点和ResourceManager 通信
  下列是ResourceManager的组件和运行在集群节点上的NodeManager进行通信。
  1、ResourceManager Tracker Service
  NodeManager发送心跳给ResourceManager,ResourceManager的该组件负责相应来自所有节点的RPC。实现了ResourceTracker接口与所有NodeManager的通信。主要负责:注册新节点、接收前面注册节点的心跳、确保合法的节点可以和ResourceManager通信。Reource Tracker Service转发一个合法的心跳给YARN调度器,YARN调度器随后根据节点的空闲资源及不同应用程序的资源请求做调度决定。
  2、NodeManagers 存活监控
  为跟踪活跃的节点和确定已死的节点,该组件跟踪每一个节点的标识符(ID)和它最后的心跳时间。
  3、Nodes-List Manager
  是在ResourceManager内存中的一个集合,包括有效节点和被排除的节点。它也跟踪由管理员明确退役的节点。
ApplicationMaster 组件
  ApplicationMaster负责管理已提交的应用程序的集合。在应用程序提交后,首先检查其合法性,然后,确定没有其他已提交的应用程序已经使用相同的ID.该组件还负责记录和管理已结束的应用程序,过段时间才会从ResourceManager的内存中清除。
一、ApplicationMaster Launcher
  在Yarn中,每一个其他类型的Container的拉起都是由ApplicationMaster发起的,ApplicationMaster本身的Container是由ResourceManager申请,并在NodeManager上准备和拉起的。该组件维护一个线程池来设置环境,且和NodeManager通信来拉起新提交应用程序的ApplicationMaster,或者因为某些原因失败的先前应用程序实例所失败的ApplicationMaster。它也在以应用程序正常结束或者要强行终止时,负责告诉NodeManager来清理ApplicaitonMaster。(杀掉相应进程)
二、YarnScheduler
  Yarn调度器负责给正在运行的应用程序分配资源,这些应用程序受到容量、队列等各方面的限制。
三、ContainerAllocationExpirer
  该组件负责确保所有分配的Container最终被ApplicationMaster使用,并在相应的NodeManager上拉起。
NodeManager 组件
  NodeManager接受来自ApplicationMaster的启动或停止Container的请求,管理Container是NodeManager的核心功能。在真正拉起一个Container之前,NodeManager会将所有需要的库文件下载到本地,包括数据文件,可执行文件、tarball、JAR文件,shell脚本等待。这样下载好的库文件可以通过本地应用级别缓存被同一应用的多个Container共享。
  NodeManager内部也可以划分为一些列嵌套组件,卧槽好多啊。。。
一、NodeStatusUpdater
&  在NodeManager刚启动时,NodeStatusUpdater组件会向ResourceManager注册,发送本节点的可用资源,以及NodeManager的Web server和RPC Server的监听端口。ResourceManager在注册过程中,向NodeManager发出安全相关的key,NodeManager将用这个KEY作为ApplicationMaster的Container请求做认证。
二、ContainerManager
  是NodeManager的核心管理组件。其中也包含许多子组件:RPC Server、资源本地化服务、PUBLIC资源的本地化等等。
具体组件就不一一列举了。。。。太多了。。。。。。。
整个作业大体总体运行流程:
1、应用程序提交给ResourceManager。
2、ApplicationMaster启动,并向ResourceManager注册。
3、ApplicationMaster向ResourceManager请求Container执行实际的工作。
4、ApplicationMaster将从ResourceManager分配的Container信息(包括各种资源配置啊等信息)传递给NodeManager启动。
5、随之,计算过程在Container中进行,这些Container将与ApplicationMaster保持通信,发送心跳等告知任务过程。
6、当应用程序完成后,Container被停止,ApplicationMaster从ResourceManager中注销。
阅读(...) 评论()查看: 27100|回复: 5
YARN工作流程【推荐】
主题帖子积分
问题导读YARN上的应用程序主要分为几类,分别是什么?YARN将分几个阶段运行该应用程序?YARN的工作流程分为八个步骤,分别是什么?
运行在YARN上的应用程序主要分为两类:(1)短应用程序(2)长应用程序短应用程序是指一定时间内(可能是秒级、分钟级或小时级,尽管天级别或者更长时间的也存在,但非常少)可运行完成并正常退出的应用程序,比如MapReduce作业、Tez DAG作业等.
长应用程序是指不出意外,永不终止运行的应用程序,通常是一些服务,比如Storm Service(主要包括Nimbus和Supervisor两类服务),HBase Service(包括Hmaster和RegionServer两类服务)等,而它们本身作为一个框架提供了编程接口供用户使用。
尽管这两类应用程序作用不同,一类直接运行数据处理程序,一类用于部署服务(服务之上再运行数据处理程序),但运行在YARN上的流程是相同的。当用户向YARN中提交一个应用程序后,YARN将分两个阶段运行该应用程序:
第一个阶段是启动ApplicationMaster;第二个阶段是由ApplicationMaster创建应用程序,为它申请资源,并监控它的整个运行过程,直到运行完成。
如图2-11所示,YARN的工作流程分为以下几个步骤:步骤1 用户向YARN中提交应用程序,其中包括ApplicationMaster程序、启动ApplicationMaster的命令、用户程序等。
步骤2 ResourceManager为该应用程序分配第一个Container(这里可以理解为一种资源比如内存),并与对应的Node-Manager通信,要求它在这个Container中启动应用程序的ApplicationMaster。
步骤3 ApplicationMaster首先向ResourceManager注册,这样用户可以直接通过ResourceManage查看应用程序的运行状态,然后它将为各个任务申请资源,并监控它的运行状态,直到运行结束,即重复步骤4~7。
步骤4 ApplicationMaster采用轮询的方式通过RPC协议向ResourceManager申请和领取资源。
步骤5 一旦ApplicationMaster申请到资源后,便与对应的NodeManager通信,要求它启动任务。
步骤6 NodeManager为任务设置好运行环境(包括环境变量、JAR包、二进制程序等)后,将任务启动命令写到一个脚本中,并通过运行该脚本启动任务。
步骤7 各个任务通过某个RPC协议向ApplicationMaster汇报自己的状态和进度,以让ApplicationMaster随时掌握各个任务的运行状态,从而可以在任务失败时重新启动任务。在应用程序运行过程中,用户可随时通过RPC向ApplicationMaster查询应用程序的当前运行状态。
步骤8 应用程序运行完成后,ApplicationMaster向ResourceManager注销并关闭自己。
1.jpg (41.37 KB, 下载次数: 45)
01:03 上传
原文链接:
本帖被以下淘专辑推荐:
& |主题: 18, 订阅: 1
欢迎加入about云群 、 ,云计算爱好者群,关注
主题帖子积分
中级会员, 积分 516, 距离下一级还需 484 积分
中级会员, 积分 516, 距离下一级还需 484 积分
mark下 留着备用
主题帖子积分
注册会员, 积分 73, 距离下一级还需 127 积分
注册会员, 积分 73, 距离下一级还需 127 积分
看着就有点明白,不看就完全没概念,怎么办?
多找资料和视频,自然熟悉了&
主题帖子积分
注册会员, 积分 84, 距离下一级还需 116 积分
注册会员, 积分 84, 距离下一级还需 116 积分
ApplicationMaster这个是提交到nodemanager上面的吗?resourcemanager上的ApplicationsManager又是什么
主题帖子积分
高级会员, 积分 2245, 距离下一级还需 2755 积分
高级会员, 积分 2245, 距离下一级还需 2755 积分
ApplicationMaster这个是提交到nodemanager上面的吗?resourcemanager上的ApplicationsManager又是什么
ApplicationMaster这个是提交到nodemanager。这个谈不上提交。首先需要整体弄懂yarn:
&&Yarn/MRv2最基本的想法是将原JobTracker主要的资源管理和job调度/监视功能分开作为两个单独的守护进程。
有一个全局的ResourceManager(RM)和每个Application有一个ApplicationMaster(AM),Application相当于map-reduce job或者DAG jobs。
注意:ApplicationMaster对应的是一个应用程序,也就是一个map-reduce job
ResourceManager和NodeManager(NM)组成了基本的数据计算框架。ResourceManager协调集群的资源利用,任何client或者运行着的applicatitonMaster想要运行job或者task都得向RM申请一定的资源。ApplicatonMaster是一个框架特殊的库,对于MapReduce框架而言有它自己的AM实现,用户也可以实现自己的AM,在运行的时候,AM会与NM一起来启动和监视tasks。
站长推荐 /4
云计算hadoop视频大全(新增 yarn、flume|storm、hadoop一套视频
等待验证会员请验证邮箱
新手获取积分方法
技术类问答,解决学习openstack,hadoop生态系统中遇到的问题
Powered by分类存档: hadoop2yarn
前天,阿里巴巴的YARN版本从0.23.6升级到2.2.0,也就是目前社区最新的release版本。我们基本把阿里巴巴的关于YARN的所有的patch全部应用到社区的2.2.0版本上,大约有120多个patch。
主要涉及以下方面:
下面就每一个方面说明下:
安全 安全分为两块,认证和授权。 认证是保持和阿里1.0版本的hadoop一样的机制,修改ugi,用账户和密码的方式。账户和密码封装在ugi中,会随着RPC请求的消息头传服务端,服务端来完成认证。在近期阿里正在结合内部的认证体系 使用证书的方式登陆,证书由一个统一的认证中心颁发。关于授权,在yarn中基本就是能不能提交app,阿里添加了在哪些时段如许提交job等。对于hive的表格式的授权,目前也正在实现中。
关于稳定性,主要是长时间运行集群挂不挂,磁盘挂了,磁盘坏了,NM挂了等出现异常怎么办的问题。0.23.6版本在阿里已经运行6个月了。2.2.0刚上线,还没有出现特别的稳定性问题。
viewfs,因为我们的NN是有多个的,所以需要viewfs。
hive,此点社区的hive版本也已经支持yarn了。
调度,RM使用FairScheduler,对于MR的appmaster去向rm申请资源时还是比较复杂的。我们引入了一个绝对的优先级的感念,也就是当一个app的level高时,他就会优先拿到所有的资源。这就存在一个问题:建设是MR,如果一个jobA正在跑map,通过启动了一些reduce。如果此时高优先级的jobB来了,那此时jobA申请不到资源(因为所有的资源给jobB了),此时,jobA的reduce就会释放,最后相当于把jobA的已经申请到的reduce资源也释放给了jobB。但是如果不释放又不知jobB运行多久,占着container也不合适,所以就悲剧了。 我们改进就是 当此job的所有map都已经申请到资源后,才开始分配此job reduce。这样对于整体的吞吐量有一定的提高,但是对于此job的运行时间肯定延长了。
运维支持 对于一些 添加节点、下架节点等最起码需求需要支持。另外 由于线上的 端口有一定的限制。所以appmaster的ipc端口的端口必须在一段开放的范围内。
Cgroups:此点麻烦点在于我们是用一个普通的账户启动container,cgroups要求需要有sudo的权限。我们改进的版本就是把权限设置为:—Sr-s— 1 root
91510 Jan 15 11:00 container-executor
跨机房,阿里的hadoop是跨机房的。实现的方案是基于一个app只会在一个机房内运行。如果出现跨机房的app,那app内部的数据交换是跨机房之间的带宽吃不消的。改动就是修改FairScheduler调度器,提交到这几个queue的app只会在指定的机房分配资源就可以了。
支持MPI、Rhive等
spark目前是阿里YARN平台支持的除支持MR以外的最重要的框架。这快支持主要是spark需要支持yarn。为了支持0.23.7和2.2.0系列,他分别写了两个工程,一个是yarn,一个是new-yarn。如果再出现一个yarn的不兼容的版本,估计是new-new-yarn了。
据我所知,目前很多公司都在尝试YARN平台,阿里目前也已经正式在社区最新的YARN-2.2.0上跑起来了。2014年,YARN必将替换JT成为越来越多的公司的海量平台。SPARK等基于内存的准实时计算框架必将在YARN上绽放青春。
在v0.4版本中,增加shuffle、配置、web服务三大块的内容。另外把一些接口从0.23.6修改为2.2.0的接口。
下载地址为:
我们知道hadoop为了性能的考虑自己设计RPC框架。在0.23.4之前,RPC经历了很多的变动,pacth就占248个之多。如此多的变动,使我们理解RPC还是有一定的难度的。在这篇博客中,分析了0.19.1(基于阿里巴巴版本的,我们集成了很多高版本patch)的RPC的具体流程。hadoop rpc是短连接方式。接下来,我分析下,RPC发展情况、RPC的版本的含义、应用层协议格式、数据包解析。
二、RPC的发展
不知道历史是盲目的,让我们去看下最原始的RPC:,我们发现就3个类,既然就3个类。不过麻雀虽小五脏俱全:RPC、Client、Server,在Client、Server中分别包括一些Thread,通过这些Thread的协调使整个RPC run起来。下面是我review ipc所有patch后整理的一个发展情况,截止到0.23.4,后面的版本及2.0.x肯定已经做出一些变动。
Server Version
改包名从Nutch到org.apache.hadoop.ipc
HADOOP-211
Switch logging use the Jakarta Commons logging API, configured to use log4j by default.用log4j
HADOOP-210
Change RPC server to use a selector instead of a thread per connection. This should make it easier to scale to larger clusters. Contributed by Devaraj Das.
HADOOP-252
Add versioning to RPC protocols. Contributed by Milind.就是添加了一个接口校验的版本号
HADOOP-677
In IPC, permit a version header to be transmitted when connections are established. Contributed by Owen.差不多有传输层验证的雏形
HADOOP-2184
RPC Support for user permissions and authentication.
(Raghu Angadi via dhruba)开始考虑安全的事情了
HADOOP-1841
Prevent slow clients from consuming threads in the NameNode.
(dhruba),添加了Response线程
HADOOP-2398
Additional instrumentation for NameNode and RPC server.
Add support for accessing instrumentation statistics via JMX.
(Sanjay radia via dhruba)
成为apache的顶级项目。跟RPC没有多大关系,记录下里程碑事件。
HADOOP-2910
Throttle IPC Client/Server during bursts of
requests or server slowdown. (Hairong Kuang via dhruba),其实就是用了LinkedBlockingQueue阻塞式队列。只是没有想到引进这个是为了长度限制,而不是为了性能。
HADOOP-2188.
RPC should send a ping rather than use client timeouts. Contributed by Hairong Kuang.
HADOOP-4348
Add service-level authorization for Hadoop.在安全上迈出一大步
HADOOP-6170
Add facility to tunnel Avro RPCs through Hadoop RPCs.在数据封装上开始考虑用Avro了
HADOOP-6422
Make RPC backend plugable.一次较大的重构,其实是为了提供接口,使上层更好地扩展
HADOOP-6419
Change RPC layer to support SASL based mutual authentication 0.21.0 看来不断地增强安全功能
HADOOP-6599
Split existing RpcMetrics into RpcMetrics & RpcDetailedMetrics.
HADOOP-6713
The RPC server Listener thread is a scalability bottleneck. Contributed by Dmytro Molkov.添加一个Reader线程
HADOOP-6904
A baby step towards inter-version RPC communications,在VersionedProtocol添加getProtocolSignature接口.思考版本之间的兼容性问题
HADOOP-6949
io Reduces RPC packet size for primitive arrays, especially long[], which is used at block reporting
HADOOP-7227
Remove protocol version check at proxy creation in Hadoop RPC. Contributed by jitendra 把验证迁移到服务器端
MAPREDUCE-4079
Allow MR AppMaster to limit ephemeral port range.(bobby via tgraves),就是提供一组ip,Server是不能绑定的。
以上只是改动比较大的改动,我把时间也记录下来了,还有一些patch改动比较小或者是边缘功能。(以上只是我个人的理解)
在所有的patch,我们看出,HADOOP RPC是不断发展的——从性能、安全、度量及功能方面。需要注意的是:其中版本号变动基本代表了协议内容的变动。在官方中,每个不同版本号的客户端服务端肯定是不能通信的。即使是同一个,也有可能不能通信(低版本的hadoop在获取proxy的时候,会请求服务端接口的接口的版本号,再和本地验证;高版本的则通过Server验证)。关于接口层的通信验证相关的patch:HADOOP-252、HADOOP-6904、HADOOP-7227。其实安全这一块,hadoop做的也有很多,不过我们一般采取比较简单安全策略。
三、应用层协议格式
我们看下0.23.4版本中的数据包的组成,可以参考这个文章温习下网络的一些知识。其实接下来讲的也算不上一个网络协议,如果非要说是,也可以。网络协议具有三要素,人们形象地把这三个要素描述为:语义表示要做什么,语法表示要怎么做,时序表示做的顺序。那个我们也简单说这个就是第六版H-RPC协议(官方没有这个说法,我自编的),这里主要是为了协商安全号、版本号,传一些安全信息(安全信息专门在包头中)等。协议的具体内容可以看下协议图:
从图中我们看出请求报文主要分为三个部分。第一步包括6个字节,”hrpc”+一个版本号+安全认证方式。第二部分是ConnectionHeader信息,包括protocol和一些安全信息。第三部分是Writable这个就需要看RpcEngine的子类的实现方式,如:WritableRpcEngine是用Invocation,包括一些基本的调用信息。第二部分和第三部分不是固定长度,所以加了长度,占位4个字节。
返回报文比较简单,就直接call.id+status.state+xxx,xxx的信息需要根据status.state来确定,如果是0,则是 结果。如果是1,-1则是errorClass及error。
我们为了兼容多个版本之间的通信,就需要对协议内容非常了解。以上是0.23.4的协议图,如用0.23.4的client调用0.19.1的服务端,则需要修改0.19.1的Server的解析程序。目前,阿里巴巴的版本0.19.1的服务端已经兼容0.20.x及CDH3版本,目前我们打算兼容0.23.x版本的客户端(这个也主要是为了使我们的hdfs和yarn兼容)。
四、应用层数据包协议解析
那如何解析呢,其实根据上面那张图,我们大致知道怎么去解析这个数据包了。
while (true) {
int count = -1;
if (dataLengthBuffer.remaining() & 0) {
count = channelRead(channel, dataLengthBuffer); //读取4个字节的数据,其实就是hrpc
if (count & 0 || dataLengthBuffer.remaining() & 0)
if (!rpcHeaderRead) {//如果没有解析,就进入解析
//Every connection is expected to send the header.
if (rpcHeaderBuffer == null) {
rpcHeaderBuffer = ByteBuffer.allocate(2);
count = channelRead(channel, rpcHeaderBuffer);//再读取2个字节的数据 版本号+AuthMethod
if (count & 0 || rpcHeaderBuffer.remaining() & 0) {
int version = rpcHeaderBuffer.get(0);
byte[] method = new byte[] {rpcHeaderBuffer.get(1)};
authMethod = AuthMethod.read(new DataInputStream(
new ByteArrayInputStream(method)));
dataLengthBuffer.flip();
。。。。省去检查部分。。。。
rpcHeaderBuffer =
rpcHeaderRead =//解析完,设置标志
if (data == null) {
dataLengthBuffer.flip();
dataLength = dataLengthBuffer.getInt();//读取长度
data = ByteBuffer.allocate(dataLength);//分配dataLength的长度
count = channelRead(channel, data);
if (data.remaining() == 0) {
dataLengthBuffer.clear();
data.flip();
boolean isHeaderRead = headerR
processOneRpc(data.array());
if (!isHeaderRead) {
private void processOneRpc(byte[] buf) throws IOException,
InterruptedException {
if (headerRead) {
processData(buf);//分析数据
processHeader(buf);//分析头
headerRead =//解析头,设置标志。
大致的意思就是:先解析第一步,判断版本号,如果不兼容则报错。再读取header部分,最后读取Data部分。在代码中都有注释。返回的部分是Client#Connection#run来解析,和上面差不多。
文章可能会重新编辑,如果想浏览最新内容请访问。由于作者个人知识面有限,如果描述有错误或者遗留之处敬请谅解,再欢迎指出,我们共同进步。
我们都知道,yarn版本的hadoop无论是从架构上面还是软件设计的层面上面都比原始的hadoop版本有较大的改进。在架构方面,我们认为yarn模式是新一代的框架,这个在官方等丛多的资料中说明得很详细了。在软件设计方面,我认为主要有以下的一些大的方面的改进:服务生命周期管理模式、事件驱动模式、状态驱动模式。这几个模式都写在hadoop-yarn-common中,接下来,我将详细说明这些模式。
二、服务生命周期管理模式
一个对象肯定有生与死,那在我们设计中如何表示这一点呢?在业务系统中,我们一般是用spring,spring就负责管理对象的生命。在hadoop,我们没有必要引进spring这么厚重的容器。我们可以自行设计一套代码来管理我们服务的生命周期。那需要满足那些条件呢?
一个服务的生命大概有4个状态:NOTINITED、INITED、STARTED、STOPPED。对应一些基本的操作,如:init start stop等。
服务的状态变化会触发一些变化。可以用观察者模式。
有组合服务的概念,因为我需要一个循环同时启动多个服。可以使用Composite模式。
那yarn的设计方面如下:
从中我们看出service这个设计正好满足我们的三个基本的要求。从图中,我看得很清楚,这个是一个典型的设计方案。一个接口,下面有一个抽象类,再有一个组合类。AbstractService其实实现了register()、unrgister()及状态变化后,调用Listener基本的功能。CompositeService实现了组合服务的需求,如:ResourceManager可以组合几个服务。在yarn中,Listener并没有实现异步。个人感觉主要有两个理由:第一,如图中,NodeManager既是Service又是Listener,如果异步有死锁的风险。第二,因为都是服务,其启动,停止调用次数都相对非常少,状态也不会经常发生变化,没有必要引入异步。
这一套机制其实在很多的框架中都有涉及,如jetty中的LifeCycle,其实和这个差不多的。
三、事件驱动模式
事件驱动模式最核心的部分就是一个异步dispatcher,以此来达到解耦的目的。我们看下yarn中怎么实现的,如下图:
这个也是一个典型的设计方案,我在以前的系统中经常这么设计事件的。其实这个也是监听者模式。在消息中间件中,我们往往引入中间的存储层——存储转发。其实这个在路由器中也是这样的。用到最后,其实都差不多,关键在于你能否看破。
需要注意的是,AsyncDispatcher也是一个service,这样ResourceManager等组合服务可以add AsyncDispatcher获得AsyncDispatcher事件转发的功能。
四、状态驱动模式
在设计模式中,有一个状态模式,其实我这里讲的理论就是有穷状态机。状态模式我们可以认为是 ,我们这里讲的主要是, yarn中实现的还是比较复杂的,可以看出他就是非确定型的自动机。在框架中还是比较少看见状态机的,这个可以仔细研究下,我们可以先看下RMNode状态机的状态图(这个图是根据RMNode状态机自动生成的)。
我们看到 任意两个状态之间的变化可以是任意的事件,并且可以是多个事件;同一个事件可以使一个状态迁移到多个不同的状态。我们可以认为这里的状态机是非确定性米利型有限状态机。这些知识在大学的编译原理上面讲过,我也是翻书的。我们看下yarn中的实现,如下图所示:
我认为其中最重要就是构建这个Map&STATE, Map&EVENTTYPE,Transition&OPERAND, STATE, EVENTTYPE, EVENT&&& stateMachineTable对象,这里面存了状态机的元信息。后续调用完全是根据这个Map来运行的。重点讲下这个map的组成,从from到to端,第一个STATE是from端的状态。从一个状态转移可以有多个事件触发,其中的每一个事件可以有一个Transition,每个Transition就是有一个OPERAND操作。
一个Transition可以转移到多个to端的状态。可以从类图中看到Transition的两个实现类SingleInternalArc、MultipleInternalArc。MultipleInternalArc还带了一个默认的状态。
这个数据构建的时候用了builder模式,实现了FluentInterface: 。客户端是直接使用StateMachine的接口调用的,当然这个StateMachine也是由StateMachineFactory构建的(make)。我们看下状态的执行流程:
在yarn中,我们看下事件驱动模式与状态驱动模式是怎么结合的,从中可以看出,状态机其实和事件是密不可分的。状态机的Transition也会产生一些Event再输出到AsynDispatcher中。
在yarn中的应用了很多新的设计思想,以上3个只是在整个框架中比较突出的几个。我们在阅读框架时,要时刻牢记,设计软件的第一原则是软件设计的理论及架构模式。文章可能会重新编辑,如果想浏览最新内容请访问。由于作者个人知识面有限,如果描述有错误或者遗留之处敬请谅解,再欢迎指出,我们共同进步。
分布式系统比普通程序开发有一些特别的难度,最主要的就是环境问题。本博客将记录怎么去解决这些问题,最主要的是一些脚本。后期会连续更新,目前最主要的技巧有:
ssh打通:hadoop在部署的时候,各个机器之间肯定要打通,我们不可能手工去敲每一个命令。所以最好有一个脚本。 此为我一个同事写的脚本。
远程执行:我们往往在修改了一些配置、命令后,需要同步到各个自己上面,此时就需要远程执行。一般就是 ssh h2 “command”,如果同步多个文件最好是这么书写,如: 如果弄成多线程的,可以 此为我网上找的。
debug,我们一般需要在一些守护进程上面加上调试端口,如:
elif [ "$COMMAND" = "resourcemanager" ] ; then
CLASSPATH=${CLASSPATH}:$YARN_CONF_DIR/rm-config/log4j.properties
CLASS='org.apache.hadoop.yarn.server.resourcemanager.ResourceManager'
YARN_OPTS="$YARN_OPTS $YARN_RESOURCEMANAGER_OPTS"
YARN_OPTS="$YARN_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=1314,server=y,suspend=n"
AM需要在配置文件mapred-site.xml配置:
&property&
&name&yarn.app.mand-opts&/name&
&value&-Xmx1000m -Xdebug -Xrunjdwp:transport=dt_socket,address=5555,server=y,suspend=n&/value&
&/property&
以前的版本对于child是配置:
&property&
&name&mapred.child.java.opts&/name&
&value&-Xmx2000mM&!-- Xdebug -Xrunjdwp:transport=dt_socket,address=6666,server=y,suspend=y--&&/value&
&description&Java opts for the task tracker child processes.
The following symbol, if present, will be interpolated: @taskid@ is replaced
by current TaskID. Any other occurrences of '@' will go unchanged.
For example, to enable verbose gc logging to a file named for the taskid in
/tmp and to set the heap maximum to be a gigabyte, pass a 'value' of:
-Xmx1024m -verbose:gc -Xloggc:/tmp/@taskid@.gc
The configuration variable mapred.child.ulimit can be used to control the
maximum virtual memory of the child processes.
&/description&
936 &/property&
yarn版本控制container的参数比较多:分admin、user,user可以覆盖admin的;把map、reduce分开。参数有:mapreduce.map.java.opts、mapreduce.admin.map.child.java.opts、mapreduce.reduce.java.opts、mapreduce.admin.reduce.child.java.opts。
运行yarn的MR程序,发现出现问题,报错:
Exception in thread "main" java.lang.NoClassDefFoundError: org/apache/hadoop/mapreduce/v2/app/MRAppMaster
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.mapreduce.v2.app.MRAppMaster
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:205)
at java.lang.ClassLoader.loadClass(ClassLoader.java:323)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:294)
at java.lang.ClassLoader.loadClass(ClassLoader.java:268)
at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:336)
这个问题在hadoop-mapreduce-user邮件列表上面有人讨论过,地址: 不过不深入。
这个问题,很明显一看就是类加载不到,我们肯定首先去看下这个类在哪里,在包hadoop-mapreduce-client-app-2.0.0-alpha.jar中,路径在$HADOOP_HOME/share/hadoop/mapreduce(在2.0版本中,后续我估计这个可能会调整)
这个我猜应该是classpath的问题,所以我很想弄到启动container的时候的参数。
我们知道启动是通过shell命令启动,在ContainerLaunch.java中,我最终调试发现了启动参数(下面的这段代码其实最后会写入到/tmp/nm-local-dir/nmPrivate/application_4_0005/container_4_001/launch_container.sh这样类似的文件中):
#!/bin/bash
export YARN_LOCAL_DIRS="/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003"
export NM_HTTP_PORT="8042"
export JAVA_HOME="/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre"
export NM_HOST="hd19-vm4.yunti."
export CLASSPATH="$PWD:$HADOOP_CONF_DIR:$HADOOP_COMMON_HOME/share/hadoop/common/*:$HADOOP_COMMON_HOME/share/hadoop/common/lib/*:$HADOOP_HDFS_HOME/share/hadoop/hdfs/*:$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*:$YARN_HOME/share/hadoop/mapreduce/*:$YARN_HOME/share/hadoop/mapreduce/lib/*:job.jar:$PWD/*"
export HADOOP_TOKEN_FILE_LOCATION="/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003/container_7_001/container_tokens"
export APPLICATION_WEB_PROXY_BASE="/proxy/application_7_0003"
export JVM_PID="$$"
export USER="yarn"
export PWD="/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003/container_7_001"
export NM_PORT="49111"
export HOME="/home/"
export LOGNAME="yarn"
export APP_SUBMIT_TIME_ENV="8"
export HADOOP_CONF_DIR="/home/yarn/hadoop-2.0.0-alpha/conf"
export MALLOC_ARENA_MAX="4"
export AM_CONTAINER_ID="container_7_001"
ln -sf "/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003/filecache/-1520617/job.jar" "job.jar"
mkdir -p jobSubmitDir
ln -sf "/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003/filecache/5082106/appTokens" "jobSubmitDir/appTokens"
ln -sf "/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003/filecache/-097803/job.xml" "job.xml"
mkdir -p jobSubmitDir
ln -sf "/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003/filecache/0839370/job.split" "jobSubmitDir/job.split"
mkdir -p jobSubmitDir
ln -sf "/tmp/nm-local-dir/usercache/yarn/appcache/application_7_0003/filecache/3329844/job.splitmetainfo" "jobSubmitDir/job.splitmetainfo"
exec /bin/bash -c "$JAVA_HOME/bin/java -Dlog4j.configuration=container-log4j.properties -Dyarn.app.mapreduce.container.log.dir=/tmp/logs/application_7_0003/container_7_001 -Dyarn.app.mapreduce.container.log.filesize=0 -Dhadoop.root.logger=INFO,CLA -Xmx1024m org.apache.hadoop.mapreduce.v2.app.MRAppMaster 1&/tmp/logs/application_7_0003/container_7_001/stdout 2&/tmp/logs/application_7_0003/container_7_001/stderr
classpath是:
"$PWD:$HADOOP_CONF_DIR:$HADOOP_COMMON_HOME/share/hadoop/common/*:$HADOOP_COMMON_HOME/share/hadoop/common/lib/*:$HADOOP_HDFS_HOME/share/hadoop/hdfs/*:$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*:$YARN_HOME/share/hadoop/mapreduce/*:$YARN_HOME/share/hadoop/mapreduce/lib/*:job.jar:$PWD/*"
其实这个是:yarn.application.classpath这个参数控制,这个默认的是:
&property&
&description&Classpath for typical applications.&/description&
&name&yarn.application.classpath&/name&
$HADOOP_CONF_DIR,
$HADOOP_COMMON_HOME/share/hadoop/common/*,
$HADOOP_COMMON_HOME/share/hadoop/common/lib/*,
$HADOOP_HDFS_HOME/share/hadoop/hdfs/*,
$HADOOP_HDFS_HOME/share/hadoop/hdfs/lib/*,
$YARN_HOME/share/hadoop/mapreduce/*,
$YARN_HOME/share/hadoop/mapreduce/lib/*
&/property&
通过比较,那$HADOOP_HOME/share/hadoop/mapreduce/hadoop-mapreduce-client-app-2.0.0-alpha.jar应该在$YARN_HOME/share/hadoop/mapreduce/*这个中,现在的问题就是$YARN_HOME这个数值是多少?
在命令行下执行:
[yarn@hd19-vm2 ~]$ echo $YARN_HOME
/home/yarn/hadoop-2.0.0-alpha
是正确的。
那在launch_container.sh命令执行过程中,难道不起作用么?这个就要从linux的环境变量说起了,参考:
鸟哥讲述了login 与 non-login shell的区别, non-login shell是不读取~/.bash_profile这个文件啦,是读取:~/.bashrc这个文件。(我们设置环境变量的时候大部分人会写到~/.bash_profile文件中)
我们通过远程调用shell及java调用shell的过程其实都不会读取~/.bash_profile文件的。所以说launch_container.sh中也export了很多的环境变量了。这个主要是ContainerLaunch#sanitizeEnv()写入的。
我们看到有export JAVA_HOME=”/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre” 没有export YARN_HOME=xxx的,所以执行launch_container.sh的时候,其实YARN_HOME是空的。
因为System.getenv中没有YARN_HOME所以在launch_container.sh也没有export选项。(这个要看源码ContainerLaunch.java#sanitizeEnv())
我们也看下jvm启动的时候env:
System.getenv()
(java.util.Collections$UnmodifiableMap&K,V&) {HADOOP_PREFIX=/home/yarn/hadoop-2.0.0-alpha, SHLVL=2, JAVA_HOME=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64, YARN_LOG_DIR=/home/yarn/hadoop-2.0.0-alpha/logs, XFILESEARCHPATH=/usr/dt/app-defaults/%L/Dt, SSH_CLIENT=10.249.197.55 47859 22, MAIL=/var/mail/yarn, PWD=/home/yarn/hadoop-2.0.0-alpha, LOGNAME=yarn, CVS_RSH=ssh, G_BROKEN_FILENAMES=1, NLSPATH=/usr/dt/lib/nls/msg/%L/%N.cat, LD_LIBRARY_PATH=/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/amd64/server:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/lib/amd64:/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0.x86_64/jre/../lib/amd64, SSH_CONNECTION=10.249.197.55 .197.56 22, MALLOC_ARENA_MAX=4, SHELL=/bin/bash, YARN_ROOT_LOGGER=INFO,RFA, YARN_LOGFILE=yarn-yarn-nodemanager-hd19-vm2.yunti..log, PATH=/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin, USER=yarn, HOME=/home/yarn, LESSOPEN=|/usr/bin/lesspipe.sh %s, HADOOP_CONF_DIR=/home/yarn/hadoop-2.0.0-alpha/conf, LS_COLORS=, SSH_ASKPASS=/usr/libexec/openssh/gnome-ssh-askpass, LANG=en_US.UTF-8, YARN_IDENT_STRING=yarn, YARN_NICENESS=0}
这些主要是.bashrc与hadoop启动的命令产生的(其实从启动机器上面也可以带环境变量过来,大家可以做一个实验 export a=b; ssh h2 “echo $a&test”;ssh h2 “cat test”;)
还有一点非常注意:. xx.sh 如果没有export x 那x有效范围就是调用的进程,YARN_HOME就是这么弄的。
那么我们修改这个就是非常容易了,我们可以把YARN_HOME等设置在.bashrc中。设置的变量主要有:JAVA_HOME,HADOOP_COMMON_HOME,HADOOP_HDFS_HOME,HADOOP_CONF_DIR,YARN_HOME
其中JAVA_HOME一般会ssh的时候带过去(当然需要所有机器的JAVA_HOME一致)、已经export的有HADOOP_CONF_DIR
或者修改$HADOOP_HOME/libexec中的代码,把YARN_HOME等变量export 。
hadoop2的设计细想比hadoop1进步了很多,毕竟hadoop1是几年前的东西了。软件设计的理论在这几年中发展很快,出现了很多的软件设计理论 如:领域驱动模型、事件驱动模型、状生命周期管理等,也出现了很多的开源的解决方案,当然开源的方案很多都是起源apache社区。在hadoop2中,采取了maven的工程管理结构,把以前的单一工程换成了多工程结构模式,现在估计有45个(pom.xml文件的个数)project,以后会不会更多或者合并一些,这个就要持续关注hadoop开源社区的发展了。当然project也不是越多越好,我见过的最多的包工程有几百个,eclipse刷新的时候就需要几个小时,这个对于开发效能是一个极大的挑战。一般的项目的project个数大约在10个左右。hadoop大约有45个,我感觉有点多,当然hadoop2把project合理的分层了,这个确实是非常清晰的。
关于多个project的好处,我认为主要是:其一project之间的依赖的关系是单向的,包之间的功能是隔离的,这个不同于package,package是可以互相依赖的,对于隔离主要看设计者;其二就是管理方便,开发方便。
二、hadoop2工程分析
我们接下来对release-2.0.0-alpha分析,源码来自:http://svn.apache.org/repos/asf/hadoop/common/tags/release-2.0.0-alpha,其他的一些版本包会有一些变化。
分析的工具是:structure101,可以google看下。
第一层:hadoop主要有四部分:hadoop-common-project、hadoop-hdfs-project、hadoop-mapreduce、hadoop-tools。他们之间的依赖关系如下图1所示:
每部分的功能从名称就看得出来,这样的依赖关系很清晰。我们将从低往上去看下依赖关系。
第二层:图2展示了第二层的结构。
我们可以看出四个包的下属工程,其中hadoop-mapreduce的工程hadoop-yarn有一个向上依赖hadoop-mapreduce-client 依赖是pom.xml的scope为test的依赖。我认为这个也是不对的,应该是去掉。 tools工程下面的子工程互相之间是独立的,因为他们都是工程包。
第三层:我们再看下其中hadoop-yarn与hadoop-mapreduce-client,如图3所示:
我们看到hadoop-yarn还是很清楚的。对于hadoop-mapreduce-client有6个project不过还是比较清楚。
第四层:看下 hadoop-yarn-server下属的包,建图4
在此图中,我们看到了 hadoop-yarn-server-namemanger及hadoop-yarn-server-resourcemanager,在计算中,也就是这两大守护进程了。
svn co http://svn.apache.org/repos/asf/hadoop/common/tags/release-2.0.0-alpha xxx
linux: 参考$HADOOP_HOME/BUILDING.txt 及$HADOOP_HOME/hadoop-mapreduce-project/INSTALL(ps,我开始没有注意这两个文件,所以我以下都是一步一步调试,纠结,痛苦中写出来了。)
装protoc buffer
mvn install -Dmaven.skip.test即可。
产生部署tar包:mvn install -Dtar
-Pdist -Dmaven.javadoc.skip=true -DskipTests=true
在win下面,首先下载cygwin: 在path中设置路径。
下载proto buffer 如路径:/p/protobuf/downloads/detail?name=protoc-2.4.1-win32.zip&can=2&q= 解压后把protoc.exe放在cygwin根目录的bin目录下面。
打上patch:https://issues.apache.org/jira/browse/MAPREDUCE-3881#comment- 就是修改hadoop-mapreduce-projecthadoop-yarnhadoop-yarn-commonpom.xml:https://issues.apache.org/jira/secure/attachment//pom.xml.patch
mvn install -Dmaven.skip.test即可。
遇到的一些问题:附上最后的conf目录:
在eclipse中导入工程,在3.7版本中,出现通过f4找不到ClientRMProtocol的实现类ClientRMService。但是在3.6eclipse中可以。这个比较奇怪,让我不得不用3.6eclipse。
mvn install -Dtar
-Pdist -Dmaven.javadoc.skip=true
-Dmaven.test.skip=true打包过程中,出现:
[sourcecode language=”shell”][ERROR] Failed to execute goal org.apache.maven.plugins:maven-assembly-plugin:2.3:single (package-mapreduce) on project hadoop-mapreduce: Assembly is incorrectly configured: hadoop-mapreduce-dist: Assembly is incorrectly configured: hadoop-mapreduce-dist:
[ERROR] Assembly: hadoop-mapreduce-dist is not configured correctly: Cannot find attachment with classifier: tests in module project: org.apache.hadoop:hadoop-mapreduce-client-jobclient:jar:2.0.0-alpha. Please exclude this module from the module-set.[/sourcecode]
此我对hadoop-assemblies工程下的hadoop-mapreduce-dist.xml修改,开始我直接删除了moduleSets导致了,启动yarn报错。后我把&attachmentClassifier&tests&/attachmentClassifier&注释掉了,我现在还不知道这个有啥左右。
补充下,找到原因了。其实就是 -Dmaven.test.skip=true会跳过测试资源编译,这个测试会在maven-assembly-plugin用到。所以报错了。应该该用为-DskipTests=true。
hdfs格式化后,启动hdfs后。java.io.IOException: Incompatible clusterIDs in /tmp/hadoop-yarn/dfs/data: namenode clusterID = CID-2917fbbc-dcd7-40f3-8a1f-f222c3941fc1;
datanode clusterID = CID-d53b270a-893f-4fa5-b5e5-1e5ed5ee4e86,需要把各个DN下/tmp/hadoop-yarn/dfs/ 下的文件全部删除。
启动yarn 报错。
[sourcecode language=”java”][yarn@hd19-vm1 sbin]$ ./start-yarn.sh
starting yarn daemons
starting resourcemanager, logging to /home/yarn/hadoop-2.0.0-alpha/logs/yarn-yarn-resourcemanager-hd19-vm1.yunti..out
Exception in thread &main& java.lang.NoClassDefFoundError: org/apache/hadoop/yarn/server/resourcemanager/ResourceManager
Caused by: java.lang.ClassNotFoundException: org.apache.hadoop.yarn.server.resourcemanager.ResourceManager
at java.net.URLClassLoader$1.run(URLClassLoader.java:217)[/sourcecode]
这是因为打包少了包的原因,主要是我自定对hadoop-assemblies工程下的hadoop-mapreduce-dist.xml修改的缘故。
mr始终在本地运行,因为配置问题,改为yarn的。
&property&
&name&mapreduce.framework.name&/name&
&value&local&/value&
&description&The runtime framework for executing MapReduce jobs.
Can be one of local, classic or yarn.
&/description&
&/property&
java.lang.IllegalStateException: Invalid shuffle port number -1 returned fo,这个问题我查了很久,主要是yarn对调试比较纠结。
[sourcecode language=”java”]Container launch failed for container_8_004 : java.lang.IllegalStateException: Invalid shuffle port number -1 returned for attempt_8_0002_r_
at org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl$Container.launch(ContainerLauncherImpl.java:162)
at org.apache.hadoop.mapreduce.v2.app.launcher.ContainerLauncherImpl$EventProcessor.run(ContainerLauncherImpl.java:373)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:636)[/sourcecode]
解决方法其实很简单(框架也不默认下)是因为:yarn.nodemanager.aux-services没有配置mapreduce.shuffle
[sourcecode language=”shell”]
&property&
&name&yarn.nodemanager.aux-services&/name&
&value&mapreduce.shuffle&/value&
&/property&
[/sourcecode]}

我要回帖

更多关于 认证中心的体系结构 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信