如何保持所需数量的AWS Lambda函数容器温暖 [英] How to keep desired amount of AWS Lambda function containers warm

查看:160
本文介绍了如何保持所需数量的AWS Lambda函数容器温暖的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,有一个在AWS API Gateway和AWS Lambda上实现的REST API。由于AWS Lambda函数在我们对其进行调用时是无服务器且无状态的,因此AWS使用Lambda函数的代码启动一个容器来处理我们的调用。根据 AWS文档,在完成Lambda函数执行AWS后不要停止该容器,我们可以处理该容器中的下一个调用。这种方法提高了服务的性能-仅在首次调用时AWS才花时间启动容器(冷启动Lambda函数),并且所有下一个调用都使用相同的容器(热启动),因此执行速度更快。



作为提高性能的下一步,我们创建了cron作业,该作业定期调用Lambda函数(为此我们使用Cloudwatch规则)。这种方法可以使Lambda函数保持温暖状态,从而避免停止和重新启动容器。即当真正的用户调用我们的REST API时,Lambda不会花费时间来启动新的容器。



但是我们面临的问题-这种方法只能保暖一个容器包含Lambda函数,而来自不同用户的并行调用的实际数量可能会大得多(在我们的案例中,这是数百个,有时甚至是数千个用户)。有什么方法可以为Lambda函数实现预热功能,该功能不仅可以预热单个容器,而且可以预热一些容器?



我知道这种方法会影响成本Lambda函数的使用,也许最好使用旧的旧应用程序服务器会更好,但是我认为,比较这些方法及其成本将是下一步,目前,我仅想找到方法温暖的Lambda函数容器的期望数量。

解决方案

这可能很长,但请耐心等待,因为这可能会给您解决方法,并且可能将会使您更好地理解 Lambda的工作原理吗?



或者,您也可以跳到底部 解决方法,如果您对阅读不感兴趣。



对于不了解冷启动的人,请阅读此博客帖子以更好地理解它。简而言之:



冷启动




  • 执行函数时第一次或在更新
    函数代码或资源配置之后,将为
    旋转一个容器以执行此功能。所有代码和库都将
    加载到容器中以便能够执行。该代码将从初始化代码开始运行
    。初始化
    代码是在处理程序外部编写的代码。此代码仅在首次创建容器时运行
    。最后,执行Lambda
    处理程序。 此设置过程被称为冷启动

  • 为了提高性能,Lambda能够重复使用创建的$ b容器$ b以前的调用。这样可以避免初始化新的
    容器和加载代码。仅处理程序代码将执行
    。但是,您不能依赖先前
    调用中的容器来重用。如果您没有更改代码,但是
    花费了很多时间,Lambda可能会重用以前的容器。

  • 如果您更改了代码,资源配置或一段时间自上次调用以来已传递了
    ,则将初始化
    的新容器,您将体验到冷启动。



<现在,请考虑以下情况以更好地理解:




  • 在示例中,请考虑首次调用Lambda函数。 Lambda将创建一个容器,将代码加载到该容器中并运行初始化代码。然后将执行函数处理程序。此调用将经历冷启动。如评论中所述,该功能需要15秒钟才能完成。一分钟后,该函数再次被调用。 Lambda很可能会重用上一次调用中的容器。此调用不会冷启动。

  • 现在考虑第二种情况,其中第二次调用在启动后5秒钟执行第一次调用。由于先前的函数需要15秒钟才能完成且尚未完成执行,因此新调用将必须创建一个新容器以使该函数执行。因此此调用将遇到冷启动。



现在要提出问题的第一部分您已解决的问题:



关于防止冷启动,这是一种可能,但是,不能保证,通常的解决方法只能保暖一个容器Lambda函数。为此,您将使用计划事件(cron表达式)运行CloudWatch事件,该事件将每隔几分钟调用一次Lambda函数以使其保持温暖。






解决方法:



对于您的用例,您的Lambda函数将被频繁调用并发率非常高。为了避免尽可能多的冷启动,您将需要保暖尽可能多的容器,以达到最高的并发性。为此,您需要延迟调用这些函数,以允许该函数的并发性构建并达到所需的并发执行量。这将迫使Lambda加速您所需的容器数量。因此,这会增加成本,并且不能保证避免冷启动。



话虽这么说,这里是您如何做的一种分解一次使多个容器保持功能的温暖:




  • 您应该具有 CloudWatch Events规则是按时间表触发的。该时间表可以是固定汇率,也可以是cron表达式。例如,您可以将此规则设置为每5分钟触发一次。您将然后指定一个Lambda函数(Controller函数)作为此规则的目标。


  • 您的 Controller Lambda函数然后调用任意数量的并发运行容器的Lambda函数(您要保持温暖的函数)。




这里有几件事要考虑:


  1. 您将必须建立并发性,因为如果第一个调用
    在另一个调用开始之前完成,则此调用
    可能会重用先前的调用容器,而不创建新的
    。为此,如果控制器
    函数调用该函数,则需要在
    Lambda函数上添加某种延迟。 这可以通过使用这些调用将特定的有效负载传递给
    函数来完成。您
    要保持温暖的lambda函数将检查此有效载荷是否存在。如果确实有
    ,则该函数将等待(以构建并发
    调用),如果没有,则该函数可以按预期的
    执行。


  2. 如果您反复调用Invoke Lambda API,还需要确保不会受到限制。应该编写
    Lambda
    函数来处理这种限制,如果发生
    并考虑在API调用之间添加延迟以避免限制。


