Lego OS 介绍

网友投稿 2019-10-30 14:27

1  背景

  OSDI2018大会上普渡大学的学者提交了一篇LegoOS的论文,个人认为比较有意思,把论文大体翻译了一下,和大家分享。

项目主页:http://legoos.io/

源代码:https://github.com/Wuklab/Lego

LegoOS的作者认为现在的单片服务器导致资源利用低下:

https://cdn.china-scratch.com/timg/191101/142K15641-0.jpg

上图是作者分别对Google和阿里的服务器集群进行29天和12小时的跟踪,结果表明在所有时间中,大约只使用了一半的CPU和内存。作者认为造成这种资源利用不足情况的原因之一是需要从同一物理机器分配任务的CPU和内存,硬件弹性差。

另外,根据《Disk Failures in the Real World:What Does an MTTF of 1,000,000 Hours Mean to You?》这篇文章的分析,主板、内存、CPU、电源故障占服务器总硬件故障的50%-82%。(MTTF平均失效前时间mean time to failure) 

总之,作者认为目前单片服务器面临如下问题:

a.导致资源利用效率低下,因为作业的CPU和内存必须从同一台机器分配。即使利用率总体较低(例如50%),这也可能因为资源不足而导致任务逐出。

b.在硬件组件安装到服务器之后,很难添加,移动,移除或重新配置硬件组件,这导致硬件部署的前期规划周期很长,而需求的变化速度却很快。

c.它会创建一个故障域:当服务器中的任何硬件组件发生故障时,整个服务器通常都无法使用。

d.它不适用于异构设备:例如GPU,TPU,DPU,FGPA,NVM和基于NVMe的SSD。

2  Splitkernel架构

作者认为,为支持硬件不断增长的异构性并在硬件级别提供弹性和灵活性,应该打破整体服务器模型,因此设想了一种硬件资源分解模型,其中传统服务器中的硬件资源(CPU、内存、存储设备)被分解到网络连接的硬件组件中,每个组件都有一个控制器和一个网络接口,可以独立运行操作系统,是一个独立的,故障隔离的实体。

进一步作者提出了一种Splitkernel的新操作系统模型来管理系统。Splitkernel具体架构如下:将操作系统分为多个不同的功能,每个功能都在相应的硬件组件上运行并管理硬件组件。所有组件通过公共网络传递消息进行通信,由Splitkernel进行全局资源管理和组件故障处理。

  另外作者认为下面三种硬件趋势使得硬件资源分解变得可行:

1.网络速度增长了一个数量级以上。在过去十年中,通过远程直接访问内存(RDMA)等技术使得网络变得更具扩展性。InfiniBand将很快达到200Gbps和600ns以下的速度,这个速度在带宽上仅比内存储器总线慢2到4倍,根据《Scaling the Band width Wall: Challenges in and Avenues for CMP Scaling》由于内存总线面临带宽墙,未来网络带宽甚至预计会超过本地DRAM带宽。

2.网络接口越来越接近硬件组件,因此硬件设备能直接访问网络无需连接任何CPU。Intel Omni-path、RDMA等

3. 硬件设备正在整合更多处理能力,允许将应用和操作系统逻辑下放到硬件上。

Splitkernel架构的四个关键概念:

1、拆分OS功能。Splitkernel将传统操作系统功能拆分为称为监视器的组件,每个监视器管理特定的硬件组件,通过虚拟化并保护其物理资源。Splitkernel中监视器是松耦合的,监视器通过和其他监视器通信来访问远程资源。为使得每个监视器对其他监视器依赖最小,在监视器之间通过共享最小数据来使用无状态设计。

2、在硬件上运行监视器。作者希望每个非CPU的硬件组件都有一个可以运行监视器的硬件控制器,这个硬件控制器可以是低功耗通用处理器,也可以是ASIC或者FPGA。监视器之间可以异构,使得更容易集成GPU等异构硬件。

3、不保证组件一致性的传递消息。Splitkernel在通用网络(比如以太网)上运行,不提供跨组件的高速缓存一致性,这样设计主要考虑是:维持一致性会导致高网络带宽消耗。在Splitkernel上运行的应用程序需要自己通过消息传递来实现应用自己需要的数据一致性。

4、全局资源和故障管理。由于一个硬件组件可以为多个应用提供资源服务,组件的故障会应用这些应用,因此需要全局的资源和故障管理。

 下面是Splitkernel架构示意图:

https://cdn.china-scratch.com/timg/191101/142K15106-1.jpg

3  LegoOS

LegoOS是Splitkernel模型的一个实现。目前LegoOS实现主要针对三种类型硬件:处理,内存和存储,这意味着处理器和内存通过网络分离!

