仓库规模操作系统的背景之操作系统

目录

前言

操作系统

经典分布式操作系统

数据中心操作系统

问题和挑战

效率

安全

观察

新抽象的可行性

总结


前言

本文是Malte Schwarzkopf的博士论文《Operating system support for warehouse-scale computing》一个翻译版本,融入了作者自身的经验和理解,读者如果想阅读原文,可以访问:http://people.csail.mit.edu/malte/pub/dissertations/phd-final.pdf

编写本文的目的是提供一个中文版本的文档,同时为自己保留一份学习笔记,供日后事件参考以及优化调整。当然,优化调整部分不能更新在公网,因为笔者同一时间在公司内网发布了改文章,相应部分只会更新在公司内网的文章中。

操作系统

前面章节中的例子说明了典型的大型数据中心的工作负载,同时它们的细节不同,所有分布式应用程序都依赖于本地的和分布式的底层系统软件。在这一节中,我考虑在数据中心操作系统的性质和作用。操作系统提供硬件抽象,多进程,资源共享以及程序和用户之间的安全隔离。这种操作系统概念在六十年的过程中进化,主要驱动力就是资源共享效率。

起源:早期的机器只相当于原始的引导加载程序,例如“某个特定的引导程序”。 在图灵的自动化计算引擎ACE上的一种不变的初始次序,或者在EDSAC上硬连线的初始化命令。很快大家都意识到,由系统软件运行多个用户程序对于高效的使用机器是至关重要的。

因此,设计了监视器(或监控器)程序自动按顺序运行多个作业(“批处理”)。这样的批处理监视器开启了多道程序设计(multiprogramming

),但没有支持交互系统的使用。机器的时间共享能够使用多个程序共享处理器看似并行执行,但是需要一种机制来中断当前计算并跳转到监督器中。早期共享系统,如CTSS和Titan监控器,作为一个批量监控器和交互式操作系统的组合:远程终端交互式的访问计算机,但处理器在空闲时才运行传统的批处理作业。这有点类似于数据中心批处理和服务之间的资源共享,其目的是回收服务的空闲资源尝试性用于批处理作业。这里需要注意的是,当批处理作业运行过程中被优先级更高的服务或者批处理中断时,可以选择“暂停”或者“结束”作业,这要视情况而定。笔者以前设计的视频/图像高性能计算平台选择的就是结束,因为这种方案实现比较简单,受限于现场环境没有比较好的“暂停”方案,利用资源空闲期赌博性的执行批处理作业,万一成了呢!

时间共享产生了许多在今天的操作中使用的保护和隔离机制:段、虚拟内存、保护环(protection ring)和一个具有ACL的单个文件系统命名空间。然而,所有这些抽象专注于在多个程序和用户之间安全地共享一台机器。后面,我解释如何分布在多台机器上。

经典分布式操作系统

早期的计算只限于一台带有远程终端的通用机器。然而,跨机器的分布式操作的研究早在20世纪60年代中期,当Fuchel和Heller在两个数据中心6600台机器之间共享一个扩展的核心存储(extended core store ECS)。他们的“基于ECS的操作系统” 通过把数据交换到ECS使进程在机器之间迁移成为可能,并且引入了缓冲的I/O和容差故障。其实这一点比较好理解,就好像现在的虚拟机关机后再把虚拟机文件拷贝到另一个主机上启动就可以复原,当然进程迁移要比虚拟机迁移要轻量一些。

然而,直到20世纪70年代末,当小型机和个人工作站的成本、稳定性变得可以接受,同时出现相对廉价的局域网技术,几乎没有一家机构运行多台计算机。当第一次可能拥有大量连接的计算机时,资源池的概念触发分布操作系统的发展(见表2.5)。

2.5:典型的分布式操作系统及其属性。

早期分布式操作系统:HYDRA的C.mmp机是其中之一最早的分布式操作系统。C.mmp由十六个具有共享时钟和共享存储的PDP11机器组成,通过交叉连接。尽管它相当像C.mmp的对称多处理(Symmetrical Multi-Processing SMP)架构,HYDRA开创了分布式操作系统几个关键的原理,比如使用分布式对象作为主要抽象,容忍机器和连接故障,以及基于能力(capability-based )的保护。

Medusa,CMU早期的另一个分布式操作系统,目标是Cm*架构,以10为簇连接50个“计算模块”。由于在模块之间通信成本高,Medusa强调了局部性和限制性共享。Medusa是以显式消息传递为中心的分布式操作系统的先例之一,并抽象三类对象暴露给用户,包括(i)页、(ii)管道和信号量,和(iii)文件、“特别工作组(task forces)”和描述符列表。由于硬件的限制,Medusa只提供了适度和粗粒度的保护:通过描述符访问对象,这些描述符驻留在受保护的描述符列表中 。关于特别工作组原文是task forces,我的理解是具备较高权限的一些进程/线程之类的东东。

消息传递系统:Rochester Intelligent Gateway(RIG)的Aleph OS、Acdent和Mach是80年代初开发的三个分布式操作系统,他们都是基于利用端口的消息传递(进程消息队列)。

Aleph的设计很简单:端口不受保护,全局标识符被当作数据对待,消息传递不是完全透明的,即用户必须了解消息接收者的定位(这句话笔者也不太理解想,所以也找不到好的翻译词语)。它的使用场景是提供小型计算机网络,并充当大型、分时复用机器的“网关。

Accent重新设计RIG的原理,围绕虚拟内存、完全透明和一个对象风格编程模型。Accent有一个磁盘上的“页面存储”用于持久存储,内核将页面加载到内存中以响应消息。为了优化较大消息传输,Accent使用copy-on-write重新映射到主机地址空间,跨机器边界通消息过懒检索(我的理解是需要时在检索)远程存储来实现。Accent编程人员使用接口描述语言IDL编译器生成的高级的过程调用接口,类似的IDL概念存在于后来许多的分布式和微内核操作系统中,以及在今天的数据中心RPC库中,例如Protocol Buffer。

Mach使用了Accon的原理,并扩展它们支持多处理器和兼容Unix。它引入了线程,允许共享任务的(进程的)端口,可以用户空间共享内存做同步,并支持外部用户空间页。Mach作为一个微内核架构具有影响力,但作为一个分布式操作系统,它因为全透明的消息抽象的通信成本比计算昂贵得多而最终受到阻碍。

其他分布式操作系统提供了更接近传统系统调用API的接口。例如,LOCUS和VAXCluster在VAX机器上创建分布式系统,扩展VAX/VMS和Unix范例用于支持分布式。LOCUS在共享存储的副本文件上支持嵌套事务,每个副本所在本地操作系统强制执行互斥。LOCUS通过分布式命名目录定位文件,对它们的访问是完全透明的。还有,LOCUS支持的动态集群节点,并在网络分区依然保持可用,在修复时使用协调协议合并分歧状态。相比之下,VASCluster组合了一些VAX机器和专用存储节点成为单个安全域。决定是由节点投票产生的,出现分区时,少数节点分区不可用。不像LUCUS,分布式存储中的文件操作依赖于分布式锁管理器。

基于RPC的系统:20世纪80年代后期,出现了几个大型分布式操作系统项目,例如V、Sprite和Amoeba,它们使用远程过程调用(RPC)模型,没有直接暴露消息格式。然而,他们的方法不同:Sprite和V目标是每个用户工作站(per-user workstation)模型,使用进程迁移来利用空闲资源。Sprite基于共享文件系统(类似LOCUS),强调了Unix的兼容性(比如Mach),并且没有开放支持分布式应用程序的特殊特性。相比之下,Amoeba假设所有用户共享基于分布式对象和能力(如Chorus)的集中处理池。它有一个微内核体系结构,具有系统范围用户空间的服务和完透明的远程操作。

Plan9Plan9是在20世纪90年代初作为UNIX的概念继承者开发的。对于透明的分布式操有更普遍的文件抽象和内核级支持。Plan9目标是网络终端用户的工作站,并提倡以文件为中心,允许远程资源挂载到每个进程命名空间。因此,通过命名空间挂载,本地应用程序可以透明地与远端进程、设备和其他资源交互。

Plan9从未被广泛采用,但它的一些关键概念随后出现在操作系统:Linux中目录结构的procfs是一个以暴露文件的方式控制钩子的例子;容器使用的内核命名空间是每个进程一个命名空间的例子;和基于JSON的REST API类似于Plan9的文本消息传递。

为什么分布式操作系统不能被采纳?分布式操作系统开发超过了30年,当时他们的特征很少出现在现代操作系统中。我相信分布式操作系统未能广泛采用的原因有三:

  1. 没需求.20世纪80年代的工作负载很少需要多台机器的资源,复杂的分布式操作很难让他们体现价值。经典的分布式操作系统是可行的技术,但是没有任何迫切的使用场景。
  2. 单机性能增益战胜了并行计算。原则上可以利用并行性提高性能的工作负载通常在大型、昂贵、分时复用的机器上运行也很好。对于桌面工作负载而言,并行计算很难获得收益,因为更快的工作站很快就可用了。
  3. 计算和网络速度之间的差异更有利于本地计算。尽管随着网络技术的不断完善,本地计算速度仍然大大超过了跨机的通信速度。事实上,这个差距在80年代末扩大了:时钟速度迅速增加,但网络延迟仅缓慢地降低,使得远程消息传输变得越来越昂贵。

然而,在现代数据中心的环境下,所有这些条件都发生了重大变化:

  1. 工作负荷已经需要分布式。数据中心工作负载从根本上需要分布式规模的扩容和容错能力,以及面对大量机器分布式是必要性而非可选。
  2. 单机性能提升放缓。工作负载不再依赖机器变得越来越快。此外,基于请求和数据并行的工作负载需要超过单个机器资源的网络和存储带宽。
  3. 网络性能相对于计算速度增加。20世纪80年代计算速度超越网络速度的趋势在90年代开始逆转:网络带宽仍然增加并且接近DRAM带宽,并且网络延迟再次降低。

因此,数据中心运营商已经开发了分布式基础设施系统满足这些需要。在下一节中,我将在概念上的“数据中心操作系统”中讨论他们的作用。

数据中心操作系统

在仓库规模的数据中心中看到的工作负载需要跨机器协作、资源管理、数据共享和身份验证。专用分布式基础设施系统服务于更上层的用户应用程序。用户应用程序依赖于分布式基础设施系统,就像传统应用程序依赖于本地操作系统一样:它们假设分布式基础设施服务总是可用的,并且依赖它们实现关键功能(例如,持久存储)。因此,分布式基础设施系统充当数据中心操作系统。

表2.6列出了传统单机操作系统功能的分布式基础设施等价物。例如,集群管理器在启动、调度和终止任务时形成特权内核的分布式等价物。集群管理器还执行准入控制,并在不同的任务之间划分硬件资源(另一个传统的内核职责)。同样,分层分布式文件系统是传统本地和网络文件系统的可伸缩等价物,旨在公开类似的存储抽象。

表2.6:许多经典的本地操作系统组件在当前的分布式基础设施系统中具有等价物,它们构成了事实上的数据中心操作系统。

然而,这个列表仅仅有点粗略的近似。一些分布式基础设施没有直接的本地操作系统等价物:非结构化存储系统,如blob存储和键值存储,最多可以视为绕过内核文件系统或在其上构建的数据库后端的等价物。

在其他情况下,类比更加微弱:例如,并行数据处理系统在某些方面是多线程库的分布式等价物,但是通常具有更高层次的编程模型和内置的容错机制。同样,用于分布式锁定、资源和服务发现的协调服务在传统操作系统中也有类似的前辈(例如,UNIX/etc文件系统和Windows注册表),但是协调服务必须使用Paxos或Raft等算法来实现分布式一致性,以便在多个机器之间提供一致视图。可以这么理解:单机的多个服务一般采用文件系统/注册表等实现全局配置,但是对于分布式系统来说,全局的配置也是通过每个单机的文件系统/注册表实现,但是要通过一致性算法实现每个单机的文件系统/注册表的内容一致。当然了,我们肯定不能直接访问协调服务的文件系统,而是访问协调服务提供的接口,这样解释是为了方便理解。

鉴于这些相似之处,人们可能会想知道为什么这些系统不是从经典的分布式操作系统抽象的基础之上建立,开发人员之所以设计自己的抽象并从头构建新系统,有两个原因:

  1. 灵活性:数据中心栈通常有几个专用的系统,例如Facebook栈中不同的缓存系统。这些系统不是众所周知的长期用例发展而来,而是为了响应紧急的业务需求。从零开始构建系统可以快速演进,独立于更新很慢的广泛使用的标准、通用抽象或操作系统扩展。
  2. 不可用性:经典分布式操作系统未来不再被使用,它们的抽象在当前的操作系统中不存在或者没有被采用。因此,没有广泛部署的用于构建分布式系统的抽象可用。

数据中心操作系统的这种演进产生了一系列系统,这些系统对于它们的特定用例和部署工作得很好。然而,这并不是没有它的缺点,导致几个问题和挑战,我接下来将讨论。

问题和挑战

与单机操作系统和经典的分布式操作系统不同,组成数据中心操作系统的基础设施服务集合实际上在某种程度是点对点的,并且分布式操作系统组件缺乏统一性和可组合性。

表2.7通过比较当前数据中心基础设施软件和经典的分布式操作系统来说明这一点。在高层上,显然,经典的分布式操作系统在抽象上力求统一,期望它们被各种各样的应用程序使用。

表2.7:当前用在“数据中心操作系统”的分布式基础设施系统和经典分布式操作系统的比较。

然而,数据中心操作系统中的每个系统都有自己的方法、API和抽象。接下来,我将讨论这种差异对数据中心基础设施的效率和安全性的影响。

效率

不同的分布式基础设施组件使用并公开它们存储和处理的数据的表示:例如,考虑HDFS文件vs Spark RDD vs BigTable的三维映射中的值。所有这些都包含任意的二进制数据,但是不复制数据就不可能从一个表示转换为另一个表示。

这不仅导致不必要的拷贝,而且使不同系统之间的数据共享复杂化:不存在共享只读内存映射的分布式等价物,例如,在Web服务器、分布式文件系统和分析作业之间共享的一组图片。实际上,由于这个原因,数据中心基础设施最终得到了多个、不协调和冲突的数据缓存实现:本地机器操作系统缓冲区缓存、memcached之类的键值存储以及Tachyon之类的文件系统缓存覆盖。

现有的分布式系统的抽象也常常缺乏对内省(计算机程序在运行时检查对象类型的一种能力,通常也可以称作运行时类型检查)的支持。如果不知道特定于系统的API细节,则很难或不可能找到数据的位置、它们的持久性或它们副本的位置。然而,这些信息对于跨系统优化可能是至关重要的。例如,从缓存在另一台机器内存上的数据集读取比从本地磁盘读取更有效,但是写入可能需要在不同的故障域中进行复制。

最后,大多数当前数据中心管理资源的基础设施系统都有一个中心化控制器:例如Borg中的BorgMaster、HDFS中的NameNode和Spark中的Spark master。“高可用”是通过控制器的多副本实现的,不以分布式方式管理资源及其元数据。

因此,数据中心操作系统的效率取决于具有更加统一、支持内省和分布式的资源管理抽象。实际上,未来的数据中心硬件趋势——例如RDM的预期广泛部署——只会加剧这种需求。

安全

命名还与资源存在的可否认性密切相关:如果用户在键值存储中获得数据项的键,那么他们可以认为它存在。大多数现有系统没有名称空间,因此不能划分资源发现(比如只能看到自己所在命名空间的资源)或选择性否认绝资源存在(即使资源存在但是也看不到),无论它们是基于能力权限的还是基于ACL的。例如,memcached命名空间必须使用键前缀或后缀实现,并且HDFS目录列举只能通过UNIX文件系统权限表达拒绝。

当前的访问控制方案不仅过于粗粒度,而且缺乏一致性:每个系统有它们自己主体(例如,HDFS中的用户/组、Mesos中的用户和框架工程)、身份验证方法和限制属性的自定义概念。由于每个系统都从头开始实现访问控制,而且常常不完整,因此多个用户访问同一数据中心操作系统的组件的端到端安全性和隔离性通常很差。

最后,数据中心运维人员需要审计资源访问,不幸的是,当前系统要么根本不支持审计,要么仅仅支持定制的审计日志(例如,在HDFS中)。

经典的分布式操作系统通过依赖能力保护解决了许多这些问题,主要有两个原因。首先,虽然ACL和权限都可以被分布式管理,但是由于它们不需要使用ACL和能力对主体进行身份验证,所以它们适合分布式使用。第二,能力权限很好地映射到分布式系统中常见的数据流抽象。它们传统的缺点——复杂的编程模型和撤销的困难——在完全分布式的环境中影响不大。

显然,当前数据中心基础设施将受益于使用统一方法实现的更细粒度的保护和访问控制。因此,在数据中心环境中,良好的安全性和细粒度保护需要基于广泛的、细粒度的能力访问控制。

观察

对当前充当操作系统的数据中心系统软件的调查表明,有很大的改进潜力。确实,其他人也提出了类似的观点,并呼吁在数据中心操作系统中采用更统一、可重用和可组合的抽象和机制。

我的主要观点是,经典的分布式操作系统已经解决了上述许多问题——尽管是在稍微不同的上下文中——因此,我们可以并且应该向他们学习。因此,我们可能能够识别新的通用分布式操作系统抽象,这些抽象为当前的数据中心操作系统组件提供更加统一、有效和安全的资源管理和访问控制。

下一节将研究我们是否可能希望仅通过少量的抽象来支持现有数据中心应用的需求。

新抽象的可行性

对于一个数据中心操作系统来说,新的资源管理和访问控制抽象的概念必然会引起复杂性的问题:需要多少这样的抽象来支持通用应用程序,我们能够让应用程序来仅使用新的抽象吗?后者从安全性角度来看很有趣:只使用新抽象的应用程序不可能绕过它们的访问控制机制。

关键问题是,一小组操作是否足以有效地支持数据中心应用程序——或者甚至仅仅支持性能敏感的“数据平面”。如果是这样,那么数据中心操作系统的清洁模型似乎是可行的。下面,我提出一个探索性的研究,提供了对这个问题的一些见解。

实验:我使用Linux系统调用作为典型数据中心应用程序调用的操作系统功能的(原始)代理,我研究了四个应用程序:Hadoop MapReduce、Redis键值存储、Zookeeper协调服务和GraphChi图形计算框架。使用典型的工作负载对每个应用程序进行基准测试,并使用strace监视其系统调用调用。当然,这无法捕获所调用的高级分布式操作,但是它给出了一个指示,表明一个干净的模型必须提供最小的本地操作系统功能。

图2.8:公共数据中心应用程序上的探索性系统调用跟踪的结果。

图2.8a比较了不同应用程序调用的不同Linux系统调用的总数。对于Hadoop,我测量了典型Hadoop集群的四个不同的系统组件:(i)MapReduce JobTracker(“Hadoop-JT”),(ii)MapReduce TaskTracker(“Hadoop-TT”),(iii)HDFS NameNode(“Hadoop-NN”),(iv)HDFS DataNode(“Hadoop-DN”)。

