I have app in java on lambda AWS. When I run the test for lambda it analyzes the file from S3 and creates output. When I run first time after deploying a new image for lambda it always processes with successful status. Also when I will wait some time and run this process again it will end the successful status.
But If I run 2 or more lambdas one by one it throws exceptions for the next lambda when trying to read the file from S3 (I am always using another copy of the same file). In the java application, I am using the Spring framework.
It looks like lambda was holding states for some objects, and the next lambda that starts up has been using these objects.
What can I do with this?
CodePudding user response:
Lambda keeps the process of your Lambda function's invocation around for a certain unspecified amount of time (in the order of a few minutes).
So, after you deploy a new version (or a first version) of your Lambda function or after you waited for said unspecified amount of time and then invoke your Lambda function, the Lambda runtime will instantiate a new small container with your Lambda function as a process living inside of it.
This container and your process is then used to handle the Lambda invocation and then gets dormant (no CPU time issued to the process). However, the process itself and all of its memory is still kept around.
When, within said unspecified time interval, your Lambda function is invoked again, then the Lambda runtime will know that it still has a created instance of your Lambda function's container lying around and will then give the container CPU time to execute your Lambda handler. Once it returns, the container falls to sleep again.
We say that a Lambda function is "cold" when no container for it is currently created by the Lambda runtime. Likewise, we say that a Lambda function is "warm" whenever the interval since the last invocation was within said unspecified time such that the Lambda runtime is still keeping an instantiated container around for your Lambda function.
So, whatever you are doing in your process (JVM process, Spring application), notably storing things in memory, will still be around when your Lambda function is called while it is "warm".
When your Lambda function errors after having been called two or more times in quick succession, then that means that you are storing/caching some state in-process in memory between invocations which in your case results in an error.
To avoid this, you must, in principle, design Lambda functions such that they are stateless (nothing is shared/kept in memory between invocations). However, in order to improve runtime performance and take advantage of the fact that your Lambda function will be "warm" for a certain amount of time, you can cache certain things, such as database connections or AWS SDK client instantiations. Basically, everything you would do once after your application starts up.