AWS lambda 和 Java 并发
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38016683/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
AWS lambda and Java concurrency
提问by Andremoniy
It is known that AWS lambda mayreuse early created objects of handlers, and it really does it (see FAQ):
众所周知,AWS lambda可能会重用早期创建的处理程序对象,并且确实做到了(请参阅常见问题解答):
Q: Will AWS Lambda reuse function instances?
To improve performance, AWS Lambda may choose to retain an instance of your function and reuse it to serve a subsequent request, rather than creating a new copy. Your code should not assume that this will always happen.
问:AWS Lambda 会重用函数实例吗?
为了提高性能,AWS Lambda 可能会选择保留您函数的一个实例并重用它来为后续请求提供服务,而不是创建一个新副本。您的代码不应假设这将始终发生。
The question is regarding Java
concurrency. If I have a class for a handler, say:
问题是关于Java
并发。如果我有一个处理程序的类,请说:
public class MyHandler {
private Foo foo;
public void handler(Map<String,String> request, Context context) {
...
}
}
so, will it be thread-safe to access and work with the object variable foo
here or not?
那么,foo
在这里访问和使用对象变量是否是线程安全的?
In other words: may AWS lambda use the same object concurrently for different calls?
换句话说:AWS lambda 是否可以同时为不同的调用使用相同的对象?
EDITMy function is processed on an event based source, particularly it is invoked by an API Gateway method.
编辑我的函数是在基于事件的源上处理的,特别是它由 API 网关方法调用。
EDIT-2Such kind of question rises when you want to implement some kind of connection pool to external resources, so I want to keep the connection to the external resource as an object variable. It actually works as desired, but I'm afraid of concurrency problems.
EDIT-2当您想实现某种与外部资源的连接池时,会出现此类问题,因此我想将与外部资源的连接保持为对象变量。它实际上按预期工作,但我担心并发问题。
EDIT-3More specifically I'm wondering: can instances of handlers of AWS lambda share common heap (memory) or not? I have to specify this additional detail in order to prevent answers with listing of obvious and common-known things about java thread-safe objects.
EDIT-3更具体地说,我想知道:AWS lambda 的处理程序实例是否可以共享公共堆(内存)?我必须指定这个额外的细节,以防止列出关于 Java 线程安全对象的明显和公知的事情的答案。
回答by Leon
May AWS lambda use same object concurrently for different calls?
Can instances of handlers of AWS lambda share common heap (memory) or not?
AWS lambda 可以为不同的调用同时使用相同的对象吗?
AWS lambda 的处理程序实例是否可以共享公共堆(内存)?
A strong, definite NO. Instances of handlers of AWS Lambda cannot even share files (in /tmp
).
一个强有力的,明确的否。AWS Lambda 的处理程序实例甚至不能共享文件(在 中/tmp
)。
An AWS Lambda container may notbe reused for two or more concurrently existing invocations of a Lambda function, since that would break the isolation requirement:
一个 AWS Lambda 容器不能被重复用于两个或多个同时存在的 Lambda 函数调用,因为这会破坏隔离要求:
Q: How does AWS Lambda isolate my code?
Each AWS Lambda function runs in its own isolated environment, with its own resources and file system view.
每个 AWS Lambda 函数都在其自己的隔离环境中运行,具有自己的资源和文件系统视图。
The section "How Does AWS Lambda Run My Code? The Container Model"in the official description of how lambda functions workstates:
该段“如何AWS LAMBDA我的代码运行的容器模型?”在官方说明lambda函数是如何工作的状态:
After a Lambda function is executed, AWS Lambda maintains the container for some time in anticipation of another Lambda function invocation. In effect, the service freezes the container after a Lambda function completes, and thaws the container for reuse, if AWS Lambda chooses to reuse the container when the Lambda function is invoked again. This container reuse approach has the following implications:
Any declarations in your Lambda function code remains initialized, providing additional optimization when the function is invoked again. For example, if your Lambda function establishes a database connection, instead of reestablishing the connection, the original connection is used in subsequent invocations. You can add logic in your code to check if a connection already exists before creating one.
Each container provides some disk space in the /tmp directory. The directory content remains when the container is frozen, providing transient cache that can be used for multiple invocations. You can add extra code to check if the cache has the data that you stored.
Background processes or callbacks initiated by your Lambda function that did not complete when the function ended resume if AWS Lambda chooses to reuse the container. You should make sure any background processes or callbacks (in case of Node.js) in your code are complete before the code exits.
执行 Lambda 函数后,AWS Lambda 会维护容器一段时间,以期待另一个 Lambda 函数调用。实际上,如果 AWS Lambda 在再次调用 Lambda 函数时选择重用容器,则该服务会在 Lambda 函数完成后冻结容器,并解冻容器以供重用。这种容器重用方法具有以下含义:
Lambda 函数代码中的任何声明都保持初始化状态,从而在再次调用该函数时提供额外的优化。 例如,如果您的 Lambda 函数建立了数据库连接,而不是重新建立连接,而是在后续调用中使用原始连接。您可以在代码中添加逻辑以在创建连接之前检查连接是否已存在。
每个容器在 /tmp 目录中提供一些磁盘空间。当容器被冻结时,目录内容仍然存在,提供可用于多次调用的临时缓存。您可以添加额外的代码来检查缓存是否包含您存储的数据。
如果 AWS Lambda 选择重用容器,则由您的 Lambda 函数启动但在函数结束时未完成的后台进程或回调会恢复。在代码退出之前,您应该确保代码中的任何后台进程或回调(在 Node.js 的情况下)都已完成。
As you can see, there is absolutely no warning about race conditions between multiple concurrent invocations of a Lambda function when trying to take advantage of container reuse. The only note is "don't rely on it!".
正如您所看到的,在尝试利用容器重用时,绝对没有关于 Lambda 函数的多个并发调用之间的竞争条件的警告。唯一需要注意的是“不要依赖它!”。
回答by Farhan Haider
Taking advantage of the execution context reuse is definitely a practice when working with AWS Lambda (See AWS Lambda Best Practices). But this does not apply to concurrent executions as for concurrent execution a new container is created and thus new context. In short, for concurrent executions if one handler changes the value other won't get the new value.
在使用 AWS Lambda 时,利用执行上下文重用绝对是一种实践(请参阅AWS Lambda 最佳实践)。但这不适用于并发执行,因为对于并发执行,会创建新容器并因此创建新上下文。简而言之,对于并发执行,如果一个处理程序更改了值,另一个处理程序将不会获得新值。