这是一个Java lambda,使用AWS提供的SDK执行2次DynamoDB操作需要4s。我听说这些通常在<20ms内完成,但对我来说它高出3个数量级。这些长操作是(a)创建DynamoDB对象和(b)在完全空表(下面的代码)上执行表扫描。
我应该怎样做才能减少延迟?
创建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
答案 0 :(得分:2)
根据AWS论坛上AWS员工的this post,构建AmazonDynamoDB
对象非常昂贵。将构造(后退)移动到静态初始化器中并结合一点额外内存(= CPU)分配基本上可以解决问题。
来自日志的数据仍然显示上面确定的2个慢速步骤中的每一个都花费大约一半的时间。因此,大概AmazonDynamoDB
对象的构造和首次使用都很慢。
显然,这对第一个请求仍然没有帮助,这个请求仍然需要与问题相同的时间。但是,一旦lambda变暖,后续请求需要~15ms (远低于最小计费阈值100ms)。解决第一个请求问题是well understood - 例如通过使用CloudWatch Events来安排对lambda的常规调用以使其保持温暖。
答案 1 :(得分:1)
(不是答案,但我希望它可以帮助其他人) 我已经在此处发布了更新,除了这些更新,我还必须对dynamoDb进行“虚拟”查询操作(以打开与之的连接),以防万一有人帮助,我的代码如下:>
class MyFunctionHandler : RequestHandler<Map<String, Any>, ApiGatewayResponse> {
//var dbClient: AmazonDynamoDB = AmazonDynamoDBClientBuilder.defaultClient()
var dbClient: AmazonDynamoDB = AmazonDynamoDBClientBuilder
.standard().withRegion("sa-east-1").build()
override fun handleRequest(input: Map<String, Any>, context: Context): ApiGatewayResponse {
LOG.info("received input: $input")
input["wakeup"]?.let {
if (it == true) {
with(EmpresaRepository(dbClient)) {
LOG.info("### Connection was not stablished at this point")
someDynamoQueryHere("dummyParameter")
LOG.info("### The Connection was opened and will keep alived for 1 minute")
}
return buildResponseForWakeUpReq(input)
}
}
val param = input["queryStringParameters"]?.toString()
...
随后将打开dynamoDb连接的操作将以毫秒为单位!
答案 2 :(得分:0)
所有aws ClientBuilder.build()函数在lambda中都需要花费一些时间,并且依赖于该函数专用的内存。但是,如果容器已经初始化,并且您是第二次或在后续请求中调用ClientBuilder.build(),则它以毫秒为单位而不是秒。