译者 | 蔡柱梁
策划 | Ethan
本文讨论了目前流行的用于实现无服务器架构扩展用例的架构,以及何时可以使用它们。
在本文中,我们讨论了大规模运行无服务器的注意事项。本文还讨论了目前流行的用于实现这种无服务器架构扩展用例的架构,以及我们如何以及何时可以通过 AWS Lambda 和 Dynamo DB 示例可扩展选项最佳地使用无服务器架构进行扩展。
一、为什么谈论无服务器的可扩展性?
当我们谈论可扩展性时,在许多情况下,可扩展性、可用性和性能可以通过客户完全控制的本地基础设施设置,得到最佳优化。但是,当预算审批收紧时,操作系统管理、服务器部署、管理员等的全天候维护和计费成本就会成为问题,并被认为是非常高的成本。
按需付款成为了节省开销的不二选择!
在无服务器架构中,需要优化代码以触发功能以响应事件,并且只需为触发事件处于活动状态的时间付费。仅当出现峰值时,负载突然飙升会导致更多事件,进而导致更多成本。因此,它显着降低了运营成本和与之相关的复杂性,并且开发人员可以专注于只提供生产性结果。在无服务器架构的情况下,云服务提供商处理 100% 的服务器管理,包括流量优化、开发环境更新、资源分配和后端配置。因此,这就像以更低的成本获得零到最小的开销!
在这里,在高峰负载期间,无服务器功能可以轻松扩展以响应高峰时的多个并发请求。
二、大规模无服务器应用程序的设计模型注意事项
1.设计:无服务器同步模型
在无服务器同步模型中,无服务器功能将根据请求/事件的数量进行缩放,从而产生相应的输出数量。
但是,在这种情况下,如果目标输出系统或下游系统的设计或建模未端有过多额外负载,则可能会崩溃。
它适用于峰值负载时目标输出已知的情况。如果我们知道我们的系统能够大规模处理或存储峰值负载,那么这个模型可能非常简单、快速、成本最低且方法高效。
2.设计:更适合云原生设计的异步模型
在这个模型中,我们考虑解耦我们的架构并使用中间弹性服务来存储传入的请求轰炸而不会丢失任何数据。
对于中间存储服务,我们可以考虑任何事件支持模型,如队列,例如 IBM MQ、Amazon SQS,甚至持久存储,如 Amazon S3/Dynamo DB 等,或任何流服务,如 Apache Kafka、Amazon Kinesis 等。
在此设计中,例如,我们可以轮询来自队列/数据存储的请求,然后定义一个批次,其中无服务器功能可以在每次迭代中处理定义的批次大小的请求,并以最佳方式将结果发送到目标系统。
在这个模型中,我们可以更好地控制来处理目标系统的限制(如果有的话),同时确保消息的可靠性。
三、设计模型以 AWS Lambda Dynamo DB 和 SES 无服务器选项为例进行说明
考虑一家大型航空公司服务提供商,他们可能必须处理数以百万计的季节性航班预订,这些航班预订因不同的假期而异。
如果航空公司提供商考虑上面详述的设计 1,可能的解决方案可能如下所示,其中 AWS Gateway 与多个后端(如 AWS Lambda、Dynamo DB、SES 和 S3)通信。
1.设计示例1
在这里,我们使用 AWS API Gateway 将消息路由到并发的 Lambda 函数,然后将结果输出到 Amazon DynamoDB,这是一个 NoSQL 数据库,用于在此处存储数据并可以根据扩展的负载进行扩展,Amazon SES,成本-有效、灵活和可扩展的电子邮件服务,使航空公司服务提供商能够根据需要向用户发送电子邮件通知,Amazon S3 用于托管静态网站内容,如 HTML、媒体文件、CSS、JavaScript 作为前端在航空公司客户端的浏览器中。
三个目标系统——Dynamo DB、SES 和 S3 本身是具有良好扩展能力的产品;因此,该设计非常适合考虑 CloudWatch 警报设置,以触发另一组 Lambda 函数,以便在警报发出任何警报时根据需要向用户发送通知消息。
我们可以利用 CloudFront 在全球范围内安全地分发静态内容,并提供更好的性能,如上所示。使用 CloudFront 缓存静态内容可为提供所需的性能和规模,从而为查看者提供快速可靠的体验。CloudFront 会随着全球分布的客户端在的用户所在的边缘获得可用的请求数据而自动扩展。Amazon CloudFront 可用于动态内容并利用缓存等功能。
另一种情况可能是零售连锁店预计只有在超级销售期间才会出现峰值负载,但当然不能依赖目标系统容量,因为这个销售日可能是黑色星期五的预期正常工作日的吞吐量可能是多方面的。
在这里,我们可以通过引入 Amazon SQS 来选择下面指定的选项,例如,可靠地存储消息,然后以非常适合其在 Dynamo DB 可扩展数据存储中的底层存储的批量大小触发 Lambda 函数。
2.设计示例2
3.Lambda 并发与吞吐量
我们可以根据吞吐量和函数执行时间对 lambda 进行高级并发估计,如下所示:
并发估计
平均函数执行时间(以秒为单位)* 平均请求/秒 = 并发估计
例如:如果请求的平均执行时间为 0.2 秒,吞吐量为 5 个请求/秒,则并发估计 = 0.2 *5 = 1
四、无服务器中的扩展限制
当所需功能的所有当前容器都已处于处理事件的中间时,Serverless 功能需要横向扩展。
它毫不费力地神奇地做到了!
例如,AWS Lambda 函数将自动扩展以支持额外的负载,而无需提前提供。更重要的是,500 个容器并行处理 500 个事件的 lambda 成本与一个容器一次串行处理一个事件的成本相同。
那么我们是说我们可以使用无服务器架构无限扩展吗?
显然不会。那样的话,云服务提供商很快就会破产!
因此,默认情况下,每个 CSP 将针对每个区域每个帐户的所有无服务器函数的并发执行数量设置这些限制。例如,对于每个 AWS 帐户,Lambda 函数的此限制当前为 1000,但我们可以通过联系 CSP 支持团队请求增加此限制。
如果我们达到CSP 设置的缩放限制,我们会在执行中看到节流错误。
需要注意的是,由于此限制是账户范围的,因此扩展 BIG 的一个无服务器函数可能会影响同一账户中所有其他函数的性能。因此,建议将预期在不同账户中扩展的不同潜在服务分开,以避免这些节流问题。
1.并发控制
避免由于上述扩展限制而导致的节流错误的另一种选择是在 CSP 级别为每个函数配置并发控制。
所以在 AWS Lambda 的情况下,我们可以配置如下:
2.预留并发
我们可以为每个函数设置 Reserved Concurrency,这样其他函数就无法使用它的限制,并在尝试扩展时对该函数造成限制问题。这通常可以免费配置。
3.预置并发
借助预配置并发,我们可以请求 CSP 提供一些预配置环境以立即运行并响应预期的峰值负载。借助预配置并发,CSP 将负责为提供环境,而不会出现任何冷启动延迟。然而,这是一个收费选项。
4.其他压力点
除了节流错误之外,我们可能会在大规模执行期间看到如下其他压力点:
- 数据库负载会影响查询性能和 Lambda 执行时间。
- lambda 执行时间越长,成本越高,它还会导致 API 网关超时(~29 秒)。
- 较长的 lambda 执行时间也会导致 Lambda 函数超时(约 15 分钟)。
- Lambda 突发节流会导致 API 网关错误。
5.优化
如果遇到上面列出的压力点,我们可以采用以下可能的优化解决方案:
(1)Lambda 函数 -> AWS Step Functions 工作流
(2)更丰富的工作流程如下:
(3)API 网关限制选项
(4)将 API 从 Synch 转换为 Asynch,并使用 Polling、Webhooks、Websockets等模式
(5)考虑更改数据库类型,例如 Amazon Aurora Serverless 数据 API 或使用 Dynamo DB
(6)汇集和共享数据库连接
五、无服务器扩展模型
无服务器功能(例如 Lambda 默认情况下)遵循水平扩展模型,通过实例化新容器来处理额外负载。
同时,我们也可以将无服务器功能配置为垂直扩展。例如,AWS 中的 Lambda 函数可以手动配置为从 128 MB 扩展到 10 GB RAM(当前),并且性能按垂直比例扩展。
原文链接:
https://dzone.com/articles/serverless-at-scale
译者介绍
蔡柱梁,51CTO社区编辑,从事Java后端开发8年,做过传统项目广电BOSS系统,后投身互联网电商,负责过订单,TMS,中间件等。