全部产品
云市场

函数计算冷启动优化最佳实践

更新时间:2019-09-24 14:09:40

按量函数实例的冷启动优化

函数计算为用户提供了按量和预留两种类型的资源。按量资源是指函数实例的分配和释放完全由函数计算系统负责,用户只需要根据实例执行请求的时间按需付费。按量实例大大简化了用户管理应用资源的难度,但也造成了冷启动延时毛刺等性能问题。

按量实例的冷启动环节

如上图所示,冷启动是指在函数调用链路中包含了代码下载、启动函数实例容器、运行时初始化、用户代码初始化等环节。当冷启动完成后,函数实例就绪,后续请求就能直接被函执行。冷启动的优化是一个共享的责任(shared responsibility),需要开发者和平台共同努力。函数计算已经对系统侧的冷启动做了大量优化。对于用户侧的冷启动,建议您通常从以下几方面优化:

  1. 精简紧凑的代码包: 开发者要尽可能瘦身代码包,去掉不必要的依赖。降低 Download/Extract Code 的时间。例如对 Nodejs 函数使用 npm prune, 对 Python 函数使用autoflake,autoremove 去除没有使用的依赖。另外一些第三方库中可能会包含测试用例源代码,无用 binary 和数据文件。有选择地删除无用文件可以降低函数代码下载解压时间。
  2. 选择合适的函数语言: 由于语言理念的差异,Java 运行时冷启动时间通常要高于其他语言。对于冷启动延迟敏感的应用。在热启动延迟差别不大的情况下,使用 Python 这样的轻量语言可以大幅降低长尾延迟。
  3. 选择合适的内存: 在并发量一定的情况下,函数内存越大,冷启动表现越优。
  4. 降低冷启动概率:
    • 使用定时触发器 预热函数
    • 使用 Initializer 函数入口,函数计算会异步调用初始化接口,消除掉 “User Code Init” 的时间,在函数计算系统升级或者函数更新过程中,用户对冷启动无感知。

使用预留实例优化函数性能

很多时候,用户难以消除用户侧的冷启动。比如深度学习推理中,要加载数 GB 的模型文件;或者函数要和遗留系统交互,必须使用初始化耗时很长的客户端等等。在这些场景下,如果函数对延时非常敏感,您可以为函数预留实例,或者在同一个函数里同时使用预留和按量实例。预留实例的分配和释放由用户管理,根据实例的运行时长计费。当负载对资源的需求超过预留实例的能力后,系统自动使用按量实例,从而在性能和资源利用率上获得很好的平衡。通过预留实例,一方面用户能够根据函数的负载变化提前分配好计算资源;另一方面系统能够在扩容按量实例时仍然使用预留实例处理请求,从而彻底消除冷启动带来的延时毛刺。下图展示了用户混合使用预留和按量资源的情况,既避免了冷启动的延时毛刺,又实现了极高的资源利用率。

在函数的预留和按量资源间自动伸缩

当用户混合使用预留和按量实例时,函数计算保证优先使用预留资源实例。假设您为函数预留了 10 个实例,意味着每秒钟能使用的预留资源是 10 个实例的算力。如果一秒内需要的实例数超过 10 个,系统会创建新的按量实例处理请求。判断一个实例是否满载和该实例上的并发请求数配置有关。系统追踪每个函数实例上正在处理的请求数,当并发的请求数达到用户设定的上限后,系统会选择其他的函数实例。当所有实例的请求数都达到上限后,则创建新的实例。预留实例由用户管理,即使没有请求,您也需要为闲置的预留实例付费。按需实例由函数计算系统管理,系统在适当的时候将回收没有请求处理的闲置按量实例。您只需为按量实例实际处理请求的时间段付费。计费规则详情请参考函数计算计费文档。您可以设置按量资源的使用上限,确保资源的使用在期望的范围内。

函数计算提供“活跃实例数(Active Instance Count)”指标帮助您掌控函数实际使用的资源。该指标的含义是当前时刻正在处理请求的预留和按量函数实例数总和,详情请参见指标项文档。如下图所示,通过对比活跃实例数和预留实例数,您能够一目了然的判断是否设置了合理数量的预留资源。

合理设置预留资源

总结

综上,函数计算为您提供了丰富的手段和指标项,帮助您轻松消除冷启动带来的延时毛刺,获得稳定的性能。