Alibaba Cloud Linux 2 (原Aliyun Linux 2)是阿里云操作系统团队基于社区版 4.19 LTS 内核打造的一款针对云产品优化的下一代 Linux 操作系统发行版,不仅提供 Linux 社区的最新增强功能,也提供了云上最佳用户体验并针对阿里云基础设施做了深度的优化。今年 3 月 26 日Alibaba Cloud Linux 2 LTS 正式发布,这是一个重要的里程碑。在 LTS 版本中,阿里云操作系统团队将提供长期的技术支持、稳定的安全更新以及持续的特性与优化。

阿里云同时推出了基于 Alibaba Cloud Linux 2 LTS 的快速启动版镜像,当前正在火热公测中,用户可以在北京、杭州、张家口、香港等可用区的控制台中购买试用。Alibaba Cloud Linux 2 LTS 为快速启动版做了大量优化工作,本文将深度披露相关操作系统侧的优化技术细节。

镜像目前在北京、杭州、张家口、香港等可用区公测,欢迎购买试用。

1、Linux 系统启动流程简介

我们首先需要定义 Linux 系统启动,这里我们定义为从系统上电到用户能够登录终端的时间为启动时长,对于云上用户来说,从 Guest OS 启动到用户可以通过 ssh 登录的阶段,为系统启动阶段。通用 Linux 操作系统启动大致分为三个阶段:引导阶段(第一阶段),内核启动阶段(第二阶段)及用户态启动阶段(第三阶段),相关流程如下图所示:

下面来看看各阶段大致的启动流程。

第一阶段

Bootloader 是位于系统引导扇区的一段独立的系统程序,用于系统启动初期的硬件初始化,系统分区识别,系统内核加载及跳转执行。目前应用比较广泛的 bootloader 是用于通用系统的 Grub2 和嵌入式系统的 uboot。Grub2 是多重引导器(multiboot),提供交互界面,默认配置下 Grub2 有5秒交互超时时间,启动耗时较长。

第二阶段

Bootloader 加载 Linux 内核(一般为压缩内核 vmlinuz)到内存,并运行内核自解压缩程序,解压后跳转至start_kernel(),开始内核初始化流程:

第三阶段

Linux 内核完成一系列初始化动作之后,开始运行 init 程序,创建 PID 为 1 的用户态进程,将系统控制权从内核态跳转到用户态。init 程序会继续进行用户态启动流程,开启各种必要的或是预先配置的系统服务,最后启动登陆服务,完成整个系统的启动。

Initrd 与 Switch Root

init 是用户态程序,存放在系统根文件系统(rootfs)里。内核需要先挂载 rootfs,才能运行 init 程序。通用 Linux 发行版需要支持多种磁盘设备及文件系统,这需要内核预加载多种可能的磁盘设备驱动及文件系统相关用户态工具软件才能正确识别 rootfs。而这些驱动及用户态工具一般都存放在 rootfs 中,形成一个循环依赖。

为解决这个问题,initrd 应运而生,将挂载 rootfs 必要的驱动、用户态工具以及其他需要预加载的代码从 rootfs 中抽取出来,并依照 rootfs 的文件结构,打包成一个小的 rootfs,做成一个内存盘(ram disk)。内核在挂载最终的 rootfs 之前,先从内存中挂载 initrd,加载必要的驱动后,先运行 initrd 中的 init 程序,挂载最终的 rootfs。然后执行 switch root 动作,切换至最终的 rootfs。

Alibaba Cloud Linux 2 采用 systemd 来管理用户空间启动流程,systemd 就是 init 程序,initrd 使用压缩格式的initramfs 文件。因此在加载 initrd 之前,内核需要先解压缩 initramfs。

cloud-init

在阿里云 ECS 环境中,cloud-init 是一个必不可少的初始化配置工具。在实例启动阶段能从多种数据源读取相关数据并据此对虚拟机进行配置,如用户密码,主机名,网络,用户数据等等一些配置。

2、工欲善其事必先利其器

优化系统启动时间,自然需要先对系统启动画像,了解启动时间分布情况,找出系统启动耗时热点。

启动时间测量

Linux 操作系统有如下常见的启动时间测量统计方法:

  • systemd-analyze: systemd 自带的启动分析工具,能够给出总的启动时间消耗,已经用户态服务启动耗时统计。

  • dmesg: dmesg 输出内核启动日志,时间戳能够帮助分析内核初始化各阶段耗时情况。配合-d选项计算出日志间的时间差,方便快速定位内核启动过程中耗时热点。

  • initcall_debug: 内核启动参数,开启后会统计内核各初始化函数的耗时情况,相比dmesg -d更加精确。

  • printk/trace_printk: 要分析一些启动热点的细化耗时情况时,手动增加一些 printk/trace_printk 探针能够帮助获取时间统计信息。

  • ftrace: 必要时也可开启内核早期 ftrace 功能,帮助分析热点耗时。不过需要注意开启 ftrace 后可能会导致函数延时增加,因此不宜参考 ftrace 得出函数绝对耗时,可以参照 trace 结果帮助分析热点函数的耗时逻辑。

