简体   繁体   English

AWS Lambda中的S3客户端初始化速度缓慢

[英]Slow S3 client initialisation in AWS Lambda

I'm currently working on an AWS Lambda function written in Java. 我目前正在研究用Java编写的AWS Lambda函数。 It needs to fetch objects from S3 and I have therefore set up an IAM role and am building an S3 client in the Lambda's handler: 它需要从S3获取对象,因此我设置了一个IAM角色,并在Lambda的处理程序中构建一个S3客户端:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import com.amazonaws.services.s3.AmazonS3;
import com.amazonaws.services.s3.AmazonS3ClientBuilder;

public class Example implements RequestHandler<Void, Void> {

    @Override
    public Void handleRequest(Void nothing, Context ctx) {
        long start = System.currentTimeMillis();
        AmazonS3 amazonS3 = AmazonS3ClientBuilder.defaultClient();
        ctx.getLogger().log("Creating S3 client took " + (System.currentTimeMillis() - start) + "ms");
        ...
        return null;
    }
}

Nevertheless, using the AmazonS3ClientBuilder is very slow, the log statement prints out the following timings when allocating 192MB to the function: 尽管如此,使用AmazonS3ClientBuilder非常慢,当为函数分配192MB时,log语句会打印出以下时序:

Creating S3 client took 13541ms
Creating S3 client took 16482ms
Creating S3 client took 13617ms
Creating S3 client took 16380ms

Even when bumping memory right up to 3008MB to get maximum processing power (as AWS allocates CPU power proportional to the memory for Lambdas), it still takes between 1 and 2 seconds to get the client: 即使将内存高达3008MB以获得最大处理能力(因为AWS分配的CPU功率与Lambdas的内存成比例),获取客户端仍需要1到2秒:

Creating S3 client took 1413ms
Creating S3 client took 1170ms
Creating S3 client took 1528ms
Creating S3 client took 1394ms

These timings were recorded in cold start scenarios and I am caching the AmazonS3 instance for subsequent requests, but it seems pretty extreme that just building an S3 client can take over 16 seconds on a non warm Lambda. 这些时间是在冷启动场景中记录的,我正在为后续请求缓存AmazonS3实例,但是看起来非常极端,只需构建一个S3客户端就可以在非温暖的Lambda上花费超过16秒。

Am I misusing the AmazonS3ClientBuilder , possibly by not overriding some default values, leading to poor performance? 我是否滥用AmazonS3ClientBuilder ,可能是因为没有覆盖某些默认值,导致性能不佳? How can client initialisation be sped up? 如何加快客户端初始化?

AWS clients are considered thread safe and can be safely used by multiple requests at the same time. AWS客户端被认为是线程安全的,可以同时安全地由多个请求使用。 You should be able to create the client as a member variable and reuse the same client for each request. 您应该能够将客户端创建为成员变量,并为每个请求重用相同的客户端。 This should save considerable time since the default client makes a few aws calls each time it is created to find the region and credentials. 这应该节省大量时间,因为默认客户端每次创建一些aws调用以查找区域和凭据。

The AWS SDK for Java 2.0 was released in November. AWS SDK for Java 2.0于11月发布。 It's basically a rewrite of version 1.x and it seems to have improved performance quite a bit. 它基本上是1.x版本的重写,似乎有相当多的性能提升。 Migrating the code from the question to use the new SDK would give us something similar to the following: 从问题中迁移代码以使用新SDK将为我们提供类似于以下内容的内容:

import com.amazonaws.services.lambda.runtime.Context;
import com.amazonaws.services.lambda.runtime.RequestHandler;
import software.amazon.awssdk.services.s3.S3Client;

public class Example implements RequestHandler<Void, Void> {

    @Override
    public Void handleRequest(Void nothing, Context ctx) {
        long start = System.currentTimeMillis();
        S3Client s3Client= S3Client.create();
        ctx.getLogger().log("Creating S3 client took " + (System.currentTimeMillis() - start) + "ms");
        ...
        return null;
    }
}

When allocating 192MB to the function: 为功能分配192MB时:

Creating S3 client took 9380ms
Creating S3 client took 9719ms
Creating S3 client took 10098ms
Creating S3 client took 9519ms

When allocating 3008MB to the function: 为功能分配3008MB时:

Creating S3 client took 884ms
Creating S3 client took 873ms
Creating S3 client took 886ms
Creating S3 client took 877ms

Based on these rough figures, S3 client creation time in cold start scenarios has decreased by over a third when using version 2 of the SDK. 基于这些粗略的数字,在使用SDK的第2版时,冷启动场景中的S3客户端创建时间减少了三分之一以上。

When running a serverless function, it will stay active (aka, hot) as long as you're running it. 运行无服务器功能时,只要您正在运行它,它就会保持活动状态(也称为热)。 Your container stays alive, ready and waiting for execution. 您的容器保持活动,准备就绪并等待执行。

After a period of inactivity, your cloud provider will drop the container, and your function will become inactive, (aka, cold). 经过一段时间的不活动后,您的云提供商将丢弃容器,您的功能将变为非活动状态(又称冷)。

A cold start happens when you execute an inactive function. 执行非活动功能时会发生冷启动。 The delay comes from your cloud provider provisioning your selected runtime container and then running your function. 延迟来自您的云提供商配置您选择的运行时容器,然后运行您的功能。

You could fix this by keeping your functions 'warm'. 你可以通过保持你的功能“温暖”来解决这个问题。 One way to do this would be to add a cronjob that pings your function every now and then. 一种方法是添加一个cronjob,不时地ping你的功能。 There is a plugin available that does just that called serverless-plugin-warmup , and I am sure there are many more just like that. 有一个插件可用,只是称为无服务器插件 - 热身 ,我相信还有更多这样的插件

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

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