繁体   English   中英

如何在aws lambda java中仅从s3下载s3文件一次

[英]how to download s3 file from s3 only once in aws lambda java

我正在创建一个 aws lambda 函数,它下载一个 s3 文件并根据它每次收到的事件处理它。 但是我不想每次都从 s3 下载 s3 文件。 谁能建议我如何只下载一次 s3 文件并处理传入的事件而不必每次都下载 s3 文件?

目前,即使我将代码从 s3 下载到 lambdafunctionhandler 类的构造函数中,它也每次都会下载

如果您做任何代码参考或示例,请使用java。 提前致谢

如果您并行运行多个 lamdbas,则不会重用上下文。 所以你需要下载所有 lambdas 中的文件。 使用 /tmp/ 存储文件。 它的限制为 512MB。

但是,如果您一个接一个地运行 lamdba,则上下文可能会被重用,因此该文件将存在。 记住冷启动。

摘自AWS Lamdba DOC

在执行 Lambda 函数后,AWS Lambda 会在一段时间内维护执行上下文,以期待另一个 Lambda 函数调用。 实际上,如果 AWS Lambda 在再次调用 Lambda 函数时选择重用上下文,则该服务会在 Lambda 函数完成后冻结执行上下文,并解冻上下文以供重用。 这种执行上下文重用方法具有以下含义:

  • 在函数的处理程序方法之外声明的对象保持初始化状态,在函数执行时提供额外的优化
    再次调用。 例如,如果您的 Lambda 函数建立了一个
    数据库连接,而不是重新建立连接,
    原始连接用于后续调用。 我们建议
    在代码中添加逻辑以检查之前是否存在连接
    创造一个。 每个执行上下文在 /tmp 目录中提供 512 MB 的额外磁盘空间。 当执行上下文被冻结时,目录内容仍然存在,提供可用于多次调用的临时缓存。 您可以添加额外的代码来检查缓存是否包含您存储的数据。 有关部署限制的信息,请参阅 AWS Lambda 限制。 如果 AWS Lambda 选择重用执行上下文,则由您的 Lambda 函数启动但在函数结束时未完成的后台进程或回调将恢复。 在代码退出之前,您应该确保代码中的任何后台进程或回调都已完成。

从 S3 下载对象的示例代码:

AmazonS3 s3client = AmazonS3ClientBuilder
                  .standard()
                  .withRegion(Regions.EU_WEST_1)
                  .build();

        //S3 download file

        GetObjectRequest getObjectRequest = new GetObjectRequest(System.getenv("bucket"), "key");
        s3client.getObject(getObjectRequest, new File("/tmp/example.png")); 

编辑 1:对于需要在不同调用之间维护状态的应用程序,一般不建议使用 Lambdas 和无服务器。

您的意思是,您只想在 lambda 热的时候下载文件一次?基于 VPC 的 lambda 函数会保持热 15 分钟。

如果是,如果您在处理程序函数之外调用下载函数,则代码只会在 lambda 热时执行一次。

在函数的处理程序方法之外声明的对象保持初始化状态,从而在再次调用函数时提供额外的优化。 例如,如果您的 Lambda 函数建立了数据库连接,而不是重新建立连接,而是在后续调用中使用原始连接。 我们建议在您的代码中添加逻辑以在创建连接之前检查连接是否存在。

https://docs.aws.amazon.com/lambda/latest/dg/running-lambda-code.html

我认为您可以在 Java 上使用静态块,该代码块将仅执行一次,如下所示

// code from https://www.geeksforgeeks.org/g-fact-79/
class Test { 
    static int i; 
    int j; 
    static { 
        i = 10; 
        // File download logic here , will be called only once
        System.out.println("static block called "); 
    } 
    Test(){ 
        System.out.println("Constructor called"); 
    } 
} 

class Main { 
    public static void main(String args[]) { 

       // Although we have two objects, static block is executed only once. 
       Test t1 = new Test(); 
       Test t2 = new Test(); 
    } 
} 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM