在刚刚结束的 openEuler Summit 2022 上,华为服务器 OS 首席架构师、openEuler 社区技术委员会委员熊伟为广大开发者介绍了 openEuler 在过去 3 年的成就和成果。而其中最值得关注的是,openEuler 在云、服务器、边缘计算、嵌入式等四大场景下的八个技术方向的创新。
用熊伟博士的话来说,“在过去的三年里,openEuler 深入行业和产业,用八个技术方向的纵深创新,引领全场景的产业领先”。接下来,作为一个一直关注开源操作系统的技术人,我分享一下我的理解。
可编程内核:系统调度的极限追求
首先介绍一下可编程内核。
我们知道,内核是一个操作系统的核心。对于我们所熟悉的 PC 和服务器,由于对资源的消耗和性能的需求没有那么的敏感,无需毫厘必争,所以往往不太需要在内核层面做删减,正常使用即可。删减内核功能的成本可能远高于增加内存的成本。
但对于资源消耗和成本更加敏感的边缘计算、嵌入式设备来说,每一丝的资源占有,都是难以估量的成本。对于资源集群量级极大的云计算场景而言,每 0.1% 的性能优化,对于整个集群而言,都是十分可观的收益。一个可编程的内核相比于模块化的内核,为生产环境下的优化提供了更多的可能性 —— 工程师可以根据业务的实际变化,随时调整内核的实现和策略,从而优化系统的性能。
在这种情况下,对于内核进行组装,支持可编程能力,就变得极其重要。openEuler 创新性地借鉴了社区当中 eBPF 的思想,并在此基础之上,将内核的机制和框架进行了分离,将框架内置到内核,实现的功能和策略则可以在开发完成后,注入到内核中即可实现对内核二次编程的效果。
说起来简单,但在具体落实层面,openEuler 做了不少的工作来达成这个目标:
openEuler 在系统内核层面,提供了编写用户态策略的基础库函数和可配置的调度策略模板,可以帮助用户快速理解内核的编程方式。支持用户快速编排和扩展,降低用户对内核实现调整时的成本,降低上手的门槛。在具体的管理机制方面,则提供了对任务 / 进程 / 组 / 用户等对象的自定义拓展标签,从而承载了用户态与内核态、内核态组件之间协同调度的语义,实现了整个内核的统一调度,确保力往一处使。此外,openEuler 还在内核层面提供了丰富的钩子点位和辅助函数,从而支持对 CFS 调度类的选核、选任务、抢占流程的自定义策略注入。
对于普通的开发人员来说,也可以基于 openEuler 提供的可编程框架,来实现针对不同的应用场景来开发自定义策略,动态加载到内核执行,提升内核的执行效率,为整个业务系统降本增效。
除了内核级别的资源调度,在 openEuler 操作系统中,还实现了两种不同层面的混合部署:在线/离线业务混部和软硬实时混部。从这个角度看,openEuler 志在实现更多更大场景的统一管理和运筹。我们先来看一下在线/离线业务混部:
在线/离线业务混部:资源利用率和系统性能的极限平衡追求
对于任何规模化的业务来说,必然会存在波峰和波谷。如何平衡不同业务之间分配的资源从而实现资源的最大化利用,是一个极为重要的课题。
在 openEuler 当中,你可以使用可编程的内核来完成内核级别的资源调度;而在更上一层,openEuler 提供了完整的在线/离线业务混部能力。openEuler 为开发者提供了三层不同的层次的资源调度能力。
在内核层,基于内核优先级隔离调度技术,对于 CPU、内存、IO/NET 等资源维度实现干扰隔离,从根源上优化资源调度和隔离的能力。在用户态,为用户提供了基于 Rubik 的动态配置和拓扑编排能力,同时配合新一代 QoS 感知资源调度器 Skylark 所提供的资源调度能力,从而实现为不同的 QoS 要求的混部业务提供合适的资源调度。
Rubik 为开发者提供了基于应用画像的应用调度机制,来实现自动的资源调度能力。通过自动注入技术,来实现业务的自动画像和自动分析,得出不同业务负载对于资源的敏感度和压力度。再基于画像和标记,对各节点的资源进行调度(如 CPU、内存带宽、缓存带宽、磁盘带宽、网络带宽等)和数据收集,并基于历史数据二次调度资源,均衡各不同业务对于资源的平均利用水平。
在应用调度之上,Rubik 还会基于业务指标进行一定程度上的节点资源超卖。通过对业务资源维度的采样,预测可压缩资源的使用情况,从而实现基于预测情况的超卖。在为在线业务准确预留所需资源,保障其 QoS 的同时,将未使用资源尽可能多地分配给离线业务,最大化离线业务的吞吐率,提升节点的资源利用率。
通过引入 Rubik 在离线混部解决方案,在保证业务 SLA 不下降的情况下,资源利用率从业界平均的 15% 提升到 35%。
除了在线/离线业务混部之外,openEuler 还支持软硬件层面的实时混部:
软硬实时混部:多层次确定性时延需求满足
在 openEuler 当中,集成了一个新的硬实时内核 uniProton,帮助开发者磨平底层的硬件平台的差异,提供一套标准统一的操作系统平台。uniProton 支持任务管理、事件管理、队列管理、硬中断管理等管理方式,兼容 POSIX 标准接口的开发,降低了开发者的开发成本。
而对于开发者而言,更重要的是 uniProton 是鸿蒙系统和 openEuler 共同支持的内核。开发者可以开发一套应用,同时运行在 openEuler 计算设备和鸿蒙设备上,降低了开发者的开发成本。
对于需要硬实时方案的开发者来说,配合 uniProton 和 openEuler 的系统镜像裁剪能力,可以实现 KB 级的系统镜像,调度时延 < 3us;而可以接受软实时方案的开发者则可以选择基于内核自旋锁和信号量优先级继承机制,配合周期性、Workqueue 延时、负载均衡等任务驱逐机制,实现 20us 中断响应。
通过软硬实时方案的混部能力,openEuler 实现了 CPU 、内存等全域资源的隔离分区,满足了数控机床、传统工业场景下对于多层次确定性时延的需求,帮助 openEuler 开发者可以进行传统工业场景的开发。
openEuler 除了和鸿蒙系统共建 uniProton,还提供了一个更有价值的特性 —— 多芯片架构的支持。
异构互联:泛架构算力存储统一调度
openEuler 全版本支持 x86、ARM、申威、龙芯、RISC-V 等五大架构,并支持英特尔、AMD、兆芯等多款 CPU 芯片,支持多个硬件厂商发布的多款整机型号、板卡型号,对于开发者来说,可以轻松完成多个不同型号的设备之间的互联和统一调度。
配合分布式软总线,可以实现鸿蒙设备和 openEuler 系统设备之间的即插即用、高效传输。开发者可以无需关注设备的发现机制,借助分布式软总线提供的通信机制,快速完成设备的发现、组网、连接和传输能力。开发者可以通过使用分布式软总线提供的 API 实现设备间的高速通信,无需关心通信细节,进而实现业务平台的高效部署与运行能力。
SysMaster: 安全可靠机制可靠的服务管理系统
除了上面介绍的各种内核、硬件方面的技术突破以外,openEuler 还在开发者最熟悉的初始化系统上做了一些探索和改进。
我们过去熟悉的初始化系统(比如 sysVinit、systemd、upstart),大多是使用 C 写的,且往往因为设计复杂,功能大一统等有违 UNIX 传统思维的做法而广受诟病。openEuler 社区为社区提供了一个全新的、采用 Rust 编写的初始化系统 —— SysMaster。
和 systemd 相比,由于 SysMaster 采用 Rust 语言编写,原生地规避了内存泄漏问题,开发者无需担心内存泄漏导致的 1 号进程挂掉。而从零构建的 SysMaster,也摒弃了之前的初始化系统中存在问题,为开发者提供了新一代的初始化系统。
相比于过去的初始化系统,SysMaster 提供了全新的架构设计,分为 SysMaster Core 和 SysMaster Extend 两类。SysMaster Core 提供了极度轻量的调度方式,占用更少的资源,以及更快的启动速度。拆分的架构则可以支持拓展多种服务类型,实现 1+1+N 的架构,满足初始化系统的多样化诉求。而它的生态兼容工具,则可以让开发者可以自由选择 systemd 和 SysMaster,无需担心被生态绑定。
总结
openEuler 的技术创新覆盖的场景相当地丰富和深入,以至于我无法在一篇文章中逐一分析和披露所有细分场景和技术创新点。在撰写这篇文章时,给我的最大感受是“他们居然实现了!”
对于一个产业的研发人员来说,毫无疑问,openEuler 的这些技术创新,将帮助产业和行业的开发者节省大量的时间,用更短的时间完成应用的建设,将精力投放在产业和业务当中,产生价值。
从过去的“要打造根社区”,到如今的“成为根社区,并从根出发,进入纵深领域创新”,openEuler 给我了太多的惊喜。假以时日,我相信,openEuler 还给我带来更多的震撼。