我目前正在使用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
,可能是因为没有覆盖某些默认值,导致性能不佳?如何加快客户端初始化?
答案 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的插件,我相信还有更多这样的插件。