现在“Serverless”可能是一个流行术语,但是它并非空洞的存在。AWS Lambda推出还不到5年的时间,就已经被近一半使用AWS基础设施的公司所采用。在本报告中,我们分析了数千家公司的Serverless使用情况,以了解在现实中他们是如何使用Serverless(以及使用到了什么程度)。
Serverless消除了提供和管理基础设施组件(例如,服务器、数据库、队列,甚至容器)的必要性,能够允许团队专注于代码,同时最小化他们的运维开销。本报告将关注Serverless领域的一个子集,即所谓的“函数即服务”(functions-as-a-service, FaaS),它提供了与公共云相同的即付即用模型,但处于“函数”级别,而不是基础设施组件级别。函数只是简单的代码片段,在用户请求或其他事件调用时执行离散的业务逻辑。
对于本报告来说,我们会关注AWS Lambda,它在2020年初是我们的用户群中最成熟和被广泛采用的Serverless平台。在该报告的未来版本中,我们可能会研究来自其他提供商的Serverless产品,比如Google Cloud Platform和Microsoft Azure。
在2020年初,Lambda已经不再是小众的技术。使用Amazon Web Services的Datadog客户中有近一半已经采用了Lambda。(参见文末的方法论章节以了解我们是如何定义采用Lambda和使用AWS的。)这样的采用率,再结合下面章节所讨论的根据环境分解的Lambda使用情况,表明Lambda并不局限于云原生的早期采用者和小众使用场景。相反,在采用AWS基础设施的各种各样的公司中,serverless函数得到了广泛的应用。
令人意外的是,Lambda的广泛采用并不是由更新、更小的公司所驱动的。相反,我们看到Lambda的采用情况与公司基础设施环境的大小有着明显的相关性,无论环境指的是主服务器、容器,还是serverless函数均是如此。(参见文末的方法论章节以了解我们规模区分的详细信息。)在基础设施规模最大的那些公司中,超过四分之三的公司都采用了Lambda。
在AWS中运行容器的公司特别中意于Lambda。截至2020年1月,在AWS运行容器的组织中有近80%都采用了Lambda。尽管serverless函数和容器是两个非常不同的环境,但是它们似乎基于类似的原因而被众人所接受,比如为了简化运维而抽象出基础设施的关注点。在一些使用场景中,Lambda和容器基础设施是直接连接的(例如,使用Lambda函数来触发Amazon Elastic Container Service的任务),但是更多的组织可能正在分别运行它们,以满足不同的需求。例如,某家公司可能在一个容器集群中运行其大部分的应用程序,同时将突发的、短期运行的任务(例如支付处理)转移到serverless的函数中。
在将函数连接至基础设施和应用程序组件时,Lambda用户有大量可选的技术。当函数被触发时,它通常会将自己所产生的数据发送给消息队列,而消息队列可以将数据路由至其他的Lambda函数、基于服务器的应用程序或者云服务。消息队列能够让组织采用“仅为真正使用的内容服务”的serverless模式。相对于调用其他的函数并一直等待响应(占用可计费的调用时间),serverless可以通过消息队列的方式进行异步调用。由于函数是临时的和无状态的,所以它们通常会对单独的持久化数据存储进行读写操作。
在与Lambda函数相同的请求中所调用或查询的服务里面,Amazon DynamoDB名列前茅。键值和文档存储非常适合Lambda函数,因为它是一个托管的、可自动伸缩的数据存储,可以保证低延迟。在使用Lambda的场景中,数据存储方面另一个最流行的选择是SQL数据库(无论是Amazon RDS实例还是自管理数据库)和Amazon S3。Amazon SQS(Simple Queue Service)是Lambda请求中消息队列的首选,其次是Amazon Kinesis和Amazon SNS(Simple Notification Service)。SQS在逻辑上非常适合serverless架构:它易于搭建和扩展,成本相对较低,并且提供与Lambda的紧密集成。
在Lambda用户可用的语言和框架中,我们看到有两个明显占据了主导地位:Python和JavaScript(借助Node.js)。在当前所有已部署的Lambda中,有47%在运行Python,另外还有39%在运行Node.js应用。Python 3与Python 2的比例是2比1(Python 2在2020年1月正式结束了其生命)。
Python和Node.js的Lambda运行时的流行程度反映了最近应用程序开发的趋势以及Lambda服务本身的发展。AWS在2014年首次发布Lambda预览版,其中Node.js就是第一个得到支持的运行时,2015年又增加了对Java和Python支持。对C#(借助.NET Core)、Go和Ruby的支持则是在2018年新增的。
Lambda函数运行时间的中位数约是800毫秒,这是在所有调用中取平均值得到的,但是延迟分布曲线的尾部很长。四分之一的Lambda函数平均执行时间超过3秒,12%的函数执行时间超过10秒。一些Lambda函数的持续时间很长,这是值得注意的,因为serverless的延迟不仅影响应用程序的性能,还会影响云计算的成本。Lambda定价是基于计算时间的“GB-seconds”:分配给函数的内存(详细信息如下图所示),并乘以其调用的持续时间。
我们将函数持续时间的分布放大一下可以发现,将近五分之一的函数在100毫秒内执行完成,大约三分之一在400毫秒内执行完成。
如前所述,Lambda调用的成本是根据持续时间和函数内存的乘积计算出来的。因此,鼓励运行Lambda的公司限制其函数的内存分配(这是一个可配置的设置,因此比函数的持续时间更容易控制)。实际上,47%的函数被配置为使用最小的内存运行,即128 MB,而只有14%的函数的内存分配大于512 MB,用户可以为每个函数最多分配3,008 MB。
每个Lambda函数都有一个可配置的超时设置,时间从1秒到15分钟不等,这是Lambda调用所允许的最长持续时间。大多数函数都使用了较短的超时:三分之二的超时时间配置为60秒或更少。(创建函数时的默认超时时间为3秒。)
通常来讲,建议的做法是使用较短的超时时间,因为挂起函数会增加云成本,而且Lambda应用程序架构经常需要快速响应。Amazon API Gateway通常用于在Lambda函数前提供REST接口,它的最大超时设置为29秒。因此,API网关后面的任何Lambda函数如果响应时间超过29秒的话,都将会导致一个错误,即使Lambda最终成功地完成了它的工作也是如此。尽管有这些考虑因素,但是依然有许多函数都配置为所允许超时的最大设置:当前的900秒限制以及之前的300秒限制(有效期到2018年10月)。
默认情况下,在每个region中,Lambda客户的所有函数会有1000个并发执行的限制。用户可以设置每个函数的并发限制,这样的话,就能够为特定函数在总并发池中预留一部分。如果函数超过了它的并发限制,就会进行节流。
如今,在所有的函数中,尽管大多数组织都知道有这个可选限制,但是只有4.2%的函数配置了并发性限制。实际上,88.6%运行Lambda的公司在其环境中至少为一个函数使用了并发限制。定义了并发限制的函数更有可能被限流。在5天的评估窗口中,具有并发限制的函数中有8.3%至少被限制一次,而只有0.3%的函数仅受到region的限制,而不是每个函数本身的限制。
在本报告中,我们收集了Datadog客户群中数千家公司的使用数据。虽然Datadog的客户涵盖了各个公司规模和行业范围,但他们确实有一些共同的特点。首先,他们往往对软件基础设施和应用程序的性能非常重视。他们比一般的人群更倾向于采用云平台和服务。本文中的所有结果都存在偏见,因为数据来自我们的客户群,这是一个庞大但不完美的全球市场样本。
在这个报告中,我们认为如果某家公司一个月里至少运行五个不同的Lambda函数,那么我们就认为他们采用了Lambda。Datadog Forwarder函数会将S3和CloudWatch日志等数据发送到Datadog,该函数不包含在计数中。
如果一个公司在一个月内至少运行5个不同的Lambda函数或5个不同的EC2实例,那么我们就认为该公司在使用AWS。通过这种方式,我们可以捕获AWS用户的基本信息,从而将它们分为专门运行EC2实例的公司、专门运行serverless 函数的公司或同时运行这两种功能的公司。
为了评估公司基础设施环境的相对规模,我们检查了公司的serverless函数、容器、物理服务器、云实例和其他基础设施服务的使用情况。虽然类别(如“中型”和“大型”)之间的界限必然是人为定义的,但类别之间的趋势是明显的。
原文链接:
https://www.datadoghq.com/state-of-serverless/
本文最初发表于Datadog站点,授权InfoQ中文站翻译分享。
领取专属 10元无门槛券
私享最新 技术干货