冷启动优化:开发者侧降低冷启动影响的方案

本文涉及的产品
函数计算FC,每月15万CU 3个月
简介: 冷启动优化:开发者侧降低冷启动影响的方案

代码包优化

在各个云厂商的FaaS平台中,都有着对代码包大小的限制,抛掉云厂商对代码包的限制,就单纯地说代码包的规格可能会产生什么影响,通过函数的冷启动流程可以看到:

在函数启动的过程中,有一个过程是加载代码的过程,那么当所上传的代码包过大,或者说文件过多导致解压速度过慢,就会直接导致加载代码这个过程变长,进一步直接导致冷启动时间变久。

可以设想一下,当有两个压缩包,一个是只有100KB的代码压缩包,另一个是200MB的代码压缩包,两者同时在千兆的内网带宽下理想化(即不考虑磁盘的存储速度等)下载,即使最大速度可以达到125MB/S,那么前者的下载速度只有不到0.01秒,后者需要1.6秒,除了下载时间之外,还有文件的解压时间,那么两者的冷启动时间可能就相差2秒。一般情况下,一个传统的Web接口,如果要2秒以上的响应时间,实际上对很多业务来说是不能接受的,所以在打包代码时就要尽可能地降低压缩包大小。以Node.js项目为例,打包代码包时,可以采用Webpack等方法,来压缩依赖包大小,进一步降低整体代码包的规格,提升函数的冷启动效率。

合理进行实例复用

在各个云厂商的FaaS平台中,为了更好地解决冷启动的问题,为了更合理地利用资源,是存在“实例”复用情况的。所谓的实例复用,就是当一个实例完成一个请求,他并不会释放,而是进入一个“静默”的状态,在一定时间范围内,如果有新的请求被分配过来,则会直接调用对应的方法,而不需要再初始化各类资源等,这个过程很大程度上降低了函数冷启动的情况出现。为了验证,可以创建两个函数:

  • 函数1:

    # -*- coding: utf-8 -*-
    
    def handler(event, context):
      print("Test")
      return 'hello world'
  • 函数2:

    # -*- coding: utf-8 -*-
    
    print("Test")
    
    def handler(event, context):
      return 'hello world'

在控制台多次点击测试按钮,对这两个函数进行测试,判断其是否在日志中输出了“Test”,可以统计结果:

第一次 第二次 第三次 第四次 第五次 第六次 第七次 第八次 第九次
函数1
函数2

根据上面表格情况,可以看到,其实实例复用的情况是存在的,因为函数2并不是每次都会执行入口函数之外的一些语句。根据函数1和函数2,也可以进一步思考,如果print("Test")语句是一个初始化数据库连接,或者是加载一个深度学习的模型,是不是函数1的写法就是每次请求都会执行,而函数2的写法是可以存在复用已有对象的情况?

所以在实际的项目中,有一些初始化操作,是可以按照函数2来进行实现的,例如:

  • 机器学习场景下,在初始化的时候加载模型,避免每次函数被触发都会加载模型带来的效率问题,提高实例复用场景下的响应效率;
  • 数据库等链接操作,可以在初始化的时候进行链接对象的建立,避免每次请求都创建链接对象;
  • 其他一些需要首次加载时下载文件,加载文件的场景,在初始化的时候进行这部分需求的实现,可以在实例复用的时候效率更高;

单实例多并发

众所周知,各云厂商的函数计算通常是请求级别的隔离,即当客户端同时发起三个请求到函数计算,理论上会产生三个实例来进行应对,这个时候可能会涉及到冷启动问题,可能会涉及到请求之间状态关联问题等,但是部分云厂商提供了单实例多并发的能力(例如阿里云函数计算),该能力允许用户为函数设置一个实例并发度(InstanceConcurrency),即单个函数实例可以同时处理多少个请求。

如图所示,假设同时有3个请求需要处理,当实例并发度设置为1时,函数计算需要创建3个实例来处理这3个请求,每个实例分别处理1个请求;当实例并发度设置为10时(即1个实例可以同时处理10个请求),函数计算只需要创建1个实例就能处理这3个请求。

