预计阅读本页时间:-
8.2.7 负载平衡
需要讨论的有关多计算机调度的内容相对较少。这是因为一旦一个进程被指定给了一个节点,就可以使用任何本地调度算法,除非正在使用群调度。不过,一旦一个进程被指定给了某个节点,就不再有什么可控制的,因此,哪个进程被指定给哪个节点的决策是很重要的。这同多处理机系统相反,在多处理机系统中所有的进程都在同一个存储器中,可以随意调度到任何CPU上运行。因此,值得考察怎样以有效的方式把进程分配到各个节点上。从事这种分配工作的算法和启发则是所谓的处理器分配算法(processor allocation algorithm)。
多年来已出现了大量的处理器(节点)分配算法。它们的差别是分别有各自的前提和目标。可知的进程属性包括CPU需求、存储器使用以及与每个其他进程的通信量等。可能的目标包括最小化由于缺少本地工作而浪费的CPU周期,最小化总的通信带宽,以及确保用户和进程公平性等。下面将讨论几个算法,以使读者了解各种可能的情况。
1.图论确定算法
广告:个人专属 VPN,独立 IP,无限流量,多机房切换,还可以屏蔽广告和恶意软件,每月最低仅 5 美元
有一类被广泛研究的算法用于下面这样一个系统,该系统包含已知CPU和存储器需求的进程,以及给出每对进程之间平均流量的已知矩阵。如果进程的数量大于CPU的数量k,则必须把若干个进程分配给每个CPU。其想法是以最小的网络流量完成这个分配工作。
该系统可以用一个带权图表示,每个顶点是一个进程,而每个弧代表两个进程之间的消息流。在数学上,该问题就简化为在特定的限制条件下(如每个子图对整个CPU和存储器的需求低于某些限制),寻找一个将图分割(切割)为k个互不连接的子图的方法。对于每个满足限制条件的解决方案,完全在单个子图内的弧代表了机器内部的通信,可以忽略。从一个子图通向另一个子图的弧代表网络通信。目标是找出可以使网络流量最小同时满足所有的限制条件的分割方法。作为一个例子,图8-24给出了一个有9个进程的系统,这9个进程是进程A至I,每个弧上标有两个进程之间的平均通信负载(例如,以Mbps为单位)。
在图8-24a中,我们将有进程A、E和G的图划分到节点1上,进程B、F和H划分在节点2上,而进程C、D和I划分在节点3上。整个网络流量是被切割(虚线)的弧上的流量之和,即30个单位。在图8-24b中,有一种不同的划分方法,只有28个单位的网络流量。假设该方法满足所有的存储器和CPU的限制条件,那么这个方法就是一个更好的选择,因为它需要较少的通信流量。

直观地看,我们所做的是寻找紧耦合(簇内高流量)的簇(cluster),并且与其他的簇有较少的交互(簇外低流量)。讨论这些问题的最早的论文是(Chow和Abraham,1982;Lo,1984;Stone和Bokhari,1978)等。
2.发送者发起的分布式启发算法
现在看一些分布式算法。有一个算法是这样的,当进程创建时,它就运行在创建它的节点上,除非该节点过载了。过载节点的度量可能涉及太多的进程,过大的工作集,或者其他度量。如果过载了,该节点随机选择另一个节点并询问它的负载情况(使用同样的度量)。如果被探查的节点负载低于某个阈值,就将新的进程送到该节点上(Eager等人,1986)。如果不是,则选择另一个机器探查。探查工作并不会永远进行下去。在N次探查之内,如果没有找到合适的主机,算法就终止,且进程继续在原有的机器上运行。整个算法的思想是负载较重的节点试图甩掉超额的工作,如图8-25a所示。该图描述了发送者发起的负载平衡。

Eager等人(1986)构造了一个该算法的分析排队模型(queueing model)。使用这个模型,所建立的算法表现良好而且在包括不同的阈值、传输成本以及探查限定等大范围的参数内工作稳定。
但是,应该看到在负载重的条件下,所有的机器都会持续地对其他机器进行探查,徒劳地试图找到一台愿意接收更多工作的机器。几乎没有进程能够被卸载,可是这样的尝试会带来巨大的开销。
3.接收者发起的分布式启发算法
上面所给出的算法是由一个过载的发送者发起的,它的一个互补算法是由一个轻载的接收者发起的,如图8-25b所示。在这个算法中,只要有一个进程结束,系统就检查是否有足够的工作可做。如果不是,它随机选择某台机器并要求它提供工作。如果该台机器没有可提供的工作,会接着询问第二台,然后是第三台机器。如果在N次探查之后,还是没有找到工作,该节点暂时停止询问,去做任何已经安排好的工作,而在下一个进程结束之后机器会再次进行询问。如果没有可做的工作,机器就开始空闲。在经过固定的时间间隔之后,它又开始探查。
这个算法的优点是,在关键时刻它不会对系统增加额外的负担。发送者发起的算法在机器最不能够容忍时——此时系统已是负载相当重了,做了大量的探查工作。有了接收者发起算法,当系统负载很重时,一台机器处于非充分工作状态的机会是很小的。但是,当这种情形确实发生时,它就会较容易地找到可承接的工作。当然,如果没有什么工作可做,接收者发起算法也会制造出大量的探查流量,因为所有失业的机器都在拼命地寻找工作。不过,在系统轻载时增加系统的负载要远远好于在系统过载时再增加负载。
把这两种算法组合起来是有可能的,当机器工作太多时可以试图卸掉一些工作,而在工作不多时可以尝试得到一些工作。此外,机器也许可以通过保留一份以往探查的历史记录(用以确定是否有机器经常性处于轻载或过载状态)来对随机轮询的方法进行改进。可以首先尝试这些机器中的某一台,这取决于发起者是试图卸掉工作还是获得工作。