草庐IT

华为云发布冷启动加速解决方案:助力Serverless计算速度提升90%+

华为云开发者社区 2023-03-28 原文
摘要:本文介绍了华为云对冷启动优化这一业界难题的探索之路,创新提出了基于进程级快照的优化方案。

作者信息——

子游:华为元戎高级工程师

平山:华为云中间件 Serverless 负责人

琪君:华为元戎负责人

Key Takeaways

  1. 冷启动 (Cold Start)一直是Serverless领域面临的优化难题之一,华为云创新提出了基于进程级快照的冷启动加速解决方案,致力于在用户几乎无感知的前提下,有效提升应用的冷启动性能;
  2. 特别的,Java应用冷启动速度慢的问题尤为突出。本文以Java场景为例,介绍华为云在冷启动性能优化方面的探索历程,并揭秘90%+性能提升背后的技术实现原理。文末我们也提供了Quick Start,帮助用户更快地上手该新特性。

一、问题引言:Java应用冷启动速度面临巨大挑战

Serverless应用启动时,都需要先进行初始化。其初始化时长一般取决于应用本身的属性,如业务逻辑、编程语言等,其中Java应用的初始化过程通常是最慢的。以下基于一个典型的Java应用,对其启动时延进行拆解,各阶段耗时分布如图1所示:

图1:Java应用启动耗时分解

其中,端到端冷启动耗时可分为2大部分:

  • 平台侧时间:

主要包含执行环境创建(如容器启动)、执行环境初始化(如代码包下载、部署)等准备工作,此阶段最多是秒级响应,在冷启动整体耗时中占比很低,通常不到5%,平台侧也支持一些优化方式,将耗时进一步压缩至毫秒级;

  • 服务侧时间:

主要包含应用框架启动(如构建Spring ApplicationContext)、业务初始化(如业务数据初始化)等动作,此阶段耗时一般较长。在本例中,应用框架启动耗时占比约30%,业务初始化占比约65%。由此推断,该阶段执行的动作是Java应用启动慢的核心所在

Java应用启动慢的根因其实也不难理解,主要有:

  • 框架复杂:Spring作为一个企业级的框架,为了支持广泛的应用需求,存在大量的可配置和初始化逻辑,并通过复杂的设计模式来支撑这种灵活性。例如,一个spring-boot-web的hello world,依赖的class文件就多达7404个,见图2;
  • JVM的一次编译,到处运行:类加载时,查找类、校验类的开销会随着应用复杂度而增长;同时,在应用刚启动时,方法还没有完全被JIT编译完成,因此大部分情况停留在解释执行,影响了应用启动的速度。

图2: hello world依赖的class个数

因此,对于时延敏感型的Java应用程序,在突发流量下发生冷启动时,可能会导致用户体验下降。为了应对这一挑战,用户可以提前预留资源来减少冷启动发生的频率,或者对自己的应用进行性能调优,但是第一类方案无形中增加了用户的keep-alive成本,第二类方案也有着较高的技术门槛且往往效果比较有限。

二、基于快照技术的冷启动加速:华为云的优化探索之路

Part I:站在巨人的肩膀上

业界针对Java应用的启动速度优化已有一些优秀的实践,可分为以下几类:

  • AOT:
    主要有GraalVM[1]、EJET等,AOT方案是通过在程序运行前,直接将Java源码编译成本地机器码,因为提前编译并不占用运行时间,以此来显著提升应用的启动速度,同时本地机器码可以持久化于磁盘中,不占用内存且可重复使用。但是该类方案在特定场景也存在一定的局限性,如GraalVM对反射的支持并不友好,在涉及反射的地方都需要新增配置;EJET虽然解决了反射的问题,但是其编译时间较长且不稳定,在复杂应用场景下也存在性能劣化问题。
  • AppCDS[2]:
    AppCDS方案是通过在JVM启动时从JSA文件读取共享数据,省略了共享类的加载过程,提升JVM启动速度;同时,多个JVM共享同一个归档文件,减少动态内存占用,可以提升内存使用率。该类方案主要适用于类加载比较多的场景,在一般场景下提升有限,且其对共享类的支持有一定限制,如运行时动态生成类不支持共享等。
  • 其他针对性(Spring框架)方案:

