AWS lambda和Java并发

时间:2016-06-24 15:13:42

标签: java multithreading amazon-web-services concurrency aws-lambda

众所周知,AWS lambda 可以重用早期创建的处理程序对象,它确实这样做了(参见FAQ):

  

问:AWS Lambda会重用函数实例吗?

     

为了提高性能,AWS Lambda可能会选择保留一个实例   您的函数并重用它来提供后续请求,而不是   创建一个新副本。您的代码不应该假设这将永远   发生。

问题在于Java并发性。如果我有一个处理程序的类,请说:

public class MyHandler {
    private Foo foo;
    public void handler(Map<String,String> request, Context context) {
       ...
    }
}

那么,在这里访问和使用对象变量foo是否是线程安全的?

换句话说:AWS lambda可以同时为不同的调用使用相同的对象吗?

编辑我的功能是在基于事件的源上处理的,特别是它由API网关方法调用。

EDIT-2 当您想要将某种连接池实现到外部资源时,这类问题会上升,因此我希望将与外部资源的连接保持为对象变量。它实际上可以正常工作,但我害怕并发问题。

EDIT-3 更具体地说,我想知道: AWS lambda处理程序的实例是否可以共享公共堆(内存)?我必须指定这个额外的细节,以防止回答列出有关java线程安全对象的明显和常见的事情。

3 个答案:

答案 0 :(得分:59)

  

可能AWS lambda同时使用同一个对象进行不同的调用吗?

     

AWS lambda处理程序的实例是否可以共享公共堆(内存)?

强烈的,明确的NO。 AWS Lambda处理程序的实例甚至无法共享文件(/tmp)。

AWS Lambda容器可以重用于Lambda函数的两个或多个并发存在的调用,因为这会破坏隔离要求:

Q: How does AWS Lambda isolate my code?

  

每个AWS Lambda函数在其自己的隔离环境中运行,具有自己的资源和文件系统视图。

&#34; AWS Lambda如何运行我的代码? how lambda functions work州官方说明中的容器模型&#34;

  

执行Lambda函数后,AWS Lambda会维护   容器有一段时间以期待另一个Lambda函数   调用。实际上,服务冻结后的容器   如果AWS,Lambda函数完成并解冻容器以供重用   Lambda选择在Lambda函数时重用容器   再次调用。这种容器重用方法具有以下特征   影响:

     
      
  • Lambda函数代码中的任何声明都会保持初始化状态,   在再次调用函数时提供额外的优化。   例如,如果您的Lambda函数建立了数据库   连接,而不是重新建立连接,原始   连接用于后续调用。您可以添加逻辑   您的代码在创建连接之前检查连接是否已存在。

  •   
  • 每个容器在/ tmp目录中提供一些磁盘空间。该   提供时,目录内容在容器冻结时保留   瞬态缓存,可用于多次调用。你可以加   额外的代码,用于检查缓存是否包含您存储的数据。

  •   
  • Lambda函数启动的后台进程或回调   如果AWS Lambda在函数结束时未完成   选择重用容器。你应该确定任何背景   代码中的进程或回调(如果是Node.js)已完成   在代码退出之前。

  •   

正如您所看到的,在尝试利用容器重用时,Lambda函数的多个并发调用之间绝对没有关于竞争条件的警告。唯一的注意事项是&#34;不要依赖它!&#34;。

答案 1 :(得分:0)

利用执行上下文重用绝对是与AWS Lambda一起使用时的一种做法(请参见AWS Lambda Best Practices)。但这不适用于并发执行,因为对于并发执行,将创建新的容器并因此创建新的上下文。简而言之,对于并发执行,如果一个处理程序更改了另一个处理程序的值,则不会获得新的值。

答案 2 :(得分:0)

据我所知,没有与 Lambda 相关的并发问题。只有一个调用“拥有”容器。第二次调用将获得另一个容器(或者可能必须等到第一个容器空闲)。

但我没有找到任何保证 Java 内存可见性 问题不会发生。在这种情况下,第一次调用所做的更改可能对第二次调用保持不可见。或者第一次调用的变化会在第二次调用完成后写入 RAM。

在大多数情况下,可见性问题的处理方式与并发问题的处理方式相同。因此,我建议开发 Lambda 函数线程安全(或同步)。至少只要 AWS 不向我们保证,他们会在每次调用后做一些事情来将 CPU 状态刷新到内存中。