Настройка AWS SQS / Lambda триггера для соблюдения политики 1: 1, а также максимального числа одновременных экземпляров - PullRequest
2 голосов
/ 26 марта 2020

Java 8 здесь с использованием AWS Java SDK для записи Java лямбда-выражения, которое должно выполняться в ответ на сообщение, отправляемое в очередь SQS.

В идеале , один и только один экземпляр лямбды будет вызываться / выполняться для каждой записи, отправленной в очередь SQS. Таким образом, если в очередь будет отправлено 5 сообщений, будет запущено 5 лямбд (или - в зависимости от моей лямбда-конфигурации - я могу установить максимальное количество одновременных лямбд, и в этом случае я ожидаю, что ожидающие / неиспользованные сообщения SQS будут ожидать следующего доступного лямбда).

Это не сложное требование, просто идеальное.

Я заметил, что в классе com.amazonaws.services.lambda.runtime.events.SqsEvent есть метод getRecords() : List<SQSMessage>, который меня немного беспокоит. Для меня это означает, что один лямбда-экземпляр может быть передан более 1 SQS-сообщения за исполнение , что опять-таки идет вразрез с моим желаемым поведением.

Так что мне интересно, есть ли способ настроить лямбда-триггер так, чтобы он только когда-либо срабатывал один раз для каждого сообщения очереди SQS, а также учитывал параметр «max # одновременных экземпляров Lambda», заставляя сообщения ждать в SQS, пока Lambda не будет готова. В качестве другого примера, скажем, у меня максимальное число одновременных лямбд - макс. 3 (три), и 5 сообщений отправляются в очередь одновременно. В этом случае я хотел бы, чтобы 3 лямбды сработали, каждый обрабатывая одно из 5 сообщений в очереди, и 2 из 5 сообщений ожидали бы, пока один из этих 3 лямбд завершит работу sh, чтобы другой мог сработать и забрать их .

Возможно ли это сделать? Или же Lambda просто «решает» (?) Как-то по своему усмотрению, сколько сообщений нужно отправить для данного выполнения Lambda? Если так, кто-нибудь знает, как это решается?

Ответы [ 2 ]

1 голос
/ 29 марта 2020

TL; DR

Как уже правильно указал @joseph, вы можете использовать отображение источника событий с BatchSize , установленным в 1. Это будет getRecords() вернуть максимально 1 SQSMessage . Чтобы обрабатывать максимум 1 сообщение за раз, вы должны установить для зарезервированного параллелизма функции Lambda значение 1. Однако, как также правильно указано, это не оптимально для стандарта SQS очередь. При отображении источника события возникнет TooManyRequestsException: Rate Exceeded ошибок, которые регистрируются в журналах CloudWatch.

Чтобы использовать правильный шаблон последовательной обработки по одному сообщению за один раз без полагаясь на регулирование лямбда-функции, используйте очередь SQS FIFO, как описано в блоге AWS [1]. В нем говорится: «Общий параллелизм равен или меньше числа уникальных MessageGroupIds в очереди SQS FIFO». Таким образом, вы можете настроить ровно одну MessageGroupId для своей очереди SQS FIFO, чтобы:

  • только когда-либо запускать лямбду один раз за сообщение в очереди SQS (потому что batchSize = 1)
  • при соблюдении «максимального числа одновременных лямбда-экземпляров», равного ровно 1 (потому что число параллелизма = # уникальные идентификаторы группы сообщений = 1)

Таким образом, число уникальных идентификаторов группы сообщений равно макс. число одновременных лямбда-вызовов при сопоставлении источника событий для очереди SQS FIFO.

Дополнительная информация

Java Библиотеки для Lambda

Насколько я вижу, AWS предоставил набор POJO (например, SQSEvent в библиотеке aws -lambda- java -events ) [2] для обработки входящего события SQS [3]. Событие SQS доставляется сопоставлением источника события Lambda и десериализуется в заданный POJO. Документы для POJO SQSEvent также доступны на JavaDo c .io [4], а исходный код доступен на GitHub [5]. Метод getRecords() возвращает список SQSMessage объектов, поскольку сопоставление источника событий AWS Lambda действительно может обеспечить от 1 до 10 сообщений SQS.

Сопоставление источника событий Lambda

Событие сопоставление источника создается и настраивается с атрибутами, которые задают c для типа источника. Поскольку мы рассматриваем интеграцию SQS, мы должны учитывать только атрибуты SQS-Speci c. В основном это: BatchSize и EventSourceArn . Полный список см. В [6]. Если атрибут не применим к типу источника SQS, его описание начинается с ключевого слова (Streams).

. Необходимо установить BatchSize , если вы хотите ограничить количество сообщений SQS, которое получены с помощью getRecords(). Значение по умолчанию - 10.

Лямбда-масштабирование

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

То есть выдается много ошибок регулирования (код 429), если интенсивно используется очередь SQS. , Эту проблему можно решить, если указать источнику события последовательно обрабатывать сообщения. Это достигается с помощью источника событий Amazon SQS FIFO. Это довольно новая функция. [8]

Резюме

В целом, я бы рекомендовал:

  • использовать очередь SQS с типом FIFO вместо стандартного типа
  • использовать сопоставление источника событий с BatchSize, установленным в 1
  • , использовать то же значение для атрибута MessageGroupId во всех SQS SendMessage вызовах API [9]
  • быть знакомым с различиями между очередями SQS FIFO и стандартными очередями [10] [11] - включая различия в ценах [12]
  • не обязательно устанавливать зарезервированный параллелизм, поскольку он обрабатывается источником события отображение для очередей FIFO

Ссылки

[1] https://aws.amazon.com/blogs/compute/new-for-aws-lambda-sqs-fifo-as-an-event-source/
[2] https://docs.aws.amazon.com/lambda/latest/dg/with-sqs-create-package.html#with -sqs-example-deploy-pkg- java
[3] https://docs.aws.amazon.com/lambda/latest/dg/with-sqs.html
[4] https://javadoc.io/static/com.amazonaws/aws-lambda-java-events/2.2.2/com/amazonaws/services/lambda/runtime/events/SQSEvent.html
[5] https://github.com/aws/aws-lambda-java-libs/blob/master/aws-lambda-java-events/src/main/java/com/amazonaws/services/lambda/runtime/events/SQSEvent.java
[6] https://docs.aws.amazon.com/lambda/latest/dg/API_CreateEventSourceMapping.html#API_CreateEventSourceMapping_RequestBody
[7] https://docs.aws.amazon.com/lambda/latest/dg/configuration-concurrency.html
[8] https://aws.amazon.com/about-aws/whats-new/2019/11/aws-lambda-supports-amazon-sqs-fifo-event-source/?nc1=h_ls
[9] https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html
[10] https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/using-messagegroupid-property.html
[11] https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/FIFO-queues.html#FIFO -перемещение очереди
[12] https://aws.amazon.com/sqs/pricing/?nc1=h_ls

1 голос
/ 28 марта 2020

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

Количество лямбд, обрабатывающих сообщение, зависит от ограничения параллелизма, установленного для лямбды. Просто запомните, если количество одновременно разрешенных лямбд, которые вы разрешаете, меньше, чем количество сообщений sqs, которые вы имеете в любое время, вы можете увидеть множество исключений регулирования в ваших показателях cloudwatch. Вы можете игнорировать их, если это желаемое поведение.

Также вы можете увеличить время ожидания видимости вашей конфигурации sqs, чтобы убедиться, что это же сообщение не доставляется другой лямбде, пока она уже обрабатывается одним.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...