分布式资源分配

本节介绍大数据系统里的资源分配算法。因为一个大数据系统中有非常多的计算机,这些计算机有各种 CPU 和内存资源,同时又运行非常多的任务,所以,如何管理和调度系统的 CPU 和内存等资源,在集群中运行各种计算任务,就是我们要解决的资源分配问题。比如,我们希望能够给小的作业也分配一些资源,调度它运行,不要让大的作业把所有的资源都全部占用了。

YARN 和 Mesos

YARN 是专注于 Hadoop 计算框架的资源协调器,能够为 Hadoop 任务,如 MapReduce,Spark,分配资源。具体来说,它运行一个调度程序:给它一个作业,它就会根据一定的算法,计算出这个作业应该在哪里运行。也就是说,它能够根据一个任务的特点,决定这个任务应该放到哪个节点上运行。YARN 针对 Hadoop 的长时间分析作业进行了优化,比如减少计算和数据存储的距离,以最小化网络数据传输,提高性能。

随着大数据系统的发展,大数据处理框架不仅仅只是 Hadoop 了,而是出现了其它更多的计算框架,比如 Storm、Tez,为此,人们发明了 Mesos。目前,Twitter,Apple, Netflix 都有超大规模的 Mesos 部署。Apple 的 Siri 就是基于 Mesos 实现的。最大规模的 Mesos 管理了 30000 个节点,运行超过 25 万个容器。

Mesos 把各种业务作为其上的应用,实现统一资源管理和调度,目标是在计算资源有限的条件下,最大化节点利用率。具体来说,Mesos 实现系统的第一层调度,即向各应用程序框架(如 Hadoop、Spark)分配资源。然后,各个应用程序框架再实现第二层调度,即接收到 Mesos 分配来的资源后,在自己的框架内部,再进行分配和调度。

DRF 调度算法

我们下面来看具体的资源分配算法。该算法要解决的问题是:资源有限,如何分配给多个计算任务,即有效率,又能公平。

对单种资源的分配,为了确保公平,一般采用“最大最小公平”算法。这种算法就是: 尽量分给最穷的人,除非它不需要了。

大数据系统中有多种资源,因此不能简单地套用“最大最小公平”算法,而是要综合考虑任务消耗的多种资源来进行任务调度。具体来说,大数据系统中的资源包括计算资源(即 CPU)和 I/O 资源(内存和硬盘)。比如,我有一个系统,提供 9 个 CPU,18G 内存。此时,如果有两种任务:任务 A 需要 1 个 CPU,4G 内存,任务 B 需要 3 个 CPU,1G 内存。这时,我们如何给这两种任务分配资源呢?也就是说:我可以运行几个任务 A,几个任务 B 呢?

让我们来体会下面这种分配:运行 3 个任务 A,它们一共消耗 3 个 CPU,12G 内存;运行 2 个任务 B,它们一共消耗 6 个 CPU,2G 内存。这样就花掉所有的 9 个CPU,但剩 4G 内存。大家觉得这时候,任务 A 和任务 B 是“公平”的吗?

是公平的,而且这种分配方法兼顾了效率和公平。为什么呢?因为任务 A 占的内存虽然多(12G 内存,占比 12/18 = 2/3),但任务 B 占的 CPU 多啊(6 个CPU,占比 6/9 = 2/3)。也就是说,它们正好互补:它们在各自最需要的资源上分得挺多,都占到了总资源的 2/3,因此充分利用了系统资源,效率很高;同时,它们占到的总资源的比例都是 2/3,所以是公平的。

上面这个例子提示我们,要考虑不同任务对资源的不同需求,利用它们的互补性,进行资源分配,这样就能兼顾效率和公平。

这就是 Mesos 的调度算法:DRF 算法。DRF 就是“主导资源公平”,其中 D 是 Dominant,R 是 Resource,F 是 Fair。

