如果我用Python编写的Lambda函数需要1.8秒的初始化时间(在冷启动期间)和400 ms的执行时间,那么我需要为400 ms的执行时间或整个2.2秒的初始化时间+执行时间付费吗?
从X射线中,我看到:
从CloudWatch日志中,我看到:
Duration: 404.42 ms Billed Duration: 500 ms Memory Size: 448 MB Max Memory Used: 113 MB
我从中了解到,我需要为500毫秒的执行时间计费,这是否意味着代码初始化(例如,导入内容)是免费的?
答案 0 :(得分:2)
因此,我决定尝试通过一个小尝试自己弄清楚。我使用Python 2.7创建了Lambda函数,具有 128 MB RAM , 15秒超时并启用了主动跟踪。我修改了示例代码,在import语句之后添加了10秒的睡眠时间:
print "starting import"
import json
from time import sleep
sleep(10)
print "calling handler"
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
我在CloudWatch日志中看到了这一点:
22:06:47 starting import
22:06:57 calling handler
22:06:58 START RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Version: $LATEST
22:06:58 starting import
22:07:08 calling handler
22:07:08 END RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
22:07:08 REPORT RequestId: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx Duration: 10022.57 ms Billed Duration: 10100 ms Memory Size: 128 MB Max Memory Used: 19 MB
该功能实际上运行了 TWICE 。第一次睡眠10秒钟后,它在调用处理程序方法时重新启动,基本上需要20秒钟才能完成执行,但要向我收费10秒钟。
我又跑了一次,这一次热身,我明白了:
CloudWatch日志(热启动):
22:23:16 START RequestId: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy Version: $LATEST
22:23:16 END RequestId: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
22:23:16 REPORT RequestId: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy Duration: 6.97 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 29 MB
没有可疑之处。我将功能内存增加到192 MB,将其保存并恢复为128 MB,然后再次保存以确保它再次开始冷启动并再次调用它。 X射线的输出与以前相同,但是CloudWatch日志有一些有趣的东西:
22:30:13 starting import
22:30:24 START RequestId: zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz Version: $LATEST
22:30:24 starting import
22:30:34 calling handler
22:30:34 END RequestId: zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz
22:30:34 REPORT RequestId: zzzzzzzz-zzzz-zzzz-zzzz-zzzzzzzzzzzz Duration: 10010.85 ms Billed Duration: 10100 ms Memory Size: 128 MB Max Memory Used: 19 MB
在我的代码处于休眠状态10秒钟的时候, Lambda切断了它并重新启动了它。执行时间再次是20秒,但我被收取了10秒的费用。因此,我想如果我不添加1个睡眠语句,而是添加15个一秒钟的睡眠呢?
更新的代码:
print "starting import"
import json
from time import sleep
for i in range(1, 16):
sleep(1)
print "completed {}th sleep".format(i)
print "calling handler"
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
该功能超时!
CloudWatch日志:
22:51:54 starting import
22:51:55 completed 1th sleep
22:51:56 completed 2th sleep
22:51:57 completed 3th sleep
22:51:58 completed 4th sleep
22:51:59 completed 5th sleep
22:52:00 completed 6th sleep
22:52:01 completed 7th sleep
22:52:02 completed 8th sleep
22:52:03 completed 9th sleep
22:52:04 START RequestId: 11111111-1111-1111-1111-111111111111 Version: $LATEST
22:52:04 starting import
22:52:05 completed 1th sleep
22:52:06 completed 2th sleep
22:52:07 completed 3th sleep
22:52:08 completed 4th sleep
22:52:09 completed 5th sleep
22:52:10 completed 6th sleep
22:52:11 completed 7th sleep
22:52:12 completed 8th sleep
22:52:13 completed 9th sleep
22:52:14 completed 10th sleep
22:52:15 completed 11th sleep
22:52:16 completed 12th sleep
22:52:17 completed 13th sleep
22:52:18 completed 14th sleep
22:52:19 END RequestId: 11111111-1111-1111-1111-111111111111
22:52:19 REPORT RequestId: 11111111-1111-1111-1111-111111111111 Duration: 15015.16 ms Billed Duration: 15000 ms Memory Size: 192 MB Max Memory Used: 19 MB
22:52:19
2019-03-29T22:52:19.621Z 11111111-1111-1111-1111-111111111111 Task timed out after 15.02 seconds
22:52:19 starting import
22:52:20 completed 1th sleep
22:52:21 completed 2th sleep
22:52:22 completed 3th sleep
22:52:23 completed 4th sleep
22:52:24 completed 5th sleep
22:52:25 completed 6th sleep
22:52:26 completed 7th sleep
22:52:27 completed 8th sleep
22:52:28 completed 9th sleep
22:52:29 completed 10th sleep
它实际上执行了25.8秒,但随后超时并向我收费15秒。在调用处理程序之前执行的代码运行了大约9秒钟,然后Lambda将其切断并重新启动该函数,但没有完成,最终在25.8秒后超时。如果我将Lambda超时增加到16秒,它会在25.8秒内完成执行(如X-Ray所示),并向我收费15100毫秒。
因此,这使我相信如果在初始化后约9-10秒内未调用处理程序函数,Lambda将重新启动该函数。那如果代码初始化花费不到10秒怎么办?
更新的代码:
print "starting import"
import json
from time import sleep
for i in range(1, 10):
sleep(1)
print "completed {}th sleep".format(i)
print "calling handler"
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': json.dumps('Hello from Lambda!')
}
我将此功能冷运行了大约10次,并且计费时间始终为100毫秒。 我什至将我的lambda超时更改为1秒,它仍然成功执行完毕!
CloudWatch日志:
23:23:43 starting import
23:23:44 completed 1th sleep
23:23:45 completed 2th sleep
23:23:46 completed 3th sleep
23:23:47 completed 4th sleep
23:23:48 completed 5th sleep
23:23:49 completed 6th sleep
23:23:50 completed 7th sleep
23:23:51 completed 8th sleep
23:23:52 completed 9th sleep
23:23:52 calling handler
23:23:52 START RequestId: 22222222-2222-2222-2222-222222222222 Version: $LATEST
23:23:52 END RequestId: 22222222-2222-2222-2222-222222222222
23:23:52 REPORT RequestId: 22222222-2222-2222-2222-222222222222 Duration: 0.73 ms Billed Duration: 100 ms Memory Size: 128 MB Max Memory Used: 44 MB
正如 Steve HOUEL 正确指出的那样,这使我相信 Lambda不会对您初始化代码(例如导入东西)的时间收取费用,只要它在大约9秒内完成。但是,如果花费的时间更长,Lambda将重新启动您的函数,并假设您设置了足够大的超时时间,有效执行函数将需要10秒+常规的冷启动执行时间,但您仍需为此付费冷启动执行时间,无需增加10秒。
答案 1 :(得分:0)
这取决于您对初始化时间的含义。
如果您的意思是容器启动,分配等,则无需为此付费。
如果您的意思是代码初始化(需要模块,连接到DB等),是的,您需要为此付费。
我不了解Python,但是如果您想在NodeJS中看到它的实际作用,请在导出其功能之前导入一个具有阻塞操作的模块。
例如,您可以拥有包含以下代码的someModule.js
文件:
for (let i = 0; i < 10000000000; i++) {}
module.exports = {
test: () => {}
}
for loop
是一个阻塞操作,因此,仅在循环完成后才调用module.exports。
这意味着如果您在处理程序中require('someModule)
,它将挂起,直到someModule
导出所有内容为止。
const someModule = require('./someModule')
exports.handler = async event => {
console.log(event)
}
然后,您需要花费时间someModule
才能成功导出其功能。
答案 2 :(得分:0)
仅当您在init上花费超过10s时,您才需要为它付费。在这种情况下,您的初始化过程将重新开始,您将开始为此付费。
但是您应该知道,一旦您的功能被加热,就不会再次初始化(直到静止45分钟左右)。然后,您只需支付执行时间。
答案 3 :(得分:0)
已编辑:您的实验看起来有效。
我建议阅读this excellent post,其中包括有关AWS Lambda运行时计费方式的信息。
答案 4 :(得分:-1)
您可以免费获得Lambda中的东西:
持续时间是从您的代码开始执行到返回或终止为止的时间计算的,四舍五入到最接近的100ms。
价格取决于您分配给函数的内存量。
Lambda在每次响应事件通知或调用而开始执行(包括从控制台进行测试调用)时对请求进行计数。因此,您需要为所有功能的请求总数付费。
此外,在程序启动时,需要执行一些操作,例如导入库,设置DB以及初始化全局变量和类。 您需要为Lambda初始化的这一部分支付费用。