31

Google 如何设计与构建超大规模的软件系统

 5 years ago
source link: https://www.infoq.cn/article/4YwNr8-ObhR0kJtZyUhs?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

导读:最近,在谷歌工作近十年的高级软件工程师 Onufry,以 Brog 为例,讲解了 Google 这样的大公司里如何设计与建造超大规模的软件系统。Borg 是谷歌设计的一个集群管理器,它负责对来自于几千个应用程序所提交的 job 进行接收、调试、启动、停止、重启和监控,这些 job 将用于不同的服务,运行在不同数量的集群中,每个集群各自都可包含最多几万台服务器。Borg 的目的是让开发者能够不必操心资源管理的问题,让他们专注于自己的工作,并且做到跨多个数据中心的资源利用率最大化。

根据我的经验,大多数的超大规模系统都拥有以下特点:

  • 都是从一个相对较大的、较复杂的、但还不算是超大规模的系统内核开始做起。
  • 随着需求的快速迭代,该系统的复杂度显著增大,并且局部的逻辑也变得复杂起来。
  • 随后在一些高级工程师的带领下,对系统进行多次的大规模重构,这些高级工程师通常对该系统有更多的了解。

我对一些超大规模的系统有过较深入的了解,在这些超大规模的系统中,最著名的莫过于谷歌的 Borg 系统了。从部署方面来看,Borg 系统几乎涵盖了谷歌所有的数据中心;从复杂度方面来看,Borg 系统估计是从 2000 年开始开发一直持续发展到现在这样子的。因此无论从“部署“还是“复杂度”方面 Borg 系统都算得上是超大规模系统。

大而复杂的系统内核

与大多数复杂的系统一样,Borg 最初的设计理念也是十分复杂的,但其实远没有今天这么复杂。起初它的核心思想可以简单用一页文字来描述。简要总结如下:

  • 我们希望能够自动地、动态地将所有的任务调度到由数千台独立机器组成的机器单元中。
  • 调度工作将由一个中央的“主服务器”完成,它负责维护整个机器单元的运行状态(作为主副本复制状态)。
  • 待工作的任务将指定它们对 CPU、磁盘和内存的要求,以及它们的优先级。“主服务器”将利用该优先级对所有的任务进行合理的排序,暂时腾出低优先级任务的资源给高优先级的任务使用。
  • 我们将采取超额预定资源的机制,将低优先级的任务放入那些虽然被高优先级任务预定但是还未使用的资源中。
  • 对任务资源占有量的评估,以及对超额配置所导致的资源短缺问题的响应,将由一台机器上的代理(Borglet)来完成,该代理需要拥有超级用户的权限。

其他更多关于 Borg 系统的细节信息此处省略不讲。至此我已经可以在长达一个小时的讲座中向计算机科学专业的同学讲述完 Borg 系统的所有基本思想。

该项目最初的想法可能是十年前由那些拥有 WorkQueue 工作经验的工程师提出来的,他们起初就已经清楚地知道自己想要实现的系统是什么样的。

添加更多的需求

随后就出现了系统需求的大规模增长。同时也添加了 SSD 作为一种额外的资源。即便后来证明最初的假设是错误的,即如果一个机械硬盘发生故障,那么所有使用该机械硬盘的任务都应该被认为是处于死亡状态。因此该系统中便添加了允许幸存磁盘丢失的代码路径,以用来重新调度资源,更好的组织机器单元。

此外,也围绕“主服务器”和 borglet 的核心思想构建了新的生态系统,它是一个内部检查的工具,也是一款配置语言。它可以自动化预测任务对资源的需求,而不再需要人们在配置中手动输入,同时还可以用来配额管理系统、跨机器单元调度,以及更多其他的功能,在这其中的每个功能都是为了满足特定需求而构建的。

最终,系统也在我们的开发过程中得到了改进。最初每隔一秒计算一次的资源核算机制逐渐被基于系统内核的机制(cgroups)所取代。另外,我们的用户也抱怨道,当系统有错误出现时,他们并不能完全理解他们所看到的内容,因此我们便彻底的检查了之前所有的错误提示,并对错误提示进行了大幅改进。在 Borg 系统的“主服务器”和 borglet 级别添加了只读的用户界面展示,然后随着系统的改进,最终构建出了可以跨机器单元的用户界面展示。

所有的这些都是在拓展 Borg 的主要系统或功能,也都将使其规模变得更大,系统变得更加复杂,尽管它们并不一定能使 Borg 系统变得更加深入。也就是说,你仍然可以仅仅通过对所有这些功能和想法的简单了解来推断其核心系统和 API。

主要的重构

大多数从事 Borg 系统工作的初级工程师都不是很了解整个 Borg 系统。他们可能在 borglet(我工作的地方)工作,也可能拥有更加具体的工作,比如:Borg 系统的内存管理系统,在该内存管理系统中添加新的功能。虽然他们对 Borg 系统的核心思想有过简单的了解,但他们可能从未接触过 Borg 系统真正的核心代码,更不用说任何独立的系统了。

然而,我认为这样一个超大规模系统的持续进步还是主要取决于几个高级工程师,他们相比之下更了解整个系统,也更加清楚系统的大部分功能是如何工作的,并且能够意识到,在新的要求和需求下,系统中的哪些部分会发生怎样的变化。如果由于某些原因导致系统的某些内容无法拓展,不论是由系统使用规模的极速扩大导致,还是由过多需求的增加导致系统的可维护性降低,最终可能都需要对该系统整体的体系结构进行大规模的重构来解决。

请注意,我们这里提到的 “高级工程师的全局重构” 和 “本地的代码重构” 之间的界限并不难分辨。这两种重构都会导致 Borg 系统发生许多变化,当然我们也可以分别为他们命名,它们其中也都可能包含有主要的架构的变化,比如:“主服务器”,将它的状态变为 Paxos,或者 Borglet 的变化。因此,我认为一个系统的全局体系架构的重构能力,对于这个庞大而复杂的系统是否能够持续保持增长至关重要,不过当然还是要保证系统在全局重构中不至于整体崩溃。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK