性能降低了Java Lambda的DynamoDB延迟
如何减少Lambda和;发电机
这是一个Java lambda,使用AWS提供的SDK执行2个DynamoDB操作需要4个小时。我听说这些通常在<;20毫秒,但对我来说要高出3个数量级。这些长操作包括(a)创建DynamoDB对象和(b)在完全空的表上执行表扫描(代码如下)
我应该做些什么来减少延迟
我尝试过的东西
- lambda和DynamoDB均位于同一区域(eu-west-1)李>
- 表中有5个RCU和;WCU。增加这些并没有帮助李>
- lambda使用的最大内存为92MB。如果我分配最小128MB,那么它将在15秒后超时。将内存增加到512MB可实现每次呼叫4秒的计时,再次将内存增加到1GB可将每次呼叫的计时减少到2秒。然而,对于一个微不足道的lambda来说,这是一个荒谬的记忆量,仍然留给我>;预期延迟的200倍李>
- 表度量显示表扫描时间在12到15毫秒之间。这就是我所期待的。即使有建立网络连接的开销,我仍然期望只有10毫秒,而不是几秒钟李>
- 我正在使用AWS控制台中的测试功能触发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);
执行扫描
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");
样本日志
这是一次跑步的记录
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
# 1 楼答案
(不是答案,但我希望它能帮助其他人) 我已经在这里发布了更新,除此之外,我还必须在dynamoDb上进行一个“虚拟”查询操作(打开与它的连接),以防帮助其他人,我的代码如下:
打开dynamoDb连接的后续操作将以毫秒为单位
# 2 楼答案
根据AWS论坛上一位AWS员工的this post,构建
AmazonDynamoDB
对象的成本很高。将构造(返回)移到静态初始值设定项中,再加上一点额外的内存(=CPU)分配,基本上可以解决问题日志中的数据仍然显示,上述两个缓慢的步骤中的每一个都需要大约一半的时间。因此,推测
AmazonDynamoDB
对象的构造和首次使用都很慢显然,这对第一个请求没有帮助,它仍然需要与问题中相同的时间。然而,一旦lambda被加热,后续请求需要约15毫秒(远低于100毫秒的最小计费阈值)。解决第一个请求问题是well understood——例如,通过使用CloudWatch事件来安排对lambda的定期调用以保持其温暖
2020年编辑:您还可以使用Provisioned Currency来处理冷启动问题
# 3 楼答案
所有的aws客户端生成器。build()函数在lambda中需要一段时间,并且依赖于专用于该函数的内存。但是,如果容器已经初始化,并且您正在调用ClientBuilder。build()第二次或后续请求时,它以毫秒而不是秒为单位