如何使用Lambda函数(A)的n个结果在Python中调用另一个Lambda处理器函数(B)的n个并发实例?

时间:2019-05-07 20:27:29

标签: python concurrency aws-lambda invoke

我有一个AWS Lambda函数(A),该函数返回n个URL。我想将每个这些URL作为参数分别并发地传递到另一个AWS Lambda函数(B)中。然后,函数B处理传递的url并返回结果。这两个函数都是用Python编写的,如果可能的话,我宁愿避免使用其他语言。是否有人能解决超时,并发冲突,其他极端情况和/或错误?

即使分配了最大内存,函数A仍需要约85秒才能设置有效负载并调用函数B 1,100次。调用另一个AWS Lambda函数通常需要80毫秒吗?有没有更快的方法?此外,功能B的CloudWatch Logs将多个日志流中的调用分开,这使得很难在一个地方查看所有调用,以确认事情是否正确完成和/或以什么顺序执行,和/或在哪里可能存在任何错误/延迟。

我看过boto3.client('lambda') docs

我还利用Using boto to invoke lambda functions how do I do so asynchronously?AWS Lambda: call function from another AWS lambda using boto3 invoke来获取现有代码。

这是我用于测试的代码。

# Function A - using max Memory setting (3008 MB currently) to speed things up

import boto3
import json

def lambda_handler(event, context):
    #simulate 1,100 urls (more than the default concurrency limit of 1,000)
    n = 1100
    results = range(1, n+1)
    #invoke function B asynchronously
    for result in results:
        payload = {'url' : result}
        boto3.client('lambda').invoke(FunctionName='B', InvocationType='Event', Payload=json.dumps(payload))
    return{'statusCode': 200, 'body': json.dumps('Hello from Lambda!')}
# Function B - using the min Memory setting (128 MB currently)

import json
import time

def lambda_handler(event, context):
    #wait 5 seconds to simulate processing time
    time.sleep(5)
    #process passed payload from function A
    print(event['url'])
    return{'statusCode': 200, 'body': json.dumps('Bye from Lambda!')}


1 个答案:

答案 0 :(得分:1)

  

调用另一个AWS Lambda函数通常需要80毫秒吗?

这对我来说听起来并不很糟糕,但是可能还有一些改进的余地。查看代码时,让我惊讶的一件事是,您正在一遍又一遍地创建AWS Lambda客户端对象。尝试一次创建客户端,如下所示:

client = boto3.client('lambda')
for result in results:
        payload = {'url' : result}
        client.invoke(FunctionName='B', InvocationType='Event', Payload=json.dumps(payload))

通过重用相同的客户端对象,我认为由于与AWS API服务器的基础HTTP连接的重用,您将看到性能上的改善。

  

此外,功能B的CloudWatch Logs将   多个日志流之间的调用使得很难看到所有   在1个地方调用以确认操作是否正确完成和/或   顺序和/或错误/延迟的位置。

您正在处理在多个服务器上运行的一千多个异步进程。在一个地方查看所有这些日志将是一个挑战。您可能会考虑使用类似CloudWatch Logs Insights之类的东西。

  

任何人都有解决超时的明确解决方案,   并发冲突,其他极端情况和/或错误?

用于管理超时,并发限制和其他错误的典型模式是将所有事件发送到SQS队列和let the queue trigger your second Lambda function。但是,虽然您的第一个Lambda函数将像现在一样快完成,甚至可能更快,

可以用来解决其中一些问题的另一种模式是在您的第一个Lambda函数中实现exponential backoff algorithm。但是,这将需要您函数的代码直接处理重试,而不是依靠其他AWS服务(如SQS)为您处理重试,并且这需要在Lambda函数中添加暂停,这可能会导致第一个函数调用最终在此之前超时已成功触发了所有第二个函数调用,这仅创建了另一个您必须以某种方式处理的错误条件。