Как выбрать лучший источник событий для обмена сообщениями pub/sub с помощью AWS Lambda

1656646696 kak vybrat luchshij istochnik sobytij dlya obmena soobshheniyami pubsub s

Содержание статьи

Янь Цуй

AWS предлагает множество вариантов для реализации шаблонов обмена сообщениями, например Publish/Subscribe (часто сокращается к pub/sub) с AWS Lambda. В этой статье мы сравним некоторые из этих вариантов.

Шаблон pub/sub

Pub/Sub – это шаблон обмена сообщениями, где издатели и подписчики разъединены через посреднического брокера сообщений (ZeroMQ, RabbitMQ, SNS и т.п.).

aMYeJtlvg8qD1aw7GWlpLcrptCADpvXiGRlt
Источник: Публиковать шаблон подписки (Википедия)
in-2N2y0wjCxQdEAMjGcplRv7yUWRfMvewOr

В экосистеме AWS очевидным кандидатом на роль брокера является Simple Notification Service (SNS).

SNS сделает три попытки вашей функции Lambda обработать сообщения перед тем, как отправить его в очередь мертвых писем (DLQ), если для функции указано DLQ. Однако, согласно анализу, проведенному сотрудниками OpsGenie, количество повторных попыток может достигать шести.

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

Это отлично, если вы оптимизируете пропускную способность.

lKqW9l3keN4ybs4AHSxxJSu76E22YUADwgWE

Однако мы часто ограниченный через максимальную пропускную способность, которую могут обрабатывать наши нисходящие зависимости — базы данных, S3, внутренние/внешние службы и т.д.

Если всплеск пропускной способности короткий, то, скорее всего, повторных попыток будет достаточно (существует случайный, экспоненциальный отказ между повторными попытками), и вы не упустите ни одного сообщения.

aUrhbLV0y5hatCjtR-kpZuvzi6eQZBmM9Gtz
Ошибочные сообщения повторяются 2 раза с экспоненциальным возвратом. Если всплеск кратковременный, повторная попытка, вероятно, будет успешной, что не приведет к потере сообщения.

Если всплеск пропускной способности сохраняется в течение длительного периода времени, можно исчерпать максимальное количество повторных попыток. На этом этапе вам придется полагаться на DLQ и, возможно, вмешательство человека, чтобы восстановить сообщения, которые не удалось обработать с первого раза.

2uzNYBIHpLiAdHSsZBRl9aLIXXbKM5mQ5LBG
Ошибочные сообщения повторяются 2 раза с экспоненциальным возвратом. Но частота пакетов сообщений совпадает с повторными попытками, что еще больше усугубляет проблему, и в конце концов максимальное количество повторных попыток исчерпывается, а ошибочные сообщения вместо этого нужно доставлять в DLQ (если он указан).

Подобным образом, если нисходящая зависимость испытывает сбой, то все сообщения, полученные и повторенные во время сбоя, обязательно завершатся сбоем.

PFbSpQtb0Nxx2RREF9VATvUBjJxR5lxu0WD5
Любое сообщение, полученное или повторное во время нисходящего сообщения, будет неудачным и отправлено в DLQ.

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

MdSMzBdPAvsgSkw47bXD2Dj8qlB4K9y0v5fd

SNS также склонен страдать от временных проблем, таких как вспышки трафика, сбои в нисходящей сети. Kinesis, с другой стороны, справляется с этими проблемами гораздо лучше, как описано ниже:

  • Степень параллелизма ограничивается количеством шардов, которые можно использовать для амортизации вспышек в скорости сообщений
MvIaF-A3FjeFNn5GSzSRzJ3vD-fcdF5kZv9q
Скорость вспышек амортизируется, поскольку максимальная пропускная способность определяется параметром no. сегментов * максимальный размер пакета * 5 чтений в секунду. Это дает вам два рычага для регулировки максимальной пропускной способности.
  • Записи повторяются до тех пор, пока не будет достигнут успех, если сбой не длится дольше, чем политика сохранения, используемая для потока (по умолчанию 24 часа). Впоследствии вы сможете обработать записи
v8c03ATaEUayJurzgbxbPSWtqG-rebS7v40U
Воздействие сбоя нисходящей версии поглощается политикой вызова повторных попыток к успеху.

Но Kinesis Streams не лишен собственных проблем. На самом деле, по своему опыту использования Kinesis Streams из Lambda, я нашел ряд оговорок, которые необходимо понять, чтобы эффективно использовать службу.

Вы можете прочитать эти предостережения в другой статье, которую я написал здесь.

Интересно, что Kinesis Streams – не единственный вариант потоковой передачи, доступный на AWS. Есть также DynamoDB Streams.

ZVV6125FoRnsc-WWr5xDeiQdYMgdJgbxZFbn
DynamoDB Streams можно использовать как аналогичную замену Kinesis Streams.