如Lazy Initialization[3]、Scanning-index[4]等,前者通过懒加载的方式来减少启动时加载类的数量,一定程度上提升启动速度;后者通过在编译阶段创建索引,避免启动时扫描所有路径来进行加速。但是该类方案在Serverless场景缺乏一定的普适性。

华为云FunctionGraph创新提出的基于进程级快照的冷启动加速解决方案,致力于在用户无感知(无需/少量进行代码适配)的前提下,帮助用户突破冷启动的性能瓶颈。本优化方案直接从应用初始化后的快照进行运行环境恢复,跳过复杂的框架、业务初始化阶段,从而显著降低Java应用的启动时延,实测性能提升达90%+。

Part II:快照方案如何优化Java应用启动速度

当用户Java函数打开冷启动加速的配置开关后,华为云FunctionGraph会预先执行函数对应的初始化代码,获取其初始化执行上下文环境的快照,并进行加密缓存。后续调用该函数并触发冷启动扩容时,会直接从提前初始化后的应用快照来恢复执行环境,而非重新走一遍初始化流程,以此达到极大提升启动性能的效果。

先结合图3直观对比一下优化前、后的冷启动流程差异:

图3:基于快照加速的冷启动流程

基于快照的冷启动流程,主要包含以下几个关键步骤:

Step 1:平台侧提前准备执行环境,并预执行初始化代码、保存应用快照,此动作后续统称为Checkpoint

  • 与图1对应,此阶段一般占总耗时的90%左右。

Step 2:在请求到达,触发函数新实例扩容时,直接从应用快照来恢复新的执行环境,此动作后续统称为Restore

  • Restore 耗时是秒级,相当于将数十秒完整的初始化时间(在图 1 的示例中)缩短至秒级 Restore 耗时,启动性能提升了一个数量级。

Step 3:(可选)应用进程从快照恢复后,执行Restore Hook完成业务状态的刷新

  • 由于Image File是进程运行时的快照,在重建进程之后,会涉及到进程持有状态的有效性更新。例如已建立的外部链接、加载到进程里的缓存信息等。故我们引入了Restore Hook的概念,提供手段让业务对这些状态进行刷新,详见Part IV。

Step 4:应用Ready,具备接着往下执行业务逻辑的能力

特别的,容器本身也是主机上的进程,故本优化方案也支持容器粒度的Checkpoint,即对容器内指定进程进行CR,与传统的轻量化虚机快照相比,其精细化程度更高、也更灵活。其原理详见图4:

图4:基于容器的CR流程

  1. 在Source机器上启动微服务,通过健康检查和初始化调用后,进行Checkpoint,停止服务,生成进程快照信息;
  2. 在Source机器上将进程快照信息和微服务所有相关依赖,进行压缩,加密生成内存快照包,并上传至云端存储。
  3. 在Target机器上从持久化存储中下载对应微服务的内存快照包,进行解压恢复。
  4. 在Target机器上Restore微服务进程;

Part III:快照技术揭秘

华为云提出的基于进程级快照的冷启动加速方案,其核心技术依托于CRIU[5],它支持对用户空间指定的进程进行“冻结”(即停止进程,并将该进程运行的所有上下文持久化为镜像文件),并在必要时对其进行“解冻”(即通过保存的镜像文件来正确恢复进程运行的上下文),其核心工作流程如图5-6所示[6]:

图5:CRIU如何工作——Checkpoint

图6:CRIU如何工作——Restore

Checkpoint

    1. CRIU首先通过操作系统的 /proc 目录获取指定进程和该进程下所有子进程的信息,包含文件描述符(/proc/$pid/fd)、管道参数、网络配置和内存映射文件(/proc/$pid/maps)等;
    2. CRIU接着通过Linux 的ptrace syscall接口把一段特殊代码动态注入到该进程的地址空间,通过执行该动态代码,CRIU以UNIX守护进程的方式收集dumpee进程存放在寄存器里的内存数据;
    3. CRIU将所有进程信息都收集完毕后,再次调用ptrace接口,去掉动态注入的代码,恢复该进程的原有代码;
    4. CRIU根据收集的进程内存信息,生成多个以功能分类的镜像文件,并默认杀死进程,完成Checkpoint;

Restore

    1. CRIU解析Checkpoint阶段生成的镜像文件,并分析多进程的共享资源;
    2. CRIU通过Linux 的fork 接口重新构建、恢复进程和其共享资源;
    3. CRIU恢复所有任务的资源,但不包含内存映射地址,定时器,线程等;
    4. CRIU根据镜像文件重新映射内存空间,切换进程上下文,恢复进程的继续执行,完成Restore;