作者认为构建LegoOS的最大挑战和重点是处理器和内存的分离及其管理,因为现代处理器和操作系统假定所有硬件存储器单元(包括主存储器,页表和TLB)都是本地的,将所有内存硬件和内存管理软件移动到整个网络是个挑战。

3.1  抽象和使用模型

LegoOS向用户公开一组分布式虚拟节点vNode。从用户角度看,vNode就像一个虚拟机,多个用户可以在同一个vNode中运行。每个用户可以运行多个进程。

每个vNode具有唯一的ID和虚拟的IP地址,和存储挂载点。每个vNode的资源由LegoOS保护并给予隔离。在内部,一个vNode可以在多个进程组件(pComponents),内存组件(mComponents)和存储组件(sComponents)上运行。由于Splitkernel不支持组件一致性,因此LegoOS不支持处理器之间可写的共享内存。跨进程使用可写共享内存的应用需要修改,使用消息传递代替。

LegoOS支持Linux系统调用接口和未修改的Linux ABI。在Linux上运行的分布式应用程序可以通过运行一组vNode在LegoOS群集上无缝运行。

3.2  硬件架构

LegoOS中pComponents、mComponents、sComponents都是独立的硬件设备,有自己的硬件控制器和网络接口。目前pComponents主要是CPU,mComponents主要是DRAM,sComponents使用的是SSD或者HDD。

下图是pComponents和mComponents分离,通过Network连接的架构图,其中使用的CPU、内存和网络都是采用的现有技术。

https://cdn.china-scratch.com/timg/191101/142K245b-2.jpg

3.3  LegoOS设计

LegoOS进程监视器运行在pComponents的内核态,管理pComponents的CPU资源和ExCache。用户态程序运行在pComponents的用户态。每个pComponents

上都使用一个简单的本地进程调度模型,调度不考虑内存影响,处理网络请求不使用中断,而使用轮询。

ExCache是pComponents的缓存,使用分页机制实现,LegoOS负责处理ExCache没有命中的情况。

mComponents只负责处理三种类型的数据:匿名内存(堆、堆栈),内存映射文件和存储区缓存。mComponents上运行的内存监视器管理虚拟和物理地址空间,管理内存的分配,释放和内存地址映射。mComponents上没有用户态进程,都是内核态进程。

LegoOS允许进程地址空间跨越多个mComponents,每个应用程序可以使用一个或者多个mComponents。

LegoOS使用两级资源管理,在Components之上存在三个全局的资源管理器GPM、GMM、GSM。这些全局资源管理器负责全局资源分配和负载均衡,全局资源管理之下的资源由具体的Components负责。

3.4  具体实现

LegoOS目前支持113个系统调用,15个伪文件。作者发现这些足以支持运行许多未经修改的数据中心应用程序。

由于目前没有真正的可分解硬件,因此mComponents是通过限制普通机器的CPU个数为2个来模拟的,pComponents则是通过限制普通机器的内存为ExCache大小来模拟,sComponents则是纯软件模拟,利用linux的VFS层创建一个普通文件来模拟。

3.4.1  网络栈实现

LegoOS实现了三个网络协议栈。

一个是基于LITE的基于RDMA的定制RPC框架,运行在InfiniBand上。LITE是一个用于RDMA的本地间接TiEr,它将原生RDMA虚拟化为灵活,高级,易用的抽象,并允许应用程序安全地共享资源,与原生RDMA和针对特定应用定制的现有解决方案相比,LITE提供了类似的延迟和吞吐量,同时提高了灵活性,性能可扩展性,CPU利用率,资源共享和服务质量。

下图是传统RDMA和LITE架构的区别。

https://cdn.china-scratch.com/timg/191101/142K33T5-3.jpg

关于LITE的更多信息见《LITE Kernel RDMA Support for Datacenter Applications》

第二个是在RDMA上直接实现的套接字接口。

第三个是基于lwip实现的传统套接字和TCP/IP协议栈,运行在e1000网卡上。

3.4.2  pComponents处理器监视器

在每个pComponent上保留少量内存作为缓存,称为扩展缓存ExCache,它位于当前处理器最后一级缓存(LLC)下。监视器在pComponent的内核空间中运行,管理其CPU核心和ExCache。

X86使用硬件mmu来管理TLB和遍历页表,因此在具体实现上只有使用分页机制来模拟ExCache,每个ExCache line大小是4KB。ExCache未命中会陷入LegoOS内核,进入替换。LegoOS为每个ExCache维护了一个LRU链表,并使用额外的线程实现ExCache的替换。ExCache满的时候需要将脏也刷新到mComponents,这是通过网络实现的。为减小ExCache刷新对网络的开销,在实现上LegoOS利用RPC,在每次PRC中捎带脏页刷新和页面读取请求。

