我有一个查询aws dynamodb的python aws lambda函数。 由于我的api现在需要大约1秒钟来响应非常简单的查询/表设置,因此我想了解我可以在哪里进行优化。
该表目前只有3个项目(用户),其结构如下:
library(tidyr)
df%>% mutate_if(is.factor,as.character) %>%
separate(country,sep = '\\s(?=\\d)', into = c('country','number','2','3','4','5' ))
country number 2 3 4 5
1 Bolivia 0.16 0.16 4.63* 22.10* 450
2 Germany 0.77 6.06* 0.53 15.35* 630
3 Bosnia & Herzegovina 0.72 6.84* 1.03 21.60* 889
查询非常简单:
user_id (Primary Key, String),
details ("[{
"_nested_atrb1_str": "abc",
"_nested_atrb2_str": "def",
"_nested_map": [nested_item1,nested_item2]},
{..}]
查询需要0.8-0.9秒。
答案 0 :(得分:1)
有几件事需要调查。首先,您的计时时间是.8-.9秒,是基于直接通过将查询包装在某个时间或类似计时器的时间中对查询进行计时吗?如果确实是那次查询花费时间,那么从Lambda与Dynamo的交互中肯定有一些不对劲。
如果您看到的时间实际上是通过调用Lambda来实现的(因为您提到了“ api”,所以我认为这是通过API网关作为REST API进行的),那么您看到的时间可能是由于多种因素造成的。您可以剖析API调用吗?我将检查通过Postman甚至浏览器工具是否可以进行配置,以查看DNS查找,SSL设置等的时间。此外,一旦请求达到Lambda,CloudWatch将为您提供Lambda呼叫时间的特定指标。您还可以考虑启用X-Ray,它将为您提供有关执行Lambda的更多详细信息。如果您的Lambda在VPC中运行,您也可能会遇到冷启动,这会导致您看到等待时间。
X射线: https://aws.amazon.com/xray/
冷启动:只是Google“ AWS Lambda冷启动”,您会找到各种信息
答案 1 :(得分:1)
分析我的小lambda代码(在lambda之外),我得到了这些结果,您可能会觉得有趣。
Times in milliseconds
# Initially
3 calls to DB,
1350 ms 1st call (read)
1074 ms 2nd call (write)
1051 ms 3rd call (read)
# After doing this outside the DB calls and providing it to each one
dynamodb = boto3.resource('dynamodb',region_name=REGION_NAME)
12 ms executing the line above
1324 ms 1st call (read)
285 ms 2nd call (write)
270 ms 3rd call (read)
# seeing that reusing was producing savings I did the same with
tableusers = dynamodb.Table(TABLE_USERS)
12 create dynamodb handler
3 create table handler
1078 read reusing dynamodb and table
280 write reusing dynamodb and table
270 read reusing dynamodb (not table)
因此,起初只花了3.4秒,现在仅需2秒即可添加到约1.6秒。
我在jupyter / Colab上使用%lprun获得了这些结果
# The -u 0.001 sets the time unit at 1ms (default is 1 microsecond)
%lprun -u 0.001 -f lambdaquick lambdaquick()
如果您只执行1个DB请求,而对数据库没有其他要求,请尝试按照amittn的建议将2个DB处理程序放在lambda处理程序之外。
免责声明:我刚刚学到了所有这一切,包括深度剖析。因此,所有这些可能都是胡说八道。
注意:“我们应该忘记效率低下的问题,大约有97%的时间是这样:过早的优化是万恶之源。-唐纳德·努斯(Donald Knuth)” https://jakevdp.github.io/PythonDataScienceHandbook/01.07-timing-and-profiling.html
https://docs.aws.amazon.com/lambda/latest/dg/best-practices.html https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/best-practices.html https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/GettingStarted.Python.03.html
答案 2 :(得分:0)
如果仅在第一次调用时才看到此问题,则肯定是由于lambda的冷启动引起的。否则,在随之而来的要求下,应该进行改进,以帮助您诊断出实际的疼痛点。另外,cloudwatch日志将有助于跟踪请求。
答案 3 :(得分:0)
我假设您正在重用您的连接,因为这会将您的执行时间缩短了几毫秒。如果没有,这将帮助您实现目标。
integers = ['2', '8', '2', '3', '6', '4', '1', '1', '10', '6', '3', '3', '6', '1', '3', '8', '4', '6', '1', '10', '8', '4', '10', '4', '1', '3', '2', '3', '2', '6', '1', '5', '2', '9', '8', '5', '10', '8', '7', '9', '6', '4', '2', '6', '3', '8', '8', '9', '8', '2', '9', '10', '3', '10', '7', '5', '7', '1', '7', '5', '1', '4', '7', '6', '1', '10', '5', '4', '8', '4', '2', '7', '8', '1', '1', '7', '4', '1', '1', '9', '8', '6', '5', '9', '9', '3', '7', '6', '3', '10', '8', '10', '7', '2', '5', '1', '1', '9', '9', '5']
print(sorted(integers, key=str))
函数之外的任何变量都将在Lambda调用之间冻结,并可能被重用。该文档指出:“不假设AWS Lambda总是重用容器,因为AWS Lambda可能会选择不重用容器。”但据观察,根据执行量的不同,容器几乎总是被重用。
答案 4 :(得分:0)
对于有类似经验的人,我收到了以下AWS开发人员支持回复,其中包含一些有用的参考资料。它没有解决我的问题,但是我现在知道这主要与低(测试)量和lambda启动时间有关。
1)这是对只有3个项目的表的正常查询时间,每个用户最多只有5个属性(包括嵌套)吗?
时间很慢,但可能是由于您的设置而导致的多种因素所致。由于您正在使用Lambda,因此需要记住,每次触发Lambda函数时,它都会设置您的环境,然后执行代码。 AWS Lambda函数在容器内运行,该容器是与其他函数隔离的执行环境。首次运行功能时,AWS Lambda将创建一个新容器并开始执行该功能的代码。 Lambda函数具有一个处理程序,该处理程序在每次调用时执行一次。函数执行后,AWS Lambda可能会选择将容器重用于后续的函数调用。在这种情况下,您的函数处理程序可能能够重用您在初始化代码中定义的资源。 (请注意,您无法控制AWS Lambda将该容器保留多长时间,或者根本无法重复使用该容器。)您的表很小,我看了一下。 [1]
2)如果结构保持不变,但项目(用户)数量却增加了一百倍,我是否可以期望相似的时间?
如果代码需要更长的时间来执行,并且您在DynamoDB中拥有更多的数据,最终它可能会变慢,再次基于您的设置。
关于优化设置的一些建议。
1)在同一VPC中具有Lambda和DynamoDB。您可以通过VPC端点查询DynamoDB。这将减少任何网络延迟。 [2] [3]
2)增加lambda的内存,以加快启动和执行时间。
3)随着您的应用程序扩展。确保在处理DynamoDB表时启用自动缩放功能,并增加RCU和WCU以改善DynamoDB的性能。 [4]
此外,请查看DynamoDB最佳实践。 [5]
如有任何其他问题和进一步的指导,请随时与我联系。谢谢。祝您愉快。祝你有美好的一天。