Как использовать n результатов лямбда-функции (A) для вызова n одновременных экземпляров другой функции лямбда-процессора (B) в Python? - PullRequest
0 голосов
/ 07 мая 2019

У меня есть лямбда-функция AWS (A), которая возвращает n URL. Я хотел бы передать каждый из этих URL-адресов по отдельности и одновременно в качестве параметров в другую лямбда-функцию AWS (B). Затем функция B обрабатывает переданный URL и возвращает результат. Обе эти функции написаны на Python, и я бы предпочел избегать других языков, если это возможно. Есть ли у кого-нибудь окончательное решение, которое учитывает таймауты, нарушения параллелизма, другие крайние случаи и / или ошибки?

Даже при максимальном выделении памяти функции A требуется ~ 85 секунд, чтобы просто установить полезную нагрузку и вызвать функцию B 1100 раз. Типично ли ~ 80мс для вызова другой лямбда-функции AWS? Есть ли более быстрый способ? Кроме того, журналы CloudWatch для функции B разделяют вызовы между несколькими потоками журналов, что затрудняет просмотр всех вызовов в 1 месте, чтобы подтвердить, что все сделано правильно и / или в каком порядке и / или где могут быть обнаружены какие-либо ошибки / задержки. .

Я просмотрел документы boto3.client ('lambda')

Я также использовал Использование boto для вызова лямбда-функций. Как я могу сделать это асинхронно? и AWS Lambda: вызов функции из другой лямбды AWS с использованием boto3, вызов для получения моего существующего кода .

Это код, который я использую для тестирования.

# 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 Ответ

1 голос
/ 08 мая 2019

Типично ~ 80 мс для вызова другой лямбда-функции AWS?

Это не очень плохо для меня, но, возможно, есть место для улучшения.Одна вещь, которая бросается в глаза при взгляде на ваш код, это то, что вы снова и снова создаете клиентский объект AWS Lambda.Попробуйте создать клиент один раз, например так:

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

Повторное использование того же объекта клиента, я думаю, вы увидите улучшение производительности из-за повторного использования основного HTTP-соединения с сервером AWS API.

Кроме того, журналы CloudWatch для функции B разделяют вызовы между несколькими потоками журналов, затрудняя просмотр всех вызовов в 1 месте, чтобы подтвердить, что все сделано правильно и / или в каком порядке и / или где-либоошибки / задержки могут быть обнаружены.

Вы имеете дело с более чем тысячей асинхронных процессов, запущенных на нескольких серверах.Просмотр всех этих журналов в одном месте будет сложной задачей.Возможно, вы захотите использовать что-то вроде CloudWatch Logs Insights .

Есть ли у кого-нибудь окончательное решение, которое учитывает тайм-ауты, нарушения параллелизма, другие пограничные случаи и / или ошибки?

Типичным шаблоном управления таймаутами, ограничениями параллелизма и другими ошибками может быть отправка всех событий в очередь SQS, а позволяет очереди запускать вторую функцию Lambda .Однако, в то время как ваша первая лямбда-функция завершит работу так же быстро, как сейчас, или, возможно, быстрее,

Еще одним шаблоном, который можно использовать для решения некоторых из этих проблем, будет реализация алгоритма экспоненциального отката . в вашей первой лямбда-функции.Однако для этого потребуется, чтобы код вашей функции обрабатывал повторные попытки напрямую, вместо этого полагаясь на другие службы AWS, такие как SQS, для обработки повторных попыток для вас, и для этого потребовалось бы добавить паузы в вашей функции Lambda, что потенциально может привести к тому, что первый вызов функции в конечном итоге прервется по таймауту до ее завершения.успешно запустил все вторые вызовы функций, которые просто создают еще одно условие ошибки, с которым вам придется как-то справиться.

...