3.4.3  mComponents内存监视器

mComponents在实现上是使用普通机器,限制使用机器的2到5个CPU来模拟的。实现上目前使用其中一个CPU用来轮询网络请求,其余CPU用来执行内存功能。

mComponents执行来自pComponent的PRC请求。大部分请求会在mComponents本地执行,少部分请求需求向sComponents发送RPC完成(如需要的数据在sComponents中时)。

普通程序加载的时候,内存监视器将文件从sComponents加载到mComponents,同时会处理应用的虚拟内存分配请求,在mComponents上分配内存。

目前mComponents实现是纯软件的,未来希望这部分功能由硬件实现。

3.4.4  sComponents存储监视器

sComponents则是纯软件模拟,具体实现为构建在Linux的VFS层之上的一个内核模块。LegoOS通过VFS创建一

普通文件作为每个vNode的安装分区,通过VFS的文件操作来执行LegoOS的存储I/O。

3.5  性能评估

https://cdn.china-scratch.com/timg/191101/142K4O41-4.jpg

 

上图是LegoOS使用socket和RPC在InfiniBand发送消息的网络平均延迟,相比Linux有明显优势。

https://cdn.china-scratch.com/timg/191101/142K4CS-5.jpg

 

上图是内存吞吐量的评估,测试主要对LegoOS的mComponents和Linux单节点的性能进行对比。具体测试在多线程测试的每个线程中执行一百万个联系4KB内存负载,使用的ExCache大小为32GB。

每个mComponents上可以运行1-4个woker线程,同时可以增加mComponents数量。测试表明增加每个mComponents中的worker数量,或者增加mComponents数量,都能提升内存吞吐量,但worker数量总数达到4个之后,提高变少。

https://cdn.china-scratch.com/timg/191101/142K43938-6.jpg

 

上图是比较LegoOS的sComponents节点和Linux单节点的存储吞吐量。具体测试是在SSD上进行顺序和随机的4KB读写,每次读写之后会调用fsync。这个测试LegoOS的sComponents性能低于Linux单节点。

https://cdn.china-scratch.com/timg/191101/142K559E-7.jpg

 

上图是使用PARSEC测试程序对LegoOS进行测试的结果。 

https://cdn.china-scratch.com/timg/191101/142K563a-8.jpg

上图使用tensorflow进行测试,整个测试需要使用到的虚拟内存大小大约为0.9GB,我们将设置ExCache大小为总需要内存的25%后来评估ExCache大小对应用性能的影响。同时我们和采用了swap的Linux和采用了InfiniSwap的情况进行了比较。在ExCache和swap大小变小的情况下,ExCache方案性能损失明显小于其他方案。

另外凭借更好的资源利用率和简化的硬件组件(例如,没有主板),与同等的单片服务器集群相比,根据《Disk Failures in the Real World: What Does an MTTF of 1,000,000 Hours Mean to You?》的数据估算,LegoOS相比单片服务器,MTTF将从5.8提高到了6.8-8.7,大约会提高了17%至49%。

https://cdn.china-scratch.com/timg/191101/142K5M93-9.jpg

 

4  分析点评

LegoOS的主要思想是认为硬件可以通过分解成更小的模块来提高利用率和MTTF。考虑到硬件进行了分解,因此相应操作系统是否也能根据硬件功能进行分解就是一个很自然的想法。

此外LegoOS开发者判断未来高速网络的速度会接近甚至超过内存DRAM总线,因此将CPU和内存和存储分解后,可以借用高速网络进行通信而不太影响性能。

基于上述原因,作者尝试了操作系统分解的实现--LegoOS。

不过由于目前没有内存硬件带有可以运行分解后的操作系统,因此在验证LegoOS的mComponents的时候是将一个普通机器限制CPU来模拟可运行操作系统的内存硬件。sComponents模拟也比较简单,直接使用了Linux的VFS。

学者们在x86上实现了LegoOS,在实现的时候保持了Linux ABI的兼容性,并进行了一些实际性能测试,和Linux相比互有胜负,不过LegoOS在降低服务器集群的故障率方面还是有显著优势。作者认为LegoOS有很大改进空间,在资源利用率上将会优于Linux。

目前看来LegoOS属于原型验证阶段,目前还没有支持mComponents的真实硬件。不过高速网络的发展、硬件技术的进步,使得将硬件和操作系统分解成为可能,LegoOS作了一个相当不错的尝试。

--end--

声明:本文章由网友投稿作为教育分享用途,如有侵权原作者可通过邮件及时和我们联系删除:freemanzk@qq.com