[英]Reduce DynamoDB latency from Java Lambda
這是一個 Java lambda,使用 AWS 提供的 SDK 執行 2 個 DynamoDB 操作中的每一個需要 4 秒。 我聽說這些通常在 <20 毫秒內完成,但對我來說它高 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
根據這個帖子從該AWS論壇的AWS員工,在建設AmazonDynamoDB
對象是昂貴的。 將構造(返回)移動到靜態初始值設定項中並結合一點額外的內存(=CPU)分配基本上可以解決問題。
日志中的數據仍然顯示,上面確定的 2 個緩慢步驟中的每一個都需要大約一半的時間。 因此,據推測, AmazonDynamoDB
對象的構建和首次使用都很慢。
顯然,這對第一個請求沒有幫助,它仍然需要與問題相同的時間。 但是,一旦 lambda 被加熱,后續請求需要大約 15毫秒(遠低於 100 毫秒的最低計費閾值)。 解決第一個請求問題很容易理解- 例如,通過使用 CloudWatch Events 安排對 lambda 的定期調用以使其保持溫暖。
2020年編輯:也可以使用Provisioned Currency來處理冷啟動問題。
(不是答案,但我希望它可以幫助其他人)我已經在此處發布了更新,除此之外,我還必須在 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 連接的后續操作將以毫秒為單位發生!
所有 aws ClientBuilder.build() 函數在 lambda 中都需要一段時間,並且依賴於專用於該函數的內存。 但是,如果容器已經初始化並且您第二次或在后續請求中調用 ClientBuilder.build(),則它以毫秒而不是秒為單位發生。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.