操作系统模型与乐高积木 · OSDI 2018

『看看论文』是一系列分析计算机和软件工程领域论文的文章,我们在这个系列的每一篇文章中都会阅读一篇来自 OSDI、SOSP 等顶会中的论文,这里不会事无巨细地介绍所有的细节,而是会筛选论文中的关键内容,如果你对相关的论文非常感兴趣,可以直接点击链接阅读原文。

本文要介绍的是 2018 年 OSDI 期刊中的论文 —— LegoOS: A Disseminated, Distributed OS for Hardware Resource Disaggregation1,它是 OSDI 2018 的最佳论文(Awarded Best Paper),这篇论文实现的 LegoOS 操作系统可以将数据中心中的单体服务器拆分成通过网络连接的分散硬件,其中每个硬件都由独立的控制器管理。因为现有的操作系统都无法处理类似的场景,所以这篇论文提出了一种分离内核(Split kernel)的操作系统模型来管理和控制底层的硬件资源。

我们在集群中部署服务时经常会遇到资源碎片化的问题,这是因为在今天的集群中,单独的 CPU 或者内存无法直接对外提供服务,不同的硬件需要组合成主机才能运行用户提交的工作负载,而为了减少集群中可能存在的碎片化,很多云服务厂商都会提供 CPU 和内存比例不同的多种主机2

google-cloud-machine-types

图 1 - 谷歌云提供的主机类型

除了常见的 CPU 和内存资源之外,集群中的 GPU 也无法独立对外提供服务,我们需要将不同的资源插入到主板上才可以被应用程序使用,物理机一旦按照特定的规格组装,想要拆分其中的资源就需要用到虚拟化等技术了。

而 LegoOS 可以更好地解决集群中的碎片化问题,提高整体的资源利用率。LegoOS 是个非常好的名字,它准确的描述了该操作系统的很多特征,不同的硬件在系统中是标准化的乐高积木,我们可以任意组合这些硬件构建具有海量资源的主机、集群甚至数据中心,同一个应用程序使用的 CPU、内存和存储资源可能来自使用网络连接的多个硬件。

lego-os

图 2 - LegoOS3

将计算机中的不同硬件解耦可以自然地提高对资源的利用率,但是使用网络连接硬件会带来两个比较棘手的问题,首先是由基础设施支撑的网络会带来不确定性,与分布式系统一样,很多问题都是网络的不稳定带来的,如果网络完全可靠,那么我们也不再需要重试或者幂等来保证数据的一致性;其次是网络带来的延迟是 CPU 缓存或者内存索引的 1,000x ~ 1,000,000x:

WorkLatency
L1 cache reference0.5 ns
Branch mispredict5 ns
L2 cache reference7 ns
Mutex lock/unlock25 ns
Main memory reference100 ns
Compress 1K bytes with Zippy3,000 ns
Send 1K bytes over 1 Gbps network10,000 ns
Read 4K randomly from SSD*150,000 ns
Read 1 MB sequentially from memory250,000 ns
Round trip within same datacenter500,000 ns
Read 1 MB sequentially from SSD*1,000,000 ns
Disk seek10,000,000 ns
Read 1 MB sequentially from disk20,000,000 ns
Send packet CA->Netherlands->CA150,000,000 ns

表 1 - 2012 年延迟数字对比4

虽然网络延迟受限于物理条件,但是随着网络设备和计算资源的发展和进步,我们可以缓解网络延迟带来的诸多问题,这不仅因为硬件设备拥有了更多的带宽和计算能力,还因为网卡与硬件设备变得更近。

我们在这篇文章中将介绍分布式操作系统 LegoOS 的架构与设计思路,包括它如何拆分现有操作系统的各个模块,各个模块的功能以及如何通过网络连接这些不同的模块对外提供服务。

架构与设计

LegoOS 使用全新的操作系统架构提供资源分离的功能,分离内核将操作系统分割成了具有不同功能的模块,操作系统中的全部组件都会通过网络进行通信,例如下图中的处理器、GPU、内存以及 NVM 等硬件:

split-kernel-architecture

图 3 - 分离内核架构5