还有其他一些时间测试方法,以及图形化画像工具,这里不一一介绍。

启动耗时热点分析

对早期 Alibaba Cloud Linux 2 启动进行测量画像后,按耗时排序,得到如下耗时热点:

热点 耗时(ms) 内核启动占比 总启动占比
mem init ~35 3.5% 0.7%
ORC unwind init ~90 9% 1.8%
buddy init 250 25% 5%
console enable ~60 6% 1.2 %
initramfs unpack 250 25% 5%
free initmem 270 27% 5.4%
mouse probe 650 65% 13%
systemd initrd 600 N/A 12%
mount rootfs 200 N/A 4%
cloud init 2740 N/A 54.8%

采样机器:ecs.g6.large 2C8G 实例

可见:

  • 内核启动阶段,鼠标探测耗时占比较高。

  • 总体启动耗时中,一半以上的时间消耗在用户态 cloud-init 进程上;

3、 快速启动优化

常用启动优化方法

常用的启动优化方法大致如下:

  • 瘦身

    • 移除不必要的代码,如模块,服务等,缩减启动初始化步骤;

    • 移除不必要的测试,调式及打印;

    • 精简共享库;

  • 异步、并行

    • 将耗时动作从关键路径移除,延后执行;

    • 将顺序动作并行化执行 ;

  • 原地执行(XIP): 多用于嵌入式系统;

  • 定制化: 将通用初始化程序定制化 ;

  • 算法优化: 改进算法,加速初始化时间。

我们的优化策略

去 initrd

从前面的启动耗时热点分析结果可以看出,initrd 解压缩及 initrd systemd 耗时占了较大比率。

Alibaba Cloud Linux 2 只运行于阿里云云服务器上,系统盘设备基本固定为 virtio-blk 设备,根文件系统格式基本固定为 ext4 文件系统,去掉 initrd 方案应该可行,理论上会优化掉 initramfs unpack(270) + initrd systemd(560) ~ 800ms 的启动耗时。于是开搞:

可见 initrd systemd 时间确实优化掉了,但是!总的启动时间并没有理论优化收益

继续探索原因,发现是内核启动耗时增加了约 400ms。进一步分析发现,启动耗时热点之一的 mouse probe(600ms),去 initrd 之前是与 initrd systemd 并行执行的。

去掉initrd后,这部分时间就直接计入内核启动时间了。抵去优化掉的 initramfs unpacking 的 200ms,内核实际增加了 400ms 左右。

因此,要最大化去 initrd 的优化收益,必须同时解决 mouse probe 的耗时。

延迟probe

通用 Linux 系统需要支持多种 IO 设备,而鼠标键盘是比较常用的输入设备,特别是鼠标,产品繁多,接口多样。系统启动过程中加载鼠标驱动后,需要扫描多种 IO 总线来探测鼠标设备,这一过程非常耗时。

依据前面提到的优化方法,我们有两种方案:

  1. 对云环境定制鼠标驱动,固定探测 virtio 设备;

  2. 将鼠标探测从启动关键路径剥离,延迟探测,与后面系统启动服务并行;

第一种方案需要重构相关代码,成本较高;而且定制化限制较多,无法与开源社区协作。因此需要思考第二种方法:延迟探测。一种简单可行的方法是将原本内置(built-in)的设备驱动重新编译为内核模块(kernel module),因内核模块存放在根文件系统,所以加载时机被动推迟到根文件系统挂载之后,此时内核已经启动完成,自然与用户态初始化进程并行执行。

测试结果如下:

带 initrd 启动

不带 initrd 启动

可见,内核启动时间缩减约 200ms,优化掉 initrd systemd 时间;鼠标设备探测延后至 userspace 初始化阶段,导致userspace 启动时间略有增加。获得预期的启动时间优化。

内存初始化优化

内存初始化也是内核启动热点之一,特别是在大规格实例上,内存初始化耗时占比较高。图中为 750GB 实例内存初始化耗时:

mem init 耗时近 2s

buddy init 耗时 1.8s

内存初始化动作是在内核启动的关键路径上,优化思路是并行初始化。因内存初始化时机较早,系统多CPU还未初始化完成,所以需要将内存初始化延后至CPU初始化完成之后,采用多线程并行执行内存初始化。这部分工作社区已经完成,通过内核配置deferred struct page init特性来开启。

开启后,内存初始化延后,按 NUMA node 并行执行:

前半部耗时约 0.2s

后半部耗时约 1.3s

free initmem 修复

早期 Alibaba Cloud Linux 2 启动优化前有一个概率性的启动热点,free initmem 到 buddy 系统时,会大概率出现200ms 以上延时,dmesg 日志显示如下,耗时超过 200ms:

1

[    0.687494] rtc_cmos 00:00: setting system clock to 2020-03-03 15:09:38 UTC (1583248178)

2

