ScarlettYellow 2016-10-26
Apache Mesos能够成为最优秀的数据中心资源管理器的一个重要功能是面对各种类型的应用,它具备像交警一样的疏导能力。本文将深入Mesos的资源分配内部,探讨Mesos是如何根据客户应用需求,平衡公平资源共享的。在开始之前,如果读者还没有阅读这个系列的前序文章,建议首先阅读它们。第一篇是Mesos的概述,第二篇是两级架构的说明,第三篇是数据存储和容错。
我们将探讨Mesos的资源分配模块,看看它是如何确定将什么样的资源邀约发送给具体哪个Framework,以及在必要时如何回收资源。让我们先来回顾一下Mesos的任务调度过程:
从前面提到的两级架构的说明一文中我们知道,Mesos Master代理任务的调度首先从Slave节点收集有关可用资源的信息,然后以资源邀约的形式,将这些资源提供给注册其上的Framework。
Framework可以根据是否符合任务对资源的约束,选择接受或拒绝资源邀约。一旦资源邀约被接受,Framework将与Master协作调度任务,并在数据中心的相应Slave节点上运行任务。
如何作出资源邀约的决定是由资源分配模块实现的,该模块存在于Master之中。资源分配模块确定Framework接受资源邀约的顺序,与此同时,确保在本性贪婪的Framework之间公平地共享资源。在同质环境中,比如Hadoop集群,使用最多的公平份额分配算法之一是最大最小公平算法(max-min fairness)。最大最小公平算法算法将最小的资源分配最大化,并将其提供给用户,确保每个用户都能获得公平的资源份额,以满足其需求所需的资源;一个简单的例子能够说明其工作原理,请参考最大最小公平份额算法页面的示例1。如前所述,在同质环境下,这通常能够很好地运行。同质环境下的资源需求几乎没有波动,所涉及的资源类型包括CPU、内存、网络带宽和I/O。然而,在跨数据中心调度资源并且是异构的资源需求时,资源分配将会更加困难。例如,当用户A的每个任务需要1核CPU、4GB内存,而用户B的每个任务需要3核CPU、1GB内存时,如何提供合适的公平份额分配策略?当用户A的任务是内存密集型,而用户B的任务是CPU密集型时,如何公平地为其分配一揽子资源?
因为Mesos是专门管理异构环境中的资源,所以它实现了一个可插拔的资源分配模块架构,将特定部署最适合的分配策略和算法交给用户去实现。例如,用户可以实现加权的最大最小公平性算法,让指定的Framework相对于其它的Framework获得更多的资源。默认情况下,Mesos包括一个严格优先级的资源分配模块和一个改良的公平份额资源分配模块。严格优先级模块实现的算法给定Framework的优先级,使其总是接收并接受足以满足其任务要求的资源邀约。这保证了关键应用在Mesos中限制动态资源份额上的开销,但是会潜在其他Framework饥饿的情况。
由于这些原因,大多数用户默认使用DRF(主导资源公平算法 Dominant Resource Fairness),这是Mesos中更适合异质环境的改良公平份额算法。
DRF和Mesos一样出自Berkeley AMPLab团队,并且作为Mesos的默认资源分配策略实现编码。
读者可以从此处和此处阅读DRF的原始论文。在本文中,我将总结其中要点并提供一些例子,相信这样会更清晰地解读DRF。让我们开始揭秘之旅。
DRF的目标是确保每一个用户,即Mesos中的Framework,在异质环境中能够接收到其最需资源的公平份额。为了掌握DRF,我们需要了解主导资源(dominant resource)和主导份额(dominant share)的概念。Framework的主导资源是其最需的资源类型(CPU、内存等),在资源邀约中以可用资源百分比的形式展示。例如,对于计算密集型的任务,它的Framework的主导资源是CPU,而依赖于在内存中计算的任务,它的Framework的主导资源是内存。因为资源是分配给Framework的,所以DRF会跟踪每个Framework拥有的资源类型的份额百分比;Framework拥有的全部资源类型份额中占最高百分比的就是Framework的主导份额。DRF算法会使用所有已注册的Framework来计算主导份额,以确保每个Framework能接收到其主导资源的公平份额。
概念过于抽象了吧?让我们用一个例子来说明。假设我们有一个资源邀约,包含9核CPU和18GB的内存。Framework 1运行任务需要(1核CPU、4GB内存),Framework 2运行任务需要(3核CPU、1GB内存)
Framework 1的每个任务会消耗CPU总数的1/9、内存总数的2/9,因此Framework 1的主导资源是内存。同样,Framework 2的每个任务会CPU总数的1/3、内存总数的1/18,因此Framework 2的主导资源是CPU。DRF会尝试为每个Framework提供等量的主导资源,作为他们的主导份额。在这个例子中,DRF将协同Framework做如下分配:Framework 1有三个任务,总分配为(3核CPU、12GB内存),Framework 2有两个任务,总分配为(6核CPU、2GB内存)。
此时,每个Framework的主导资源(Framework 1的内存和Framework 2的CPU)最终得到相同的主导份额(2/3或67%),这样提供给两个Framework后,将没有足够的可用资源运行其他任务。需要注意的是,如果Framework 1中仅有两个任务需要被运行,那么Framework 2以及其他已注册的Framework将收到的所有剩余的资源。
那么,DRF是怎样计算而产生上述结果的呢?如前所述,DRF分配模块跟踪分配给每个Framework的资源和每个框架的主导份额。每次,DRF以所有Framework中运行的任务中最低的主导份额作为资源邀约发送给Framework。如果有足够的可用资源来运行它的任务,Framework将接受这个邀约。通过前面引述的DRF论文中的示例,我们来贯穿DRF算法的每个步骤。为了简单起见,示例将不考虑短任务完成后,资源被释放回资源池中这一因素,我们假设每个Framework会有无限数量的任务要运行,并认为每个资源邀约都会被接受。
回顾上述示例,假设有一个资源邀约包含9核CPU和18GB内存。Framework 1运行的任务需要(1核CPU、4GB内存),Framework 2运行的任务需要(3核CPU、2GB内存)。Framework 1的任务会消耗CPU总数的1/9、内存总数的2/9,Framework 1的主导资源是内存。同样,Framework 2的每个任务会CPU总数的1/3、内存总数的1/18,Framework 2的主导资源是CPU。
上面表中的每一行提供了以下信息:
注意,每个行中的最低主导份额以粗体字显示,以便查找。
最初,两个Framework的主导份额是0%,我们假设DRF首先选择的是Framework 2,当然我们也可以假设Framework 1,但是最终的结果是一样的。
需要注意的是,可以创建一个资源分配模块,使用加权的DRF使其偏向某个Framework或某组Framework。如前面所提到的,也可以创建一些自定义模块来提供组织特定的分配策略。
一般情况下,现在大多数的任务是短暂的,Mesos能够等待任务完成并重新分配资源。然而,集群上也可以跑长时间运行的任务,这些任务用于处理挂起作业或行为不当的Framework。
值得注意的是,在当资源释放的速度不够快的情况下,资源分配模块具有撤销任务的能力。Mesos尝试如此撤销任务:向执行器发送请求结束指定的任务,并给出一个宽限期让执行器清理该任务。如果执行器不响应请求,分配模块就结束该执行器及其上的所有任务。
分配策略可以实现为,通过提供与Framework相关的保证配置,来阻止对指定任务的撤销。如果Framework低于保证配置,Mesos将不能结束该Framework的任务。
我们还需了解更多关于Mesos资源分配的知识,但是我将戛然而止。接下来,我要说点不同的东西,是关于Mesos社区的。我相信这是一个值得考虑的重要话题,因为开源不仅包括技术,还包括社区。
说完社区,我将会写一些关于Mesos的安装和Framework的创建和使用的,逐步指导的教程。在一番实操教学的文章之后,我会回来做一些更深入的话题,比如Framework与Master是如何互动的,Mesos如何跨多个数据中心工作等。
与往常一样,我鼓励读者提供反馈,特别是关于如果我打标的地方,如果你发现哪里不对,请反馈给我。我非全知,虚心求教,所以非常期待读者的校正和启示。我们也可以在twitter上沟通,请关注 @hui_kenneth。
http://www.infoq.com/cn/articles/analyse-mesos-part-04/