简单介绍YARN
YARN通过两类长期运行的守护进程提供自己的核心服务:
- 管理集群上资源使用的资源管理器(Resource Manager)
- 运行在集群中所有节点上且能够启动和监控容器的节点管理器(Node Manager)
容器用于执行特定应用程序的进程,每个容器都有资源限制(内存、CPU等),一个容器可以是一个Unix进程,也可以是Linux cgroup,取决于YARN的配置。下图为YARN应用的运行机制:
在YARN上运行一个应用,需要以下步骤:
- 客户端联系资源管理器,要求它运行一个application master进程
- 资源管理器找到一个能够在容器中启动application master的节点管理器(图中的2a和2b)
- 看图,4a和4b可以看做是一个分布式计算
资源请求
Yarn有一个灵活的资源请求模式。当请求多个容器时,可以指定每个容器需要的计算机资源数量,还可以指定对容器本地的限制要求。
本地化对于确保分布式数据处理算法高效实用集群带宽非常重要。因此,YARN允许一个应用为所申请的容器指定本地限制。本地限制可用于申请位于指定节点或机架,或集群中任何位置的容器。
有时本地限制无法被满足,在这种情况下要么不分配资源,或者可选择放松限制。例如,一个节点由于运行了别的容器而无法再启动新的容器,这时如果有应用请求该节点,则YARN将尝试在同一机架上的其他节点上启动一个容器,如果还不行,则会尝试集群中的任何一个节点。
通常情况下,当启动一个容器用于处理HDFS数据块(在MapReduce中运行一个map任务),应用将会向这样的节点申请容器:存储该数据块三个复本的节点,或是存储这些复本的机架中的一个节点。如果都申请失败,则申请集群中的任意节点。
YARN应用可以在运行中的任意时刻提出资源申请。例如,可以在最开始提出所有的请求,或者为了满足不断变化的应用需要,采取更为动态的方式在需要更多的资源时提出请求。
Spark采用了上述第一种方式,在集群上启动固定数量的执行器。另一方面,MapReduce分两步走,在最开始时申请map任务容器,reduce任务容器的启动则放在后期。同样,如果某一任务失败,将会另外申请容器再次执行运行失败的任务。
YARN的生命周期
YARN的生命周期差异性很大,短则几秒,长则几天甚至几个月。我们这里按照应用到用户运行的作业之间的映射关系对应用进行分类更有意义。
第一种模型是,一个用户作业对应一个应用,这是MapReduce采用的方式。
第二种模型是,作业的每个工作流或每个用户对话对应一个应用。这种模型比第一种效率要高,因为容器可以在作业之间重用,并且有可能缓存作业之间的中间数据,Spark采用的是这种模型。
第三种模型是,多个用户共享一个长期运行的应用。这种应用通常是作为一种协调者的角色在运行。例如,Apache Slider有一个长期运行的application master,主要用于启动集群上的其他应用。Impala也使用这种模型提供了一个代理应用,Impala守护进程通过该代理请求集群资源。由于避免了启动新的application master带来的开销,一个总是开启的application master意味着用户将获得非常低延迟的查询响应。
构建YARN应用
从无到有编写一个YARN应用是一件相当复杂的事,在很多情况下不必这样。有很多现成的应用,在符合要求的情况下通常可以直接使用。例如,如果你有兴趣运行一个作业的有向无环图,那么Spark或Tez就很合适,如果对流处理有兴趣,那么Spark、Samza或Storm能提供帮助。
许多项目都简化了Yarn应用的过程。例如Apache Slider,可以在YARN上运行现有的分布式应用。对于一个应用(例如HBase)来说,用户可以独立于其他用户在集群上运行自己的实例,则意味着不同的用户能够运行同一应用的不同版本。Slider提供了控制手段,可以修改应用运行所在节点的数量,也可以暂停和恢复应用的运行。
Apache Twill与Slider类似,但额外提供了一个简单的编程模型,用于开发YARN上的分布式应用。Twill允许将集群进程定义为Java Runnable的扩展,然后在集群上的YARN容器运行它们。Twill同样为实时日志可命令消息提供支持。
当遇到以上方法都不适合的情况下,例如一个应用有复杂的调度需求,那么作为YARN项目自身一部分的distributed shell应用为如何写YARN应用做了一个示范。该应用演示了如何实用YARN客户端API来处理客户端或application master与YARN守护进程之间的通信。