Part IV:Restore Hook

如Part II所述,虽然本优化方案能极大提升Java应用的冷启动速度,但是快照技术在某些场景也存在一定的局限性,较难做到对现有应用的全透明化。通过快照恢复后,应用的网络连接状态会受到影响,涉及到TCP Socket重连等场景,如服务注册、DB连接,分布式通信,消息队列等。

这部分场景依赖应用本身的网络重连机制来更新正确,因此,本优化方案中也引入了Restore Hook的概念,提供手段让业务对这些状态进行刷新。

Restore Hook当前已支持大部分主流第三方组件的重连,详见图7:

图7:Restore Hook支持的第三方组件

不难发现,Restore Hook需要应用本身进行少量的代码适配。为了进一步简化应用的改造负担,我们也进行了一种新的技术尝试,可以理解其充当了用户应用与BaaS之间的纽带,通过状态卸载等手段,对开发者透明,帮助应用完成状态的自动化刷新。这部分探索会在后续的技术博文中跟大家分享,敬请期待。

三、效果实测:Java冷启动时延降低90%+

我们选取了公司内部典型的Java应用,对其原始初始化流程、Restore流程进行了对比测试,如图8所示。测试结果表明,本优化方案将应用的启动速度平均提升了95%+,即使快照包的增大一定程度上增加了包下载、解压的耗时,但最终端到端的冷启动时延也降低了90%+。

图8:冷启加速前后的数据对比

四、快速上手:基于华为云FunctionGraph的简单实战

华为云发布的基于进程级快照的冷启动加速方案,是一种性能优化服务,用户无需额外付费,只需进行简单的配置、少量的代码修改,即可享受到该创新方案带来的冷启动性能提升。

下文基于华为云FunctionGraph,为大家带来特性Quick Start

1、登录FunctionGraph控制台,创建Java函数,并打开“快照式冷启动”开关

2、(可选)配置Restore Hook,并在函数代码中实现对应的Hook逻辑

3、函数发布新版本后,触发快照的自动化制作

4、请耐心等待快照制作完成(5min超时时间)

5、调用Java函数,体验快照优化后的性能提升

五、总结与展望

本文介绍了华为云对冷启动优化这一业界难题的探索之路,创新提出了基于进程级快照的优化方案。当然,本方案也并非十全十美,它依然面临着一系列挑战,如文中提到的应用状态刷新、进程级CR的精细化控制、多平台的兼容性等,我们也在持续探索、优化中。

同时,FunctionGraph 作为华为元戎内核加持的下一代 Serverless 函数计算与编排服务,致力于持续为用户提供方便、迅捷的Serverless 服务体验。您可以登录华为云FunctionGraph控制台来深入体验,更多信息请参阅FunctionGraph官方文档[7]。后续我们将分享更多围绕通用全场景 Serverless的前沿理论及其案例实践,回馈社区。

参考资料

[1]https://www.graalvm.org/22.3/reference-manual/java/compiler/

[2]https://wiki.openjdk.org/display/HotSpot/Application+Class+Data+Sharing+-+AppCDS

[3]https://spring.io/blog/2019/03/14/lazy-initialization-in-spring-boot-2-2

[4]https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-scanning-index

[5]https://github.com/checkpoint-restore/criu

[6]https://speakerdeck.com/udzura/introduction-to-criu?slide=32

[7]https://support.huaweicloud.com/functiongraph/index.html

 

点击关注,第一时间了解华为云新鲜技术~

