调用大量 AWS lambda 函数的最佳方式是什么?
What's the best way to invoke a large volume AWS lambda function?
我在想一个服务可能需要在短时间内调用大量的 Lambda 函数。例如一个非常繁忙的频道中的聊天机器人,每条新消息都会调用用 lambda 编写的机器人。 Lambda 似乎是一个很好的解决方案。
我用 AWS SDK 写了一个简单的测试代码:
var lambda = new AWS.Lambda({apiVersion: '2015-03-31'});
function invoke() {
var start = new Date();
var params = {
FunctionName: 'test', /* required */
InvocationType: 'RequestResponse',
LogType: 'None',
Payload: '{}',
};
lambda.invoke(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
}
else {
var duration = new Date() - start;
console.info("Execution time: %dms", duration);
}
});
}
for (var i = 0; i < n; i++) {
invoke();
}
lambda 函数 "test" 是一个非常简单的函数,它基本上什么都不做,只是 return 返回输入事件。在 lambda 控制台中,它通常需要不到 10 毫秒的时间来执行。我在自己的笔记本电脑上测试过,所以网络延迟大约是 200~300ms。我的开发计算机单次调用大约需要 600~800 毫秒。
小批量 运行 看起来不错:
$ node test.js 5
Execution time: 637ms
Execution time: 652ms
Execution time: 646ms
Execution time: 713ms
Execution time: 850ms
但是,如果我 运行 批量处理它,延迟会变得非常大,并且变得越来越大:
$ node test.js 1000
Execution time: 3569ms
Execution time: 4418ms
Execution time: 3571ms
Execution time: 4505ms
Execution time: 3661ms
Execution time: 3322ms
Execution time: 3645ms
Execution time: 3654ms
Execution time: 3651ms
Execution time: 4531ms
...
Execution time: 71851ms
Execution time: 70879ms
Execution time: 71777ms
我知道 AWS-SDK 实际上正在发出 HTTP 请求来调用 lambda,因此 AWS 会限制并发连接并且请求可能会排队并减慢它们的速度是有道理的。所以似乎不可能以这种方式调用大量的 lambda...:(
我正准备通过发送 SNS 来测试它,但是不确定这是否是一个好的解决方案,因为我希望从那些 lambda 函数中获得结果。
更新:我还将代码放在部署到同一区域的另一个 lambda 函数中,所以我认为网络延迟最小,看起来肯定更快,但似乎有同样的问题。
START RequestId: 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Version: $LATEST
2015-11-12T21:44:00.923Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #0
2015-11-12T21:44:01.003Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #1
2015-11-12T21:44:01.005Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #2
2015-11-12T21:44:01.063Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #3
2015-11-12T21:44:01.065Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #4
2015-11-12T21:44:01.122Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #5
2015-11-12T21:44:01.123Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #6
2015-11-12T21:44:01.124Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #7
2015-11-12T21:44:01.124Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #8
2015-11-12T21:44:01.182Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #9
2015-11-12T21:44:01.182Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Execution time: 753ms
END RequestId: 7bd3339d-8986-11e5-85d1-67b32d2e2f9c
REPORT RequestId: 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Duration: 873.46 ms Billed Duration: 900 ms Memory Size: 128 MB Max Memory Used: 14 MB
我的问题是,有没有办法在很短的时间内调用大量的 lambda?
如果您将 InvocationType
从 RequestResponse
切换到 Event
,那么您的函数将 运行 您的调用异步调用。
您需要异步调用 Lambda(正如@Matt Beckman 指出的那样),并且您需要增加 Lambda account limits。如果您必须维护状态或检索返回的结果,那么您需要找到另一种方法来做到这一点,例如附加到 SQS 队列或 DynamoDB table.
我在想一个服务可能需要在短时间内调用大量的 Lambda 函数。例如一个非常繁忙的频道中的聊天机器人,每条新消息都会调用用 lambda 编写的机器人。 Lambda 似乎是一个很好的解决方案。
我用 AWS SDK 写了一个简单的测试代码:
var lambda = new AWS.Lambda({apiVersion: '2015-03-31'});
function invoke() {
var start = new Date();
var params = {
FunctionName: 'test', /* required */
InvocationType: 'RequestResponse',
LogType: 'None',
Payload: '{}',
};
lambda.invoke(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
}
else {
var duration = new Date() - start;
console.info("Execution time: %dms", duration);
}
});
}
for (var i = 0; i < n; i++) {
invoke();
}
lambda 函数 "test" 是一个非常简单的函数,它基本上什么都不做,只是 return 返回输入事件。在 lambda 控制台中,它通常需要不到 10 毫秒的时间来执行。我在自己的笔记本电脑上测试过,所以网络延迟大约是 200~300ms。我的开发计算机单次调用大约需要 600~800 毫秒。
小批量 运行 看起来不错:
$ node test.js 5
Execution time: 637ms
Execution time: 652ms
Execution time: 646ms
Execution time: 713ms
Execution time: 850ms
但是,如果我 运行 批量处理它,延迟会变得非常大,并且变得越来越大:
$ node test.js 1000
Execution time: 3569ms
Execution time: 4418ms
Execution time: 3571ms
Execution time: 4505ms
Execution time: 3661ms
Execution time: 3322ms
Execution time: 3645ms
Execution time: 3654ms
Execution time: 3651ms
Execution time: 4531ms
...
Execution time: 71851ms
Execution time: 70879ms
Execution time: 71777ms
我知道 AWS-SDK 实际上正在发出 HTTP 请求来调用 lambda,因此 AWS 会限制并发连接并且请求可能会排队并减慢它们的速度是有道理的。所以似乎不可能以这种方式调用大量的 lambda...:(
我正准备通过发送 SNS 来测试它,但是不确定这是否是一个好的解决方案,因为我希望从那些 lambda 函数中获得结果。
更新:我还将代码放在部署到同一区域的另一个 lambda 函数中,所以我认为网络延迟最小,看起来肯定更快,但似乎有同样的问题。
START RequestId: 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Version: $LATEST
2015-11-12T21:44:00.923Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #0
2015-11-12T21:44:01.003Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #1
2015-11-12T21:44:01.005Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #2
2015-11-12T21:44:01.063Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #3
2015-11-12T21:44:01.065Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #4
2015-11-12T21:44:01.122Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #5
2015-11-12T21:44:01.123Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #6
2015-11-12T21:44:01.124Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #7
2015-11-12T21:44:01.124Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #8
2015-11-12T21:44:01.182Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Lambda invoke #9
2015-11-12T21:44:01.182Z 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Execution time: 753ms
END RequestId: 7bd3339d-8986-11e5-85d1-67b32d2e2f9c
REPORT RequestId: 7bd3339d-8986-11e5-85d1-67b32d2e2f9c Duration: 873.46 ms Billed Duration: 900 ms Memory Size: 128 MB Max Memory Used: 14 MB
我的问题是,有没有办法在很短的时间内调用大量的 lambda?
如果您将 InvocationType
从 RequestResponse
切换到 Event
,那么您的函数将 运行 您的调用异步调用。
您需要异步调用 Lambda(正如@Matt Beckman 指出的那样),并且您需要增加 Lambda account limits。如果您必须维护状态或检索返回的结果,那么您需要找到另一种方法来做到这一点,例如附加到 SQS 队列或 DynamoDB table.