分离内核架构中包含以下四个关键的概念,分析这些概念能够帮助我们理解该架构的特性:

  • 分离操作系统(Split OS functionalities)— 将传统操作系统的功能拆分到不同的监视器(Monitor)中,每个处理器都会管理硬件组件,虚拟化并保护这些物理资源;分离内核中监视器之间的耦合是很松的,它们会通过其他的监视器访问远程资源;
  • 在硬件组件上运行监视器(Run monitors at hardware components)— 集群中的所有非处理器组件都会运行独立的监视器,不同的控制器可以使用不同的实现管理自己持有的资源,这可以让数据中心中的异构硬件更好地集成;
  • 不一致组件之间的消息传递(Message passing across non-coherent components)— 分离内核依赖以太网等通用网络层进行通信,不同组件之间的通信都是通过网络进行的,我们只会保证组件内的一致性,应用程序可以在操作系统之上实现期望的一致性保证;
  • 全局资源管理和错误处理(Global resource management and failure handling)— 单个组件可以同时为多个应用程序提供服务,而组件的失效也会影响多个应用程序,为了管理集群中的不同组件、减少性能损耗和扩展性的瓶颈,我们在全局的维度管理组件并通过冗余处理组件的失效;

LegoOS 的核心设计思想就是将操作系统的功能拆分成多个模块并由全局的组件负责管理资源并处理错误,不同的硬件上运行不同的监视器来管理硬件资源,硬件之间会通过不可靠的网络传递消息,开发者需要在应用程序中实现期望的一致性。

资源管理

LegoOS 在设计上将硬件分成了处理器、内存和存储三种,分别是 pComponent、mComponent 和 sComponent,这三种硬件是互相独立的设备,有不同的硬件控制器和网络设备,我们会在 pComponent 中使用 CPU、在 mComponent 中使用 DRAM 并在 sComponent 中使用 SSD 或者 HDD。

legoos-component

图 4 - LegoOS 的组件

LegoOS 使用了两层的资源管理机制,在顶层使用三个全局的资源管理器来管理进程、内存和存储资源,分别是 GPM(Global Process Manager)、GMM(Global Memory Manager) 和 GSM(Global Storage Manager),这些跑在普通 Linux 服务器上的全局资源管理器会负责处理粗粒度的全局资源分配和负载均衡,它们会定期做出资源分配策略或者从监视器中获取负载等信息,底层的所有监视器会采用特定的策略和机制管理本地的资源。

two-level-resource-management

图 5 - 两层资源管理机制

我们在本节中会分别介绍 LegoOS 对 pComponent、mComponent 和 sComponent 三种不同组件的管理方式。

CPU

在每一个 pComponent 中,LegoOS 都会使用简单的本地线程调度模型处理数据中心中的应用程序,它会使用几个 CPU 在后台处理内核的相关任务并将剩余的 CPU 分配给应用程序的线程。当操作系统启动新的进程时,LegoOS 会使用全局的策略为当前进程的线程分配 CPU 并等待线程执行完成,在通常情况下,LegoOS 中运行的所有线程都不会被抢占。

legoos-process-component

图 6 - 进程管理器

LegoOS 的进程监视器除了持有和管理 CPU 资源之外,它还会配置和管理 ExCache 组件,当 pComponent 中处理器访问 ExCache 未命中时,LegoOS 会从对应的 mComponent 中读取相应的缓存行,与其他的缓存系统一样,ExCache 也实现了 FIFO 和 LRU 的缓存驱逐机制保证缓存的时效性。

内存

mComponent 主要会用于处理三种类型的数据:匿名内存(堆和栈)、内存映射文件和存储缓存区,它会同时管理虚拟和物理内存空间的分配、释放以及映射。每个应用程序进程都会使用一个或者多个 mComponent 保存数据,其中包含一个主 mComponent 会负责初始化加载进程、检查所有与虚拟内存管理相关的系统调用,每个进程的主 mComponent 都是由 LegoOS 中的全局内存资源管理器(Global Memory Resource Manager,GMM)统一分配的。

LegoOS 使用两层的机制管理分布式的虚拟内存空间,其中主 mComponent 负责粗粒度的、高层的虚拟内存分配决策,其他的 mComponent 负责执行细粒度的虚拟内存分配,这种策略可以减少正常内存访问和虚拟内存操作的网络通信。