В общем, DynamoDB Streams+Lambda работает так же, как Kinesis Streams+Lambda. В функциональном плане он имеет несколько интересных поворотов:

  • DynamoDB Streams автоматически масштабирует количество фрагментов
  • Если вы обрабатываете потоки DynamoDB с помощью AWS Lambda, вы не платите за чтение из потоков DynamoDB (но вы все равно платите за единицы емкости чтения и записи для самой таблицы DynamoDB)
elMIs2s1bvzsS3t1s6lck8kKjUQtoN16p2d6
Источник: DynamoDB Pricing
  • Kinesis Streams предлагает возможность продлить срок хранения данных до 7 дней, но DynamoDB Streams не предлагает такой возможности.
ZfHR49h8Odv-6oORBUdbEoulWBpkeTobaFSV
Источник: работа с потоками DynamoDB

Тот факт, что DynamoDB Streams автоматически масштабирует количество осколков, может быть палкой о двух концах. С одной стороны это избавляет вас от необходимости управлять потоком и масштабировать его (или создавать домашние решения для автоматического масштабирования). Но с другой стороны, это также может уменьшить способность амортизировать прыжки нагрузки, которую вы передаете нижестоящим системам.

Насколько я знаю, нет способа ограничить количество шардов, к которым может масштабироваться поток DynamoDB, и это то, что вы наверняка учли бы при внедрении собственного решения для автоматического масштабирования.

Я считаю, что самый подходящий вопрос: “what is your source of truth?”

Делает ли строка, записанная в DynamoDB, канонической для состояния вашей системы? Это, конечно, касается большинства N-уровневых систем, построенных вокруг базы данных, независимо от того, это база данных RDBMS или NoSQL.

В базирующейся на событиях системе моделируется как последовательность событий (в отличие от моментального снимка), источником истины вполне может быть поток Kinesis. Например, как только событие записывается в поток, оно считается каноном для состояния системы.

Кроме того, существуют другие соображения относительно стоимости, автоматического масштабирования и т.п.

С точки зрения разработки потоки DynamoDB также имеют некоторые ограничения и недостатки:

  • Каждый поток ограничен событиями из одной таблицы
  • Записи описывают события DynamoDB, а не события вашего домена, что, как я всегда считал, создает ощущение диссонанса во время работы с этими событиями

За исключением стоимости вызовов Lambda для обработки сообщений, некоторые прогнозы стоимости для использования SNS против Kinesis Streams против DynamoDB Streams в качестве посредника. Я делаю предположение, что пропускная способность постоянной, и что каждое сообщение имеет размер 1 КБ.

Ежемесячная стоимость 1 мс/с

yyuEQdQUtDXmaG-3FeSvBuM3Y1quo52SkIQY

Ежемесячная стоимость 1000 msg/s

11RcJ9KEIfnJbOCXvUz8g2J2AR6K5lKuGsNX

Эти прогнозы не следует воспринимать как чистую монету. Во-первых, предположение об идеально согласованной пропускной способности и размере сообщения является нереалистичным, и вам понадобится некоторый запас для потоков Kinesis и DynamoDB, даже если вы не достигаете ограничений дросселирования.

Тем не менее, эти прогнозы говорят мне о том, что:

  1. Вы получаете очень много с каждым шардом в потоках Kinesis
  2. Хотя существует базовая стоимость использования потоков Kinesis, стоимость уменьшается, когда использование увеличивается по сравнению с потоками SNS и DynamoDB, благодаря значительно более низкой стоимости миллиона запросов.

В то время как потоки SNS, Kinesis и DynamoDB являются вашим основным выбором для посредника, функции Lambda могут также действовать как посредники самостоятельно и распространять события на другие службы.

Это подход, использующий проект aws-lambda-fanout от awslabs. Это позволяет распространять события из потоков Kinesis и DynamoDB на другие службы, которые не могут напрямую подписаться на три основных выбора брокеров (либо из-за ограничения учетной записи/региона, либо из-за того, что они просто не поддерживаются).

arPDE4lmFHJ-GPKb3u-366nUFaDeaZxiyZp8
Проект aws-lambda-fanout от awslabs распространяет события из Kinesis и DynamoDB Streams в другие службы в нескольких учетных записях и регионах.

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

Вывод

Итак, какой самый лучший источник событий для осуществления pub-sub из AWS Lambda? Как и большинство технических решений, это зависит от проблема вы пытаетесь решить, и ограничение вы работаете с.

В данной публикации мы рассмотрели SNS, Kinesis Streams и DynamoDB Streams в качестве кандидатов на роль брокера. Мы рассмотрели несколько сценариев, чтобы увидеть, как выбор источника события влияет на масштабируемость, параллелизм и устойчивость к временным проблемам и стоимости.

Теперь вы гораздо лучше понимать компромиссы между различными источниками событий во время работы с Lambda.

В следующий раз!

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *