“AI 技术+人才”如何成为企业增长新引擎?戳此了解>>> 了解详情
写点什么

如何解决“Serverless”系统的冷启动问题

  • 2021-09-09
  • 本文字数:3389 字

    阅读完需:约 11 分钟

如何解决“Serverless”系统的冷启动问题

就像生活中所有的美好事物一样,Serverless(无服务器)也有其缺点。

 

其中一个缺点就是臭名昭著的“冷启动”(Cold Start)。在本文中,我们将介绍“冷启动”是什么,影响 Serverless 启动延迟的因素有哪些,以及如何减轻它们对应用程序的影响。

什么是冷启动?

 

“冷启动”是指函数服务于特定调用请求时的状态。

 

Serverless 函数由一个或多个微容器提供。当某个请求传入时,我们的函数将会检查是否已有某个容器正在运行来为该调用提供服务。

 

当某个空闲容器已经可用时,我们称之为“热”(“warm”)容器。如果没有现成的容器,函数将启动一个新的容器,这就是我们所说的“冷启动”。

 

当处于“冷态”(Cold State)的函数被调用时,完成请求将需要额外的时间,因为启动新容器会有延迟。这就是冷启动的问题:它们使得应用程序的响应变慢了。在 21 世纪的“即时时代”(instant-age),这可能是一个大问题。

冷启动是怎样工作的?



现在,我们已经知道了什么是“冷启动”,那么让我们深入了解一下它们的工作原理。其内部工作原理可能会因你所使用的服务(AWS Lambda、Azure Functions 等)或开源项目(OpenFaas、Kubeless、OpenWhisk 等)的不同而不同,但一般来说,这些原则适用于所有的 Serverless 计算架构。

 

当请求由某个 Serverless 容器提供服务之后,该容器通常能保持活动状态并允许空闲一段时间。容器编排系统将根据其参数来决定是否关闭以及何时关闭该容器。

 

这是一种权衡:保持容器处于活动状态将能节省启动资源并加快后续的请求速度,但会增加空闲的时间成本。

 

AWS Lambda 通常能使容器“保活”(保持活动状态)30-45 分钟。有时还不止这些(特别是对于在 VPC 内运行的 Lambda),但它不是一个文档化或承诺的参数,所以不要盲目地信任它。

 

当容器从“冷态”开始启动时,函数需要:

 

  1. 从外部持久化存储中获取代码包;

  2. 逐步启动(Spin up)容器;

  3. 在内存中加载程序包代码;

  4. 运行函数的处理程序(handler)方法/函数。

 

这些步骤需要一段时间才能完成,尤其是第 1 到第 3 步。当容器已经变“热”后,它会直接跳到第 4 步,这样可以节省大量的时间并能使应用程序的响应更快。

启动延迟如何改善?

 

