《看论文》是计算机与软件工程领域论文分析系列文章。在本系列的每一篇文章中,我们都会阅读一篇来自OSDI、SOSP等的论文。会议论文在这里不做详细介绍,只是筛选论文的重点内容。如果您对相关论文非常感兴趣,可以直接点击链接阅读原文。本文是关于2018年OSDI期刊的论文——LegoOS:ADisseminated,DistributedOSforHardwareResourceDisaggregation[^1],是OSDI2018的最佳论文(AwardedBestPaper)。该论文实现了LegoOS操作系统可以将数据中心的单片服务器分解为通过网络连接的离散硬件,每个硬件由单独的控制器管理。由于现有的操作系??统都无法处理类似的场景,本文提出了一种分裂内核操作系统模型来管理和控制底层硬件资源。我们在集群部署服务的时候,经常会遇到资源碎片化的问题。这是因为在今天的集群中,单个CPU或内存无法直接对外提供服务。需要将不同的硬件组合成主机来运行用户提交的工作。负载,并且为了减少集群中可能出现的碎片化,很多云服务提供商会提供各种不同CPU和内存配比的主机[^2]:图1-GoogleCloud提供的主机类型除了常见的CPU和内存资源另外,集群中的GPU不能独立对外提供服务。我们需要将不同的资源插入到主板中,然后它们才能被应用程序使用。一旦物理机按照特定的规格组装起来,我们就需要用到虚拟化等技术。LegoOS可以更好的解决集群中的碎片化问题,提高整体的资源利用率。LegoOS是一个非常好的名字。它准确地描述了操作系统的许多特性。不同的硬件是系统中标准化的乐高积木。我们可以将这些硬件组合在一起,构建拥有海量资源的主机、集群甚至数据中心。应用程序使用的CPU、内存和存储资源可能来自使用网络连接的多个硬件。图2-LogoOS[^3]将计算机中的不同硬件解耦自然可以提高资源的利用率,但是使用网络连接硬件会带来两个难题。首先,基础设施支撑的网络会带来不确定性。和分布式系统一样,很多问题都是由网络不稳定引起的。如果网络是完全可靠的,那么我们就不再需要重试或者幂等来保证数据的一致性;其次是网络产生的延迟是CPU缓存或内存索引的1,000x~1,000,000x:工作延迟L1缓存引用0.5ns分支预测错误5nsL2缓存引用7ns互斥锁定/解锁25ns主内存引用100ns压缩1K使用Zippy的字节3,000ns通过1Gbps网络发送1K字节10,000ns从SSD*随机读取4K150,000ns从内存中顺序读取1MB250,000ns在同一数据中心内往返500,000ns从SSD顺序读取1MB*1,000,000ns磁盘寻道10,000,000ns从磁盘顺序读取1MB20,000,000ns发送数据包CA->Netherlands->CA150,000,000ns表1-2012年网络延迟比较4^限于物理条件,但是随着网络设备和计算资源的发展和进步,我们可以缓解网络延迟带来的很多问题,这不仅是因为硬件设备拥有更多的带宽和计算能力,还因为网卡和硬件设备的距离越来越近,在这篇文章中,我们将介绍分布式操作系统LegoOS的架构和设计思路,包括它如何拆分现有操作系统的各个模块,各个模块的功能,以及如何将这些不同的模块通过网络与外界连接起来。提供服务。架构和设计LegoOS使用新的操作系统架构来提供资源分离。内核的分离将操作系统划分为具有不同功能的模块。操作系统中的所有组件都通过网络进行通信,例如下图中的处理器,GPU、内存和NVM等硬件:图3-拆分内核架构[^5]拆分内核架构包含以下四个关键概念,分析这些概念可以帮助我们理解架构的特点:SplitOSfunctionalities——将传统操作系统的功能拆分成不同的监视器(Monitor),每个处理器将管理硬件组件,虚拟化和保护这些物理资源;分离内核中monitors之间的耦合很松散,他们会通过其他monitors访问远程资源;在硬件组件上运行监视器——集群中所有非处理器组件都会运行独立的监视器,不同的控制器可以使用不同的实现来管理自己持有的资源,这样可以更好地集成数据中心的异构硬件;跨非一致性组件的消息传递——独立的核心依赖以太网等公共网络层进行通信,不同组件之间的通信是通过网络进行的,我们只保证组件内部的一致性,应用才能达到预期的一致性操作系统保证;全局资源管理和错误处理(Globalresourcemanagementanderrorhandling)故障处理)——单个组件可以同时为多个应用程序提供服务,一个组件的故障也会影响到多个应用程序。为了管理集群中的不同组件,减少性能损失和可扩展性瓶颈,我们使用全局维度管理组件,通过冗余来处理组件故障;LegoOS的核心设计思想是将操作系统的功能拆分成多个模块,全局组件负责管理资源和处理错误。不同的监视器运行在不同的硬件上以管理硬件资源,消息将通过不可靠的网络在硬件之间传递,开发人员需要在应用中实现预期的一致性。资源管理LegoOS将硬件分为处理器、内存和存储三种类型,分别是pComponent、mComponent和sComponent。这三个硬件是独立的设备,具有不同的硬件控制器和网络设备。我们将在pComponent中使用CPU,在mComponent中使用DRAM,在sComponent中使用SSD或HDD。图4-LegoOS是LegoOS的一个组件,使用两层资源管理机制。在最顶层,使用了三个全局资源管理器来管理进程、内存和存储资源,分别是GPM(GlobalProcessManager)和GMM(GlobalMemoryManager)和GSM(GlobalStorageManager),这些全局资源管理器运行在普通Linux上servers会负责处理粗粒度的全局资源分配和负载均衡,它们会定期制定资源分配策略或者从monitor获取负载等信息,底层的所有monitor都会使用特定的策略和机制来管理本地资源。图5-两层资源管理机制本节我们将介绍LegoOS对三种不同组件的管理方式:pComponent、mComponent和sComponent。CPU在每个pComponent中,LegoOS使用简单的本地线程调度模型处理数据中心的应用程序,该模型使用几个CPU在后台处理核心相关任务,并将剩余的CPU分配给应用程序线程。当操作系统启动一个新的进程时,LegoOS会使用一个全局策略,将CPU分配给当前进程的线程,等待线程执行完毕。一般情况下,LegoOS中运行的所有线程都不会被抢占。图6-除了持有和管理CPU资源外,进程管理器LegoOS的进程监视器还配置和管理ExCache组件。当pComponent中的处理器错过访问ExCache时,LegoOS会从mComponent对应的缓存行中读取对应的缓存行,与其他缓存系统一样,ExCache也实现了FIFO和LRU缓存驱逐机制来保证缓存的时效性。MemorymComponent主要用来处理三类数据:匿名内存(堆和栈)、内存映射文件和存储缓冲区。它同时管理虚拟和物理内存空间的分配、释放和映射。每个应用程序进程都会使用一个或多个mComponents来保存数据,其中一个mainmComponent负责初始化加载进程和检查所有与虚拟内存管理相关的系统调用。每个进程的主要mComponent由全局内存资源管理器(GlobalMemoryResourceManager,GMM)统一分配。LegoOS采用两层机制管理分布式虚拟内存空间,其中主要的mComponent负责粗粒度、高层的虚拟内存分配决策,其他mComponent负责细粒度的虚拟内存分配。该策略可以减少虚拟内存操作的正常内存访问和网络通信。我们将虚拟内存空间的地址划分为多个粗粒度、固定大小的虚拟区域(VirtualRegion,vRegion)。每个虚拟区域中的内存地址属于一个mComponent,底层存储用户进程虚拟空间的区域信息。当一个应用程序进程想要分配虚拟内存空间时,它执行如下所示的步骤:图7-分布式内存管理pComponent将内存分配请求转发给主mComponent;mainmComponent使用它存储的vRegion的可用虚拟内存内存空间信息选择合适的区域分配内存;如果当前mComponent中没有合适的内存区域,就会向GMM发送内存分配请求,获取新的mComponent和vRegion;如果候选mComponent不是主mComponent,则主mComponent将分配内存的请求转发给对应的mComponent;接收到请求的mComponent将负责分配本地虚拟内存区域并初始化虚拟内存空间树;pComponent获取到mComponent信息后,会直接与上述过程中选中的mComponent进行通信,并在vRegion中申请内存;与虚拟内存相比,物理内存的管理相对简单。每个mComponent都会负责管理自己持有的物理内存,你也可以自定义虚拟内存和物理内存的映射关系。存储LegoOS在sComponent中实现了核心存储能力,通过vNode的抽象向下兼容POSIX,支持多层次的文件接口。用户可以在vNode挂载点正常存储目录、文件等数据,并进行正常的读写等操作。为了保持文件系统的简洁,我们在sComponent中采用了无状态设计,所有的I/O请求都必须包含请求所需要的所有信息,而且LegoOS的存储监视器也选择使用哈希表来存储文件名映射到文件,这样也可以减少sComponent查找文件所需的计算资源,最大限度的分离CPU、内存和存储资源。图8-分布式存储缓冲区因为我们既要将内存和存储资源分离,又要保证存储访问速度,所以操作系统原有的存储缓冲区(StorageBufferCache)也放在了mComponent中。当pComponent要读取存储节点中的数据时,会先检查是否有来自mComponent的缓存数据,只有当存储缓冲区不包含相应数据时,才会调用sComponent的接口获取数据并保存数据写入mComponent的缓冲区。综上所述,今天的软件和硬件与几十年前刚刚诞生时完全不同。各种分布式系统和复杂的软件需要各种各样的硬件支持,硬件的异构性也导致了资源问题。在一台机器上管理和调度变得更加复杂。作为OSDI2018年度最佳论文,在分布式操作系统LegoOS上的工作确实很有意思。由于网络设备的发展,可以将服务器上的硬件资源打散和重新管理。如今,数据中心已成为基础设施,分布式操作系统的设计变得非常有价值,这也可能改变我们未来组织和管理硬件的方式。本文转载自微信公众号“毫无逻辑”,可关注下方二维码。转载本文请联系公众号。