在Java虚拟机(JVM)上运行的Hadoop使用最大数量的85个不同的系统调用;然而,同样基于Java的ZooKeeper只使用28个,而基于C/C++的Redis和GraphChi分别使用19个和20个不同的系统调用。这表明操作系统功能的使用范围主要并不取决于编译器或运行时,而是以数据为中心的应用程序的固有属性。如果只考虑通常调用的系统调用,则系统调用数量将进一步收缩,所谓常用系统调用要么(i)占所有调用数量的1%以上,要么(ii)在每个应用程序级请求(即“数据平面”)上至少发生一次。实际上,除了Hadoop之外,所有应用程序都有五个或更少的“公共”系统调用(图2.8a)。

在图2.8b中,我按类别对系统调用进行分组。可能毫不奇怪,主要的类别是I/O、同步和资源管理,其中I/O系统调用占主导地位,正如我们在分布式、数据密集型应用程序中所期望的那样。

图2.8c显示了每个系统调用的相对频率,它们占总调用的1%以上。系统调用调用总数的35-50%是read(2)或write(2);接下来最频繁的调用是与Linux的futex(“fast user-space mutex”)同步机制相关的那些。总而言之,总共有11个系统调用覆盖了所进行的调用的99%。这是326个Linux系统调用的一个小子集,表明在这些数据中心应用程序的“数据平面”上不需要Linux系统调用API的全量。

观察:虽然这些结果暗示许多数据中心应用程序只使用一小组本地操作系统抽象,但是应该谨慎。Linux中提供的许多额外系统调用仅用于向后兼容,很少使用,而其他系统调用可能仅用于很少触发的代码路径(例如,用于错误处理),甚至像ioctl(2)和fnctl(2)这样的其他系统调用都具有高度过载的语义。我的理解是,像ioctl(2)这样的系统调用可以被很多种设备实现,同时每种设备还有不同的请求命令,看上去都是相同的系统调用,背后的意义却大不相同。

然而,这些结果是令人鼓舞的:他们建议构建一个新的分布式数据中心操作系统是可行的,其抽象足以支撑通用的分布式应用程序。这具有双重优点:(i) 评估建立在新抽象之上干净的“数据平面” 的性能变成可能,(ii)撤销对遗留操作系统设施的访问,防止潜在的安全漏洞和旁路 (例如,通过pipe(2))。

总结

在本节中,我解释了操作系统的发展是如何通过共享底层硬件来寻求更高资源利用率的。我调查了二十世纪八十年代的经典分布式操作系统,它们没有得到采用,可能是因为它们的设计超前当时的工作负载。

然后,我发现现代数据中心事实上已经由当今使用的多个分布式基础设施系统组成了分布式操作系统。然而,这种方法有几个缺点,并且面临效率和安全挑战:

  1. 我发现分布式基础设施系统缺乏经典分布式操作系统的统一抽象。
  2. 因此,数据中心操作系统的效率总体上受到损害:数据跨系统表示必须复制和转换、共享需要副本,并且系统利用新的硬件范例并不容易。
  3. 缺乏单个访问控制方案降低了数据中心操作系统的端到端安全性:系统有自己的身份验证概念,使用可变粒度的访问控制原语,并且通常不可能进行选择性委托。

因此,在数据中心OS上下文中考虑来自经典分布式操作系统的想法似乎很有用。的确,我借助于一项探索性的研究论证,数据中心应用的狭隘和统一的需求使得设计一套新的分布式操作系统抽象是可行的,它完全支持这种应用的“数据平面”(2.2.4)。

在下一节中,我将研究数据中心OS的特定部分:集群管理器的调度器,它决定将两个应用程序任务放在共享集群基础结构中的何处。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值