最后,此解决方案可以减少冷启动,但会增加成本,并且不能保证会发生冷启动,因为使用Lambda时不可避免。您的应用程序需要更快的响应时间,而不是Lambda冷启动时会发生什么情况,建议您将服务器安装在EC2实例上。


On my project there is REST API which implemented on AWS API Gateway and AWS Lambda. As AWS Lambda functions are serverless and stateless while we make a call to it, AWS starts a container with code of the Lambda function which process our call. According AWS documentation after finishing of lambda function execution AWS don't stop the container and we are able to process next call in that container. Such approach improves performance of the service - only in time of first call AWS spend time to start container (cold start of Lambda function) and all next calls are executed faster because their use the same container (warm starts).

As a next step for improving the performance we created cron job which calls periodically our Lambda function (we use Cloudwatch rules for that). Such approach allow to keep Lambda function "warm" allowing to avoid stopping and restarting of containers. I.e. when the real user will call our REST API, Lambda will not spent time to start a new container.

But we faced with the issue - such approach allow to keep warm only one container of Lambda function while the actual number of parallel calls from different users can be much larger (in our case that's hundreds and sometimes even thousands of users). Is there any way to implement warm up functionality for Lambda function which could warm not only single container, but some desired number of them?

I understand that such approach can affect cost of Lambda function's using and possibly, at all it will be better to use good old application server, but comparison of these approaches and their costs will be the next steps, I think, and in current moment I would like just to find the way to warm desired count of Lambda function containers.

解决方案

This can be long but bear with me as this would probably give you workaround and may be would make you understand better How Lambda Works ?

Alternatively You can Skip to Bottom "The Workaround" if you are not interested in reading.

For folks who are not aware about cold starts please read this blog post to better understand it. To describe this in short:

Cold Starts

  • When a function is executed for the first time or after having the functions code or resource configuration updated, a container will be spun up to execute this function. All the code and libraries will be loaded into the container for it to be able to execute. The code will then run, starting with the initialisation code. The initialisation code is the code written outside the handler. This code is only run when the container is created for the first time. Finally, the Lambda handler is executed. This set-up process is what is considered a cold start.
  • For performance, Lambda has the ability to re-use containers created by previous invocations. This will avoid the initialisation of a new container and loading of code. Only the handler code will be executed. However, you cannot depend on a container from a previous invocation to be reused. if you haven’t changed the code and not too much time has gone by, Lambda may reuse the previous container.
  • If you change the code, resource configuration or some time has passed since the previous invocation, a new container will be initialized and you will experience a cold start.

Now Consider these scenarios for better understanding:

  • Consider the Lambda function, in the example, is invoked for the first time. Lambda will create a container, load the code into the container and run the initialisation code. The function handler will then be executed. This invocation will have experienced a cold start. As mentioned in the comments, the function takes 15 seconds to complete. After a minute, the function is invoked again. Lambda will most likely re-use the container from the previous invocation. This invocation will not experience a cold start.
  • Now consider the second scenario, where the second invocation is executed 5 seconds after the first invocation. Since the previous function takes 15 seconds to complete and has not finished executing, the new invocation will have to create a new container for this function to execute. Therefore this invocation will experience a cold start.

Now to Come up First Part of Problem that you have solved :

Regarding preventing cold starts, this is a possibility, however, it is not guaranteed, the common workaround will only keep warm one container of the Lambda function. To do, you would run a CloudWatch event using a schedule event (cron expression) that will invoke your Lambda function every couple of minutes to keep it warm.


The Workaround:

For your use-case, your Lambda function will be invoked very frequently with a very high concurrency rate. To avoid as many cold starts as possible, you will need to keep warm as many containers as you expect your highest concurrency to reach. To do this you will need to invoke the functions with a delay to allow the concurrency of this function to build and reach the desired amount of concurrent executions. This will force Lambda to spin up the number of containers you desire. This, as a result, can bring up costs and will not guarantee to avoid cold starts.

That being said, here is a break down on how you can keep multiple containers for your function warm at one time:

  • You should have a CloudWatch Events Rule that is triggered on a schedule. This schedule can be a fixed rate or a cron expression. for example, You can set this rule to trigger every 5 minutes. You will then specify a Lambda function (Controller function) as the target of this rule.

  • Your Controller Lambda function will then invoke the Lambda function (Function that you want to be kept warm) for as many concurrent running containers as you desire.

There are a few things to consider here:

  1. You will have to build concurrency because if the first invocation is finished before another invocation starts then this invocation may reuse the previous invocations container and not create a new one. To do this you will need to add some sort of delay on the Lambda function if the function is invoked by the controller function. This can be done by passing in a specific payload to the function with these invocations. The lambda function that you want to be kept warm will then check if this payload exists. If it does then the function will wait (to build concurrent invocations), if it does not then the function can execute as expected.

  2. You will also need to ensure you are not getting throttled on the Invoke Lambda API call if you are calling it repeatedly. Your Lambda function should be written to handle this throttling if it occurs and consider adding a delay between API calls to avoid throttling.

At the End this solution can reduce cold starts but it will increase costs and will not guarantee that cold starts will occur as they are inevitable when working with Lambda.If your application needs faster response times then what occurs with a Lambda cold start, I would recommend looking into having your server on a EC2 instance.

这篇关于如何保持所需数量的AWS Lambda函数容器温暖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