[    0.915315] Freeing unused kernel image memory: 1836K

uboot启动流程概述_Alibaba Cloud Linux 2 LTS OS 启动优化实践相关推荐

  1. Alibaba Cloud Linux 2 LTS 快速启动优化实践

    作者:阿里云操作系统:张世乐   概述/Overview Alibaba Cloud Linux 2(原Aliyun Linux 2,简称Alinux 2)是阿里云操作系统团队基于开源Linux内核4 ...

  2. 从源码解析-Android系统启动流程概述 init进程zygote进程SystemServer进程启动流程

    Android系统启动流程 启动流程 Loader Kernel Native Framework Application init进程 启动 rc文件规则 Actions Commands Serv ...

  3. uboot启动流程概述_关于RISCV启动部分的思考~

    1.本文说明 RISC-V的架构有着非常鲜明的特点,如果看过arm,aarch64,mips等架构的一些架构手册的基础知识,再看RISC-V的芯片的架构设计,就会觉得非常有意思,可以找到一些影子,但是 ...

  4. uboot启动流程概述_uboot 分析之 启动流程

    uboot的启动流程: 看一幅图: 1.第一阶段:start.s的内容: 点击(此处)折叠或打开 #include @该文件是第二步中mkconfig文件执行时创建的.include/config.h ...

  5. 透明大页相关内核参数_Alibaba Cloud Linux 2系统中与透明大页THP相关的性能调优方法...

    免责声明:本文档可能包含第三方产品信息,该信息仅供参考.阿里云对第三方产品的性能.可靠性以及操作可能带来的潜在影响,不做任何暗示或其他形式的承诺. 概述 本文主要介绍在Alibaba Cloud Li ...

  6. S3C2440上电启动流程概述

    一.S3C2440的启动方式 1.启动介质 S3C2440在上电时会通过判断OM0和OM1的信号组合来决定指令开始执行的位置(即引导ROM的位置),同时这两个信号也用于决定BANK0(nGCS0)的总 ...

  7. Alian解读SpringBoot 2.6.0 源码(九):启动流程分析之应用上下文刷新后处理(启动完成事件,Runner运行器,就绪事件)

    目录 一.背景 1.1.run方法整体流程 1.2.本文解读范围 二.应用上下文刷新后置处理 三.时间信息.输出日志记录执行主类名 四.发布应用上下文启动完成事件 4.1.ApplicationSta ...

  8. uboot启动流程概述_2017.09版uboot启动过程分析

    2017.9版本uboot启动至命令行几个重要函数为:_start,_main,board_init_f,relocate_code,board_init_r. ? 一 .程序的入口:_start 对 ...

  9. 全志 Linux 系统启动优化 启动优化速度方式 优化启动流程 优化uboot 优化kernel等

    文章目录 1 概述 2 启动速度优化简介 2.1 启动流程 2.2 测量方法 2.2.1 printk time 2.2.2 initcall_debug 2.2.3 bootgraph. 2.2.4 ...

最新文章

  1. linux切换软件版本,Linux中dpkg工具update-alternatives实现符号链接软件版本的切换(转)...
  2. 服务器加根网线用不用修改路由器,安装设置无线路由器需要用几根网线?
  3. 怎么打开网络访问 计算机共享,电脑只要打开共享提示“无法启用共享访问”如何解决...
  4. sql查询id最大的一行_mysql-聚合查询
  5. 键盘视频鼠标(KVM)切换器基础知识
  6. Manjaro - KDE - i3wm - PloyBar 使用配置全指南
  7. Centos下PHP5升级PHP7
  8. 淘宝客APP源码 社交电商uniapp开发源码 前端源码自营商城
  9. linux java8 安装包(版本8u131-b11)
  10. UNIX网络编程阅读建议
  11. keil5下载完成后程序不复位运行
  12. 基本分段存储管理方式
  13. 微信公众号、企业服务号如何配置运营管理人员
  14. 计算机cad运行缓慢怎样处理,旧电脑如何提高CAD运行速度
  15. 万能格式转换器1.2绿色免费汉化版
  16. 笔记本电脑怎么用u盘重装系统,u盘给电脑安装系统的方法
  17. win10 下安装wampserver 的几个坑
  18. 兵法三十六计第一计-瞒天过海。
  19. usermod -a -G group1 user1
  20. 服装行业ERP选型咨询提纲

热门文章

  1. 【C# interface接口】模拟MP3/AVI播放器
  2. Spring MVC原理及配置详解
  3. C++ 动态二维数组(二维vector)
  4. CSS3的弹性盒子flex详解(2)
  5. 【解题报告】Leecode 2057. 值相等的最小索引——Leecode周赛系列
  6. 深入理解弹性盒布局(fiex-box)——Web前端系列自学笔记
  7. 【已解决】查看Python中已经安装的包
  8. 纪念第一个正式的java程序
  9. java条件运算符类型转换_Java运算符,条件表达式,类型转换
  10. GFS分布式文件系统简介及部署——让存储变得更高级