“冷启动”的影响从几百毫秒到几秒或几十秒不等。导致冷启动延迟的主要因素有:

 

  • 内存大小:分配给函数的内存越多,启动速度越快;

  • 运行时:与编译运行时(Java、.NET、C#)相比,通常脚本语言(Python、Ruby、Javascript)在启动时的性能要好得多; 我的意思是,速度能提高 100 倍,这是很重要的;

  • VPC:在虚拟私有云中运行的函数会有额外的延迟,通常要多一到两秒才能启动;尝试着将你的函数设计为运行于 VPC 之外;

  • 代码包大小:包越大,启动新容器所需的时间越长,尽管如此,这可能是影响启动延迟最不重要的因素了。

如何解决或缓解容器的启动延迟?

 

以下 6 种策略可以解决或至少可以缓解容器启动延迟对 Serverless 应用程序的影响:

 

  • 监控性能并记录相关指标

  • 增加内存分配

  • 选择更快的运行时

  • 将共享数据保存在内存中

  • 压缩程序包的大小

  • 保留一个预热的函数池

  • 使用时间序列预测

监控性能并记录相关指标

 

我们讨论了导致容器启动延迟的基础设施因素,但我们的代码也是一个主要因素。我们需要不断地监控应用程序的性能,以便识别性能瓶颈以及导致执行时间增加或减少的原因。

 

为了做到这一点,建议在函数执行期间始终记录时间戳,并监控函数调用历史记录中的持续时间异常值。 每当它的性能低于预期时,查看日志并确定代码的哪些部分导致了性能的下降。

 

AWS X-RayDashbird 等服务支持这种开箱即用的分析,能为你在性能优化过程中节省大量的时间。 如果你在专业项目的生产环境中运行 Serverless 函数,则必须要使用此类服务。

 

增加内存分配

 

据观察,分配了更多的内存的函数往往能更快地启动新容器。如果在你的用例中,成本不是问题,那么可以考虑为你的函数分配更多的内存以获得最佳的启动性能。

为对启动时间敏感的工作负载选择更快的运行时

 

像 Python 和 Ruby 这样的脚本语言比编译后的运行时性能要好得多。Yan Cui 在 AWS Lambda 中对不同语言的启动时间做了一个非常棒的比较。

 

Python 的性能最好,其启动时间比 Java、C# 和 NodeJS 等竞争者快了 100 倍。只要有可能,请考虑使用轻量级语言(如 Python)编写 Serverless 函数。

 

尽管 Python 脚本的执行速度较慢(由于它的解释性质),但减少的启动延迟可能能抵消并提供更好的整体性能(以及降低来自云供应商的费用)。

通过在主事件处理函数之外加载来将共享数据保留在内存中


Serverless 函数通常有一个处理程序(Handler)方法/函数作为底层基础设施和代码之间的接口。该函数通常会将一个事件和上下文作为参数传递给我们的函数,然后神奇的事情就发生了。

 

有趣的是,我们可以在这个方法/函数之外运行代码。假设每次调用我们的函数时,它都需要导入一个相同的三方库,或者可能从外部持久化存储中获取对象。我们可以在调用处理程序方法/函数之前在处理程序外部执行这些操作,而不是在调用处理程序方法/函数之后再执行这些操作。

 

只要容器保持活动状态,在处理程序之外声明并执行的所有内容都将保留在容器的内存中。当它再次被调用时(从“热”状态),数据的导入或获取将不需要再次运行,可以直接从内存中获取并使用它们,从而加快了代码的执行时间。

 

这不会加快冷启动,但会减少后续请求的启动时间。总的来说,我们的应用程序将会有更好的性能。

压缩程序包的大小

 

当我们为 Serverless 函数打包代码时,通常会将所有的东西都放到压缩文件中(从 README 文件到不必要的三方库文件)。

 

在部署到生产环境之前,清理我们的包是很重要的,删除函数运行时不使用或不需要的所有内容。这将有助于减少内部网络延迟,从而缩短冷启动时间——该函数将获取更小的包文件。

保留一个预热的函数池

 

如果你仍然无法忍受冷启动的延迟时间,那么最后的办法是设置常规作业来保留一组预热的函数池。工作原理如下:

 

对函数进行配置,以快速识别短路的预热调用并终止请求,而无需运行整个函数代码。这可以通过向函数传递一个预先确定的事件来实现,例如: {"warm": true}。当函数检测到该事件参数时,只需尽可能快地终止执行。

 

设置一个常规作业(例如 CRON),每隔几分钟调用一次函数。具体时间视情况而定。AWS Lambda 通常能使容器“保活”(保持活动状态)约 30-45 分钟,但其变化很大。

 

通过调用该函数,Serverless 底层系统将启动一个新容器并使其“保活”一段时间。如果有一个预热过了的容器,它会因为最近的热调用而保活更长的时间。当真实的用户请求你的 API 时,该容器将能用于更快的响应。

 

Jeremy Dale 是一个开源且有趣的软件包,可用于帮助管理 AWS Lambda 的“加热策略”(warming strategies),你可以深入了解一下它。Serverless 框架还有一个有用的插件

 

注意并发影响:如果你只为你的函数保活了一个容器,但进入了两个并发请求,其中一个将从热态提供服务,但第二个将是冷启动。

 

这是因为只有一个容器是热的,它一次只能满足一个请求。如果你的应用程序通常服务于多个并发请求,那么你需要在“加热策略”中考虑到这一点。

用时间序列预测预热策略

 

如果你真的担心冷启动延迟,并且你的应用程序负载在并发请求的数量上显示出很大的差异,那么你可能需要稍微增加一些策略。

 

你可以使用时间序列预测来预测每个时间点应加热多少个容器。StatsModels 是一个开源项目,它提供了处理时间序列的最常用算法。这里有一个很好的教程可以帮忙你入门。

 

我们需要的基本上是一个双轴时间序列样本:

 

  1. 特定时间段内的一系列间隔(例如,过去 3 个月内每间隔 10 分钟)

  2. 在该时间间隔内,函数处理的最大并发请求数

 

我们会定期(例如,每 10 分钟)运行一次时间序列预测,以预测在下一个时间间隔(例如,下一个 10 分钟)内需要同时运行多少个容器。调整加热策略以确保预热相应数量的容器。

 

使用统计预测的一个积极的方面是,它将返回标准差(Standard Deviation,SD)。考虑到数据和 SD 的概率分布,你可以估计预测的置信水平。

 

假设你希望自己的预测 99% 都是确定的;你需要获取的所需容器预测数量,并将 SD 乘以一个系数。这个系数取决于你的数据分布。例如,如果是正态分布,这个系数将是 2.58。如果你想要更深入得了解这个主题,请阅读更多有关置信区间的内容。

 

原文链接:


https://hackernoon.com/how-to-solve-the-problem-of-cold-starts-in-serverless-systems

2021-09-09 11:374575

评论 1 条评论

发布
用户头像
python比nodejs和java快100倍,纯属胡说,阿里云架构师告诉我的
2022-10-11 17:39 · 上海
回复
没有更多了
发现更多内容

让下载速度更快更稳,华为云CDN多重技术助力网络加速

爱科技的水月

【web 开发基础】PHP中获取数组的元素个数 (51)

迷彩

数组 数组操作 PHP基础 数组查询 统计数组

人生的喜悦、不快与成长,都在那一篇篇的文字中得到记录 | 2022 年终总结

宇宙之一粟

年终总结 人生故事 代码之外 12月月更

华为云大数据BI,如何助力智慧医院数字化升级

秃头也爱科技

浅谈华为云大数据BI对企业数字化转型的助力

秃头也爱科技

直播回顾 | 根因分析助力AIOps走得更远!

博睿数据

可观测性 智能运维 博睿数据

聚焦电商场景数字化转型升级,华为云大数据解决方案高效赋能

爱尚科技

“一粒米”的故事:哈工程昇智识米团队基于昇腾AI创新提出水稻适度加工智能化解决方案

Geek_2d6073

HarmonyOS多媒体框架介绍

HarmonyOS开发者

HarmonyOS

openEuler委员会主席江大勇:跨越生态拐点 欧拉逐梦新征程

科技热闻

据+AI赋能教育智能化转型,华为云技术优势明显!

爱尚科技

【架构设计】保持简单轻量设计的三个原则——DRY,KISS, YAGNI

JAVA旭阳

Java 架构

华为云大数据BI平台,助力电商企业破除数据孤岛,轻松备战双十一

秃头也爱科技

2022-12-29:nsq是go语言写的消息队列。请问k3s部署nsq,yaml如何写?

福大大架构师每日一题

云原生 k8s k3s nsq 福大大

共创精彩游戏未来,华为云大数据解决方案助力游戏企业成功转型!

秃头也爱科技

cleanmymac2024永久版mac系统清理软件

茶色酒

CleanMyMac CleanMyMac X

FL Studio2024中文版本水果软件下载

茶色酒

FL Studio FL Studio 21

华为云大数据BI,助力电商企业打赢“年货节”攻坚战

秃头也爱科技

【web 开发基础】如何删除数组中的重复元素(52)

迷彩

数组 数组操作 PHP基础 唯一性

助力网络碳中和 | 华为发布站点能源十大趋势

Geek_2d6073

华为云CDN引领网站性能全面优化

爱科技的水月

跳槽一次能涨多少?总算是见识到跳槽天花板了

程序知音

Java java面试 后端开发 八股文 Java面试题

HTTPS基础知识

穿过生命散发芬芳

https 12月月更

智能且高效,华为云CDN三大特点助企业云上创新

爱科技的水月

CleanMyMac2024激活码使用教程

茶色酒

CleanMyMac CleanMyMac X

Mysql索引覆盖

京东科技开发者

MySQL 数据库 sql 搜索引擎 优化

华为云大数据BI,企业数字化运营得力助手

爱尚科技

缓解等待焦虑,华为云CDN为您提供畅快下载体验

爱科技的水月

界面原型设计

攻城狮Wayne

android GUI设计 mockplus droiddraw

【web 开发基础】PHP查询数组中的指定元素 (50)

迷彩

数组 数组操作 二维数组 PHP基础 数组查询

为有状态应用而生,云原生本地存储Carina正式进入CNCF沙箱

BoCloud博云

云原生 本地存储 Carina

如何解决“Serverless”系统的冷启动问题_架构_Taavi Rehemägi_InfoQ精选文章