Linux|龙蜥开源Plugsched:首次实现 Linux kernel 调度器热升级

Linux|龙蜥开源Plugsched:首次实现 Linux kernel 调度器热升级

文章图片

Linux|龙蜥开源Plugsched:首次实现 Linux kernel 调度器热升级



文/龙蜥社区内核开发人员 陈善佩、吴一昊、邓二伟
Plugsched 是 Linux 内核调度器子系统热升级的 SDK , 它可以实现在不重启系统、应用的情况下动态替换调度器子系统 , 毫秒级 downtime 。 Plugsched 可以对生产环境中的内核调度特性动态地进行增、删、改 , 以满足不同场景或应用的需求 , 且支持回滚 。
基于 plugsched 实现的调度器热升级 , 不修改现有内核代码 , 就能获得较好的可修改能力 , 天然支持线上的老内核版本 。 如果提前在内核调度器代码的关键数据结构中加入 Reserve 字段 , 可以额外获得修改数据结构的能力 , 进一步提升可修改能力 。
Plugsched 开源链接:https://gitee.com/anolis/plugsched
那么Plugsched 诞生的背景或者想要解决的问题是什么?我们认为有以下 4 点: 应用场景不同 , 最佳调度策略不同 。 应用种类极大丰富 , 应用特征也是千变万化 (throughput-oriented workloads s-scale latency critical workloads soft real-time and energy efficiency requirements) , 使得调度策略的优化比较复杂 , 不存在“一劳永逸”的策略 。 因此 , 允许用户定制调度器满足不同的场景是必要的 。调度器迭代慢 。 Linux 内核经过很多年的更新迭代 , 代码变得越来越繁重 。 调度器是内核最核心的子系统之一 , 它的结构复杂 , 与其它子系统紧密耦合 , 这使得开发和调试变得越发困难 。 此外 , Linux 很少增加新的调度类 , 尤其是不太可能接受非通用或场景针对型的调度器 , 上游社区在调度领域发展缓慢 。内核升级困难 。 调度器内嵌 (built-in)在内核中 , 上线调度器的优化或新特性需要升级内核版本 。 内核发布周期通常是数月之久 , 这将导致新的调度器无法及时应用在生产系统中 。 再者 , 要在集群范围升级新内核 , 涉及业务迁移和停机升级 , 对业务方来说代价昂贵 。无法升级子系统 。 kpatch 和 livepatch 是函数粒度的热升级方案 , 可修改能力较弱 , 不能实现复杂的逻辑改动;eBPF 技术在内核网络中广泛应用 , 但现在调度器还不支持 ebpf hook , 将来即使支持 , 也只是实现局部策略的灵活修改 , 可修改能力同样较弱 。Plugsched 能将调度器子系统从内核中提取出来 , 以模块的形式对内核调度器进行热升级 。 通过对调度器模块的修改 , 能够针对不同业务定制化调度器 , 而且使用模块能够更敏捷的开发新特性和优化点 , 并且可以在不中断业务的情况下上线 。
图1 plugsched: 业务不中断
使用 plugsched 具有以下 6 大优势:
与内核发布解耦:调度器版本与内核版本解耦 , 不同业务可以使用不同调度策略;建立持续运维能力 , 加速调度问题修复、策略优化落地;提升调度领域创新空间 , 加快调度器技术演进和迭代 可修改能力强:可以实现复杂的调度特性和优化策略 , 能人之所不能 维护简单:不修改内核代码 , 或少量修改内核代码 , 保持内核主线干净整洁;在内核代码 Tree 外独立维护非通用调度策略 , 采用 RPM 的形式发布和上线 简单易用:容器化的 SDK 开发环境 , 一键生成 RPM , 开发测试简洁高效 向下兼容:支持老内核版本 , 使得存量业务也能及时享受新技术红利 高效的性能:毫秒级 downtime , 可忽略的 overhead 。 Plugsched 应用案例 Plugsched 相比 kpatch 和 livepatch 可修改能力更强 , 热升级范围更广 , plugsched 是子系统范围的热升级 , 而后者是函数级别的热升级 。 对于 plugsched 而言 , 无论是 bugfix , 还是性能优化 , 甚至是特性的增、删、改 , 都可胜任 。 鉴于 plugsched 较强的可修改能力 , 它可应用到以下场景:
快速开发、验证、上线新特性 , 稳定后放入内核主线 针对不同业务场景做定制优化 , 以 RPM 包的形式发布和维护非通用调度器特性 统一管理调度器热补丁 , 避免多个热补丁之间的冲突而引发故障 应用案例 1:新增 Group Identity 调度特性
Group Identity 是阿里云用于混部场景的调度特性 , 它基于 CFS 调度器增加了一颗存储低优先级任务的红黑树 , 而且会对每一个 cgroup 分配一个默认优先级 , 用户也可自行配置其优先级 , 当队列中存在高优先级任务时 , 低优先级任务会停止运行 。 我们利用 plugsched 对 anck 4.19 的一个老版本内核(没有该调度特性)进行调度器热升级 , 并将 Group Identity 调度特性移植到生成的调度器模块中 , 涉及 7 个文件 , 2500+ 行的修改量 。