单实例多并发的优势:

  • 减少执行时长,节省费用。例如,偏I/O的函数可以在一个实例内并发处理,减少实例数从而减少总的执行时长。
  • 请求之间可以共享状态。多个请求可以在一个实例内共用数据库连接池,从而减少和数据库之间的连接数。
  • 降低冷启动概率。由于多个请求可以在一个实例内处理,创建新实例的次数会变少,冷启动概率降低。
  • 减少占用VPC IP在相同负载下,单实例多并发可以降低总的实例数,从而减少VPC IP的占用。

单实例多并发的应用场景时比较广泛的,例如函数中有较多时间在等待下游服务的响应的场景就比较适合使用该种功能,但是单实例多并发也并不适合全部应用场景,例如当函数中有共享状态且不能并发访问的场景,单个请求的执行要消耗大量CPU及内存资源的场景,就不适合使用单实例多并发这个功能。

预留实例与冷启动优化

预留模式通过预留适量函数实例来响应函数调用请求,降低冷启动的发生次数,为时延敏感的在线业务提供更好的服务响应。所谓的预留实例指的是在一些情况下,FaaS平台没办法根据业务的复杂需求,自动进行高性能的弹性伸缩,但是业务方却可以对其进行一定的预测。例如,某团队在此是凌晨要举办一次秒杀活动,那么该业务对应的函数可能在秒杀活动之前都是沉默状态,在秒杀活动时突然出现极高的并发请求,此时即使是天然分布式架构,本身自带弹性能力的Serverless架构,也是很难高性能的迎接该挑战。所以,在活动之前,可以由业务方手动进行实例的预留,例如在次日零时之前,预留若干实例以等待流量峰值到来,次日23时活动结束时,释放所有预留实例。

虽然预留模式在一定程度上违背了Serverless架构的精神,但是在目前的业务高速发展过程中与冷启动带来的严重挑战下,预留模式还是逐渐的被更多厂商所采用,也被更多开发者、业务团队所接纳。虽然预留模式在一定程度上会降低冷启动的发生次数,但是也并非可以完全杜绝冷启动,同时在使用预留模式时,配置的固定预留值会导致预留函数实例利用不充分,所以此时,云厂商们通常还会提供定时弹性伸缩和指标追踪弹性伸缩等多种模式进一步解决预留所带来的额外问题。

定时弹性伸缩

由于部分函数有明显的周期性规律或可预知的流量高峰,所以可以使用定时预留功能来提前预留函数实例。所谓的定时弹性伸缩,指的是开发者可以更加灵活地配置预留的函数实例,在指定时间将预留的函数实例量设定成需要的值,使函数实例量更好地贴合业务的并发量。如图35所示,配置了两个定时操作,在函数调用流量到来前,通过第一个定时配置将预留函数实例扩容至较大的值,当流量减小后,通过第二个定时配置将预留函数实例缩容到较小的值。

instance

指标追踪弹性伸缩

由于在生产条件下,往往周期性的函数并发规律并不容易预测,所以在一些复杂情况下就需要通过一些指标进行实例预留设定。例如阿里云函数计算所拥有的指标追踪弹性伸缩能力就是通过追踪监控指标实现对预留模式的函数实例进行动态伸缩。这种模式通常被用于以下场景:函数计算系统周期性采集预留的函数实例并发利用率指标,使用该指标并结合您配置的扩容触发值、缩容触发值来控制预留模式函数实例的伸缩,使预留的函数实例量更好的贴合资源的真实使用量。

instance

如图所示,指标追踪弹性伸缩根据指标情况每分钟对预留资源进行一次伸缩,当指标超过扩容阈值时,开始以积极的策略扩容预留模式的函数实例量,最快速度将函数实例量扩容至目标值;当指标低于缩容阈值时,开始以保守的策略缩容预留模式的函数实例量,小幅度向缩容目标值贴近。如果在系统中设置了伸缩最大值和最小值,此时预留的函数实例量会在最大值与最小值之间进行伸缩,超出最大值时将停止扩容,低于最小值时将停止缩容。

目录
相关文章
|
4月前
|
测试技术
优化if-else的11种方案
优雅编码不仅提升程序效率,也增进代码可读性与维护性。通过早返回减少嵌套逻辑、运用三元运算符简化条件判断、采用`switch-case`优化多分支结构、实施策略模式灵活应对不同情境、利用查找表快速定位处理方式、封装函数明确职责划分、应用命令模式解耦操作与调用、引入状态模式管理复杂状态变化、重构条件表达式以增强清晰度、运用断言确保前提条件、及合理异常处理等十大技巧,使代码更加精炼与优雅。
88 4
优化if-else的11种方案
|
28天前
|
关系型数据库 Serverless 测试技术
评估特定业务场景下扩缩容操作对性能的影响的方法
通过以上多种方法的综合运用,可以较为全面、准确地评估特定业务场景下扩缩容操作对 PolarDB Serverless 性能的影响。这有助于制定合理的扩缩容策略,确保业务系统在不同资源配置下都能保持良好的性能表现,满足业务需求。
20 1
|
5月前
|
供应链
软件架构一致性问题之通过减少修改次数降低软件供应链管理的成本如何解决
软件架构一致性问题之通过减少修改次数降低软件供应链管理的成本如何解决
54 0
|
5月前
|
开发框架 Cloud Native Devops
对抗软件复杂度问题之软件复杂度的增加会导致研发效率降低,如何解决
对抗软件复杂度问题之软件复杂度的增加会导致研发效率降低,如何解决
|
5月前
|
NoSQL 中间件 应用服务中间件
代码的应用重构问题之通过重构降低资源成本问题如何解决
代码的应用重构问题之通过重构降低资源成本问题如何解决
|
数据采集 算法 编译器
倚天710规模化应用 - 性能优化 -自动反馈优化分析与实践
编译器优化分成静态优化与动态优化,静态优化指传统编译器gcc/llvm时,增加的优化等级,如O1,O2,O3,Ofast,此时,编译器会依据编译优化等级增加一些优化算法,如函数inline、循环展开以及分支静态预测等等。一般情况下,优化等级越高,编译器做的优化越多,性能会更会好。在阿里生产环境中,单纯依赖于静态优化,并不能达到程序运行流畅目的,通过分析CPU硬件取指令、执行指令,往往会出现一些分支预测失败导致iCacheMiss率高的场景,限制了程序的性能进一步提升。基于此,业务引入了动态反馈优化工具,依据生产环境的实际运行数据,反哺指导编译器对程序代码进一步调整编译优化策略,提高分支预准确率
|
Serverless
函数计算减少冷启动对性能的影响
函数计算减少冷启动对性能的影响
382 1
EMQ
|
存储 JSON 监控
MQTT X 1.9.1 发布:资源消耗降低 80%,稳定性大幅提升
MQTT 5.0客户端工具MQTT X 1.9.1稳定版本正式发布,CPU资源消耗与内存占用减少80%,整体性能大幅优化。
EMQ
209 0
MQTT X 1.9.1 发布:资源消耗降低 80%,稳定性大幅提升
|
存储 传感器 机器学习/深度学习
V2X会是未来趋势吗?看看这种轻量级方法,大幅降低碰撞概率!
本文提出了一种Ledger概念,它通过Ledger信息的广播,在一个资源预留区间(RRI)内向网络中的每辆车传递碰撞信息。碰撞车辆知道它已经与其他车辆相撞,并将在下一个 SPS 期间重新选择。除此之外,其他协议都遵循 SPS。通过引入 Ledger,虽然牺牲了14.29% 的资源,但最终可以降低碰撞概率。本文使用蒙特卡罗模拟器对Ledger系统的性能进行了验证和分析。数值结果表明,遵循 SPS 协议,Ledger 系统可以使碰撞概率在一定数量 RRI 后收敛到零。
V2X会是未来趋势吗?看看这种轻量级方法,大幅降低碰撞概率!