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

时间:2018-04-28 17:31:01

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

我目前正在使用Java编写的AWS Lambda函数。它需要从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;
    }
}

然而,使用AmazonS3ClientBuilder非常慢,log语句在为函数分配192MB时打印出以下时序:

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

即使将内存高达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

这些时间是在冷启动场景中记录的,我正在为后续请求缓存AmazonS3实例,但是看起来非常极端,只需构建一个S3客户端就可以在非温暖的Lambda上花费超过16秒。

我是否滥用AmazonS3ClientBuilder,可能是因为没有覆盖某些默认值,导致性能不佳?如何加快客户端初始化?

3 个答案:

答案 0 :(得分:1)

AWS客户端被认为是线程安全的,可以同时被多个请求安全地使用。您应该能够将客户端创建为成员变量,并对每个请求重用相同的客户端。这将节省大量时间,因为默认客户端每次创建该默认客户端时都会进行几次aws调用以查找区域和凭据。

答案 1 :(得分:1)

AWS SDK for Java 2.0于11月发布。基本上,这是对1.x版的重写,并且似乎已经改善了很多性能。从问题中迁移代码以使用新的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;
    }
}

为该功能分配192MB时:

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

为该功能分配3008MB时:

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

基于这些粗略的数字,使用SDK版本2时,在冷启动方案中创建S3客户端的时间减少了三分之一以上。

答案 2 :(得分:0)

运行无服务器功能时,只要您正在运行它,它就会保持活动状态(等等,很热)。您的容器保持活动状态,准备就绪并等待执行。

在一段时间不活动之后,您的云提供商将丢弃容器,您的功能将变为非活动状态(a.k.a.,cold)。

执行非活动功能时会发生冷启动。延迟来自您的云提供商配置您选择的运行时容器,然后运行您的功能。

你可以通过保持你的功能“温暖”来解决这个问题。一种方法是添加一个cronjob,不时地ping你的功能。有一个可用的插件就是那个名为serverless-plugin-warmup的插件,我相信还有更多这样的插件。