有关华为云发布冷启动加速解决方案:助力Serverless计算速度提升90%+的更多相关文章

  1. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  2. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  3. 华为常用命令 - 2

    system-view进入系统视图quit退到系统视图sysname交换机命名vlan20创建vlan(进入vlan20)displayvlan显示vlanundovlan20删除vlan20displayvlan20显示vlan里的端口20Interfacee1/0/24进入端口24portlink-typeaccessvlan20把当前端口放入vlan20undoporte1/0/10删除当前VLAN端口10displaycurrent-configuration显示当前配置02配置交换机支持TELNETinterfacevlan1进入VLAN1ipaddress192.168.3.100

  4. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

  5. ruby - 使用 Capistrano 启动 sidekiq - 2

    我想用Capistrano启动sidekiq。下面是代码namespace:sidekiqdotask:startdorun"cd#{current_path}&&bundleexecsidekiq-c10-eproduction-Llog/sidekiq.log&"pcapture("psaux|grepsidekiq|awk'{print$2}'|sed-n1p").strip!endend它执行成功但sidekiq仍然没有在服务器上启动。输出:$capsidekiq:starttriggeringloadcallbacks*2014-06-0315:03:01executing`

  6. ruby-on-rails - fastercsv 的 Rails 3 服务器启动问题 - 2

    我有一个正在升级到Rails3的Rails2.3.5应用程序。我做了所有我需要做的升级以及当我使用启动Rails服务器时要做的事情railsserver它给了我这个PleaseswitchtoRuby1.9'sstandardCSVlibrary.It'sFasterCSVplussupportforRuby1.9'sm17nencodingengine.我正在使用ruby-1.9.2-p0并安装了fastercsv(1.5.3)gem。在puts语句的帮助下,我能够追踪到错误发生的位置。我发现执行在这一行停止了Bundler.require(:default,Rails.env)if

  7. 电脑启动后显示器黑屏怎么办?排查下面4个问题,快速解决 - 2

    电脑启动出现显示器黑屏是一个相当常见的问题。如果您遇到了这个问题,不要惊慌,因为它有很多可能的原因,可以采取一些简单的措施来解决它。在本文中,小编将介绍下面4种常见的电脑启动后显示器黑屏的原因,排查这些原因,快速解决! 演示机型:联想Ideapad700-15ISK-ISE系统版本:Windows10一、显示器问题如果出现电脑启动后显示器黑屏的情况。那么首先您需要检查一下显示器是否正常工作。您可以通过更换另一个显示器或将当前显示器连接到另一台计算机来检查显示器是否存在问题。如果问题仍然存在,那么您可以排除显示器故障的可能性。 二、显卡问题如果您的电脑配备了独立显卡,那么显卡故障也可能是导致电脑

  8. 华为OD机试真题 C++ 实现【带传送阵的矩阵游离】【2023 Q2 | 200分】 - 2

            所有题目均有五种语言实现。C实现目录、C++实现目录、Python实现目录、Java实现目录、JavaScript实现目录题目n行m列的矩阵,每个位置上有一个元素你可以上下左右行走,代价是前后两个位置元素值差的绝对值.另外,你最多可以使用一次传送阵(只能从一个数跳到另外一个相同的数)求从走上角走到右下角最少需要多少时间。输入描述:第一行两个整数n,m,分别代表矩阵的行和列。后面n行,每行m个整数,分别代表矩阵中的元素。输出描述:一个整数,表示最少需要多少时间。

  9. 西安华为OD面试体验 - 2

    西安华为OD面试体验开始投简历技术面试进展工作进展开始投简历去年一整年一直在考研和工作之间纠结,感觉自己的状态好像当时的疫情一样差劲。之前刚毕业的时候投了个大厂的简历,结果一面写算法的时候太拉跨了,虽然知道时dfs但是代码熟练度不够,放在平时给足时间自己可以调试通过,但是熟练度不够那面试当时就写不出来被刷了。说真的算法学到后期我感觉最重要的是熟练度和背板子(对于我这种普通玩家来说),面试题如果一上来短时间内想不出思路就完蛋了。然后由于当时找的工作不是很理想就又想考研了。但是考研是有风险的,我自我感觉自己可能冲不上那个学校,而找工作一个没成可以继续找嘛。本着抱着试试看的态度在boss上投了简历,

  10. 如何判断oracle是否启动及启动oracle数据库 - 2

    plsql连接Oracle超时,完犊子了肯定是服务器断电了。得马上检查Oracle服务器状态1、检查数据库是否启动su-oracle切换到Oracle用户,输入sqlplus/assysdba显示连接状态。如果末尾显示的状态是Connectedtoanidleinstance.证明未启动2、启动数据库startup启动数据库,末尾出现Databaseopened说明数据库启动成功3、查看数据库监听是否正常先quit;断开Oracle连接,使用lsnrctlstatus查看监听状态,如果出现TNS-开头的Nolistener、Connectionrefused等错误,说明监听未启动4、启动数据库

随机推荐