我们首先定义“主导资源”?计算任务一般有两种:一种是计算密集型的,特别耗 CPU;一种是 I/O 密集型的,特别耗内存和硬盘。那么,如果一个任务是计算密集型的,要好多 CPU,它的主导资源就是 CPU。如果它是内存密集型的,它的主导资源就是内存。“主导资源”就是这么定义的。比如说我这个系统就 9 个 CPU,18G 内存。如果任务 A 需要 1 个 CPU,4G 内存,任务 B 需要 3 个 CPU,1G 内存。那么,任务 A 需要系统的 1/9 CUP,4/18 = 2/9 内存,因此,它要的内存相对较多,主导资源是内存;而任务 B 需要系统的 3/9 = 1/3 CPU,1/18 内存;因此,它要的 CPU 相对较多,主导资源是 CPU;

DRF 的基本思想是:即然计算密集型和内存密集型的任务,要求的主导资源不一样,那么,这两种计算是可以互补的。因此,我们就可以按照它们需要的主导资源来进行公平分配。就是说,让任务 A 的主导资源占比,和任务 B 的主导资源占比,差不多。这样,大家就都没有意见。

DRF 采用怎么的分配策略呢?就是把眼睛放在各个任务的主导资源上,比较它们获得的主导资源占比,而不是简单地比较它们获得的 CPU 或内存。如果任务 A 是 CPU 密集型的,任务 B 是内存密集型的,就拿任务 A 获得的 CPU 占总 CPU 资源的比例,和任务 B 获得的内存占总内存的比例,进行比较。如果谁的比例小,下面就给这个任务分配资源,也就是让它再新开一个任务。这样就能够让这两个任务的主导资源占比尽量公平。就是这样一个简单的分配方法。

那具体怎么分配呢?我们从 0 开始,一个一个任务地分配,每次总挑主导资源份额小的框架,给它分 1 个任务的资源。谁的主导资源比例占的少,就分给它。就这样就行

我们来看上面那个例子,DRF 是怎样分配的。

刚开始的时候大家都没有份额,所以大家的主导份额都是零。我就随机的分。假设先分给了任务 B。我们不能一下分给它太多,每次只分给它一个任务的资源。因为它一个任务就消耗掉我们 3 个 CPU,1G 内存,所以它就分别消耗掉 3/9 和 1/18 的 CPU 和内存。它的主导资源是 CPU,所以它的主导资源占比现在是 3/9 = 1/3。

这时候咱们比较任务 A 和任务 B 的主导资源占比。你看任务 A 还啥都没有呢,而任务 2 的主导资源已经有 1/3 了,所以我得给任务 A 分了。好,我们给它分了一个任务需要的资源。这时候它就花掉 1 个 CPU,4G 内存。它的主导资源是内存,所以它的主导资源占比现在就升到了 2/9。

咱们然后又比较任务 A 和任务 B 的主导资源占比。这时任务 A 是 2/9,任务 B 是 1/3。所以还要给任务 A 分,再给它一个任务需要的资源。这时它就一共分掉 2 个 CPU、8G 内存。这时候它的主导资源占比就到了 8/18 = 4/9 了。这比任务 B 的主导资源占比 1/3 就大了,所以,这时候如果还有资源的话,就再给任务 B 分了。我又给任务 B 分了一个任务要的资源,因此它涨到了 2/3,比任务 A 的 4/9 高了,所以再给任务 A 分,它就也涨到 6/9 = 2/3。这时 CPU 资源已经全部分完了,就终止。

大家看,最后各种资源都分配出去了,没有浪费,各个任务之间也比较公平。这就是主导资源分配算法的原理。

我们最后请大家做个课堂练习,看能不能分清楚。题目是:系统有 10 个CPU,20G 内存,任务 A 的 1 个任务需要 3 个 CPU,2G 内存;任务B 的 1 个任务,需要 1 个 CPU,5G 内存。请大家尝试一下。

因此,主导资源公平是让任务的主导资源公平。一个任务消耗系统的某种资源的比例高,这种资源就是这个任务的主导资源。主导资源公平算法是根据任务的主导份额进行资源分配的算法。主导份额就是 一个任务的主导资源 占系统该资源的份额。该算法总选择主导份额最小的任务,分配资源给它。如此迭代,直到资源分配结束。MESOS 用的就是这种算法。


Index Previous Next