我们将虚拟内存空间地址分成多个粗粒度、固定大小的虚拟地区(Virtual Region、vRegion),每个虚拟地区中的内存地址都属于一个 mComponent,底层会存储用户进程虚拟空间的区域信息。当应用程序进程想要分配虚拟内存空间时,它会执行如下所示的步骤:

distributed-memory-management

图 7 - 分布式内存管理

  1. pComponent 会将内存分配请求转发给主 mComponent;
    1. 主 mComponent 会使用它存储的 vRegion 的可用虚拟内存空间信息选择合适的区域分配内存;
    2. 如果当前 mComponent 中没有合适的内存区域,它会向 GMM 发出内存分配请求获取新的 mComponent 以及 vRegion;
  2. 如果候选的 mComponent 不是主 mComponent,那么主 mComponent 会将内存分配的请求转发给对应的 mComponent;
    1. 收到请求的 mComponent 会负责分配本地虚拟内存区域并初始化虚拟内存空间树;
  3. 获得 mComponent 信息后,pComponent 会直接与上述过程中选择的 mComponent 进行通信,并在为它分配的 vRegion 中申请内存;

与虚拟内存相比,物理内存的管理相对比较直接,每个 mComponent 都会负责管理它持有的物理内存,也可以自定义虚拟内存到物理内存之间的映射关系。

存储

LegoOS 在 sComponent 中实现了核心的存储能力,它通过 vNode 的抽象向后兼容了 POSIX 并支持了具有多个层级的文件接口,用户可以在 vNode 挂载点中正常存储目录和文件等数据并执行正常的读写和其他操作。

为了保证文件系统的简单,我们在 sComponent 中应用了无状态的设计,所有的 I/O 请求必须包含该请求所需要的全部信息,而 LegoOS 的存储监视器也选择使用哈希表来存储文件名到文件的映射,这也可以减少 sComponent 查找文件时所需要的计算资源,最大化的分离 CPU、内存和存储资源。

distributed-storage-buffer-cache

图 8 - 分布式存储缓冲区

因为我们不仅要分离内存和存储资源,还要保证存储的访问速度,操作系统原本的存储缓冲区(Storage Buffer Cache)也被放到 mComponent 中。当 pComponent 想要读取存储节点中的数据时,它会先从 mComponent 中查找是否有缓存的数据,只有当存储缓冲区中不包含对应数据时,它才会调用 sComponent 的接口获取数据并将数据写入 mComponent 的缓冲区中。

总结

今天的软件与硬件与几十年前刚刚诞生时已经有了天翻地覆的差别,各种各样的分布式系统、复杂的软件都需要多种多样的硬件支持,硬件的异构也导致资源的管理和调度在单机上变得更加复杂。

作为 2018 年 OSDI 的最佳论文,分布式操作系统 LegoOS 中的工作确实非常有趣,因为网络设备的发展,将服务器上的硬件资源打散重新管理变成了可能,在数据中心成为基础设施的今天,分布式操作系统这一设计变得非常有价值,这也可能会改变我们在未来组织和管理硬件的模式。

推荐阅读


  1. Yizhou Shan, Yutong Huang, Yilun Chen, and Yiying Zhang. 2018. LegoOS: a disseminated, distributed OS for hardware resource disaggregation. In Proceedings of the 12th USENIX conference on Operating Systems Design and Implementation (OSDI’18). USENIX Association, USA, 69–87. ↩︎

  2. All pricing · Compute Products · Compute Engine · Documentation · Resources https://cloud.google.com/compute/all-pricing#top_of_page ↩︎

  3. LegoOS. The First Disaggregated OS. P19. https://www.usenix.org/sites/default/files/conference/protected-files/osdi18_slides_shan.pdf ↩︎

  4. Latency Numbers Every Programmer Should Know https://gist.github.com/jboner/2841832 ↩︎

  5. The Splitkernel Architecture. P18. https://www.usenix.org/sites/default/files/conference/protected-files/osdi18_slides_shan.pdf ↩︎

wechat-account-qrcode

转载申请

知识共享许可协议
本作品采用知识共享署名 4.0 国际许可协议进行许可,转载时请注明原文链接,图片在使用时请保留全部内容,可适当缩放并在引用处附上图片所在的文章链接。

文章图片

你可以在 技术文章配图指南 中找到画图的方法和素材。