减少Java Lambda的DynamoDB延迟

And*_*ose 6 java performance amazon-dynamodb aws-lambda

如何减少Lambda和DynamoDB之间当前出现的延迟?

这是Java lambda,使用AWS提供的SDK需要4秒钟来执行2个DynamoDB操作。我听说这些通常会在20毫秒内完成,但对我来说要高出3个数量级。这些较长的操作是(a)创建DynamoDB对象,以及(b)在完全空的表上执行表扫描(下面的代码)。

我应该如何减少延迟?

我尝试过的事情

  • Lambda和DynamoDB都位于同一区域(eu-west-1)。
  • 该表有5个RCU和WCU。增加这些没有帮助。
  • lambda使用的最大内存为92MB。如果我分配最小的128MB,则在15秒后超时。将内存增加到512MB可实现每次通话4s的时间,再将其增加到1GB可将每次通话2s的时间。但是,这对于琐碎的lambda来说是荒唐的内存,并且仍然给我留下了200倍的预期延迟。
  • 表指标显示表扫描时间在12毫秒至15毫秒之间。这就是我所期望的。即使建立网络连接的开销很大,我仍然期望只有几十毫秒,而不是几秒钟。
  • 我正在使用AWS控制台中的test函数触发lambda。我还尝试了通过API网关(最终将要完成的操作)进行触发以达到相同的结果。
  • 我尝试过多次连续调用lambda(以减少我遭受安装成本的可能性)。它没有帮助。
  • 日志记录显示lambda的所有其他部分运行非常快(毫秒)。

代码段

创建DynamoDB对象

log("Creating AmazonDynamoDB");
AmazonDynamoDB db = AmazonDynamoDBClientBuilder                        
  .standard()
  .withRegion(Regions.EU_WEST_1)
  .build();

log("Creating DynamoDBMapper");
DynamoDBMapper mapper = new DynamoDBMapper(db);
Run Code Online (Sandbox Code Playgroud)

执行扫描

log("Scanning table");
List<MyItem> items = dbMapper.scan(MyTable.class, new DynamoDBScanExpression());
for (MyItem item : items) {
        // Irrelevant - there aren't any
}
log("Table scan complete");
Run Code Online (Sandbox Code Playgroud)

样本日志

这是运行中的日志。

20:07:41 START RequestId: 9d436db7-5d32-11e8-8555-8564d2094ccc Version: $LATEST
20:07:41 Received request: APIGatewayRequest(path=/data/foo, httpMethod=POST, body=)
20:07:41 Creating AmazonDynamoDB
20:07:45 Creating DynamoDBMapper
20:07:45 Creating DataHandler
20:07:45 Handling request
20:07:45 Scanning table
20:07:49 Table scan complete
20:07:49 Request handled - response object: []
20:07:49 APIGatewayResponse(isBase64Encoded=false, statusCode=200, body=[], headers={})
20:07:49 END RequestId: 9d436db7-5d32-11e8-8555-8564d2094ccc
20:07:49 REPORT RequestId: 9d436db7-5d32-11e8-8555-8564d2094ccc Duration: 8256.47 ms Billed Duration: 8300 ms Memory Size: 512 MB Max Memory Used: 85 MB
Run Code Online (Sandbox Code Playgroud)

And*_*ose 5

根据这个帖子从该AWS论坛的AWS员工,在施工AmazonDynamoDB对象是昂贵的。将构造(返回)移动到静态初始值设定项中并结合一点额外的内存(=CPU)分配基本上可以解决问题。

日志中的数据仍然显示,上面确定的 2 个缓慢步骤中的每一个都需要大约一半的时间。因此,推测AmazonDynamoDB对象的构建和首次使用都很慢。

显然,这对第一个请求没有帮助,它仍然需要与问题相同的时间。但是,一旦 lambda 被加热,后续请求需要大约 15毫秒(远低于 100 毫秒的最低计费阈值)。解决第一个请求问题很容易理解- 例如,通过使用 CloudWatch Events 来安排对 lambda 的定期调用以使其保持温暖。

2020年编辑:也可以使用Provisioned Currency来处理冷启动问题。