Реализация AWS Event Sourcing

Я новичок в микросервисах и Event-Sourcing, и я пытался найти способ развернуть всю систему на AWS.

Насколько мне известно, существует два способа реализации архитектуры, управляемой событиями:

  • Использование AWS Kinesis Data Stream
  • Использование AWS SNS + SQS

Итак, моя базовая стратегия заключается в том, что каждая команда преобразуется в событие, которое хранится в DynamoDB, и использует DynamoDB Streams для уведомления других микросервисов о новом событии. Но как? Какое из двух предыдущих решений следует использовать?

К преимуществам первого относятся:

  • Порядок сообщений
  • Минимум одна доставка

А вот недостатки довольно проблематичны:

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

Преимущества второго заключаются в следующем:

  • Полностью управляется
  • Очень высокий ТПС
  • Подписки на темы
  • Функциональность видимости сообщений

Недостатки:

  • Сообщения SQS упорядочены с максимальной эффективностью, но до сих пор непонятно, что они означают. В нем говорится: «Стандартная очередь делает все возможное для сохранения порядка сообщений, но более одной копии сообщения могут быть доставлены не по порядку». Означает ли это, что при наличии n копий сообщения первая копия доставляется по порядку, а остальные доставляются неупорядоченно по сравнению с копиями других сообщений? Или "более того" может быть "все"?

Большое спасибо за любые советы!


person Christian Paesante    schedule 03.10.2018    source источник


Ответы (1)


I'm quite a newbe in microservices and Event-Sourcing

Прочтите выступление Грега Янга Polygot Data, чтобы узнать больше о том, что будет дальше.

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

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

В AWS вы обычно получаете это представление, запрашивая у авторитетного сервиса обновленный список событий (реализация которого может включать пейджинг). Служба может предоставлять список событий, запрашивая DynaModb напрямую или получая самый последний ключ из DynamoDB, а затем просматривая кэшированные представления событий в S3.

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

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

Я сам не смотрел внимательно на Kinesis - есть несколько общее обсуждение в предыдущих вопросах -- но я думаю, что Кевин Сукочефф что-то понимает, когда пишет

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

Основным вариантом использования Kinesis является сбор, хранение и обработка непрерывных потоков данных в реальном времени. Потоки данных — это данные, которые непрерывно генерируются тысячами источников данных, которые обычно отправляют записи данных одновременно и в небольших размерах (порядка килобайт).

Another thing: the fact that I'm accessing data from another 
microservice stream is an anti-pattern, isn't it?

Что ж, часть смысла разделения системы на микрослужбы состоит в том, чтобы уменьшить связь между возможностями системы. Доступ к данным через границы микросервиса увеличивает связанность. Значит, есть какое-то напряжение.

But basically if I'm using a pull model I need to read 
data from other microservices' stream. Is it avoidable?

Если вы запрашиваете необходимую информацию у службы, а не извлекаете ее из потока самостоятельно, вы уменьшаете связанность — так же, как запрашиваете данные у службы, а не обращаетесь к РСУБД и самостоятельно запрашиваете таблицы.

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

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

person VoiceOfUnreason    schedule 03.10.2018
comment
Это видео вышибло мне мозг. Самый интересный разговор, который я когда-либо видел. Большое спасибо. Я никогда раньше не рассматривал модель вытягивания, потому что думал, что когда вы пишете в ES, он сохраняет и публикует событие, и, что необходимо, предполагается модель выталкивания (которая проще и быстрее). Правильно, пока вы не можете это реализовать. Итак, ваше предложение состоит в том, чтобы иметь общий поток событий или иметь больше потоков событий, сгруппированных по теме события? Другое дело: тот факт, что я обращаюсь к данным из другого потока микросервиса, — это антипаттерн, не так ли? - person Christian Paesante; 04.10.2018
comment
Но в основном, если я использую модель извлечения, мне нужно читать данные из потока других микросервисов. Этого можно избежать? - person Christian Paesante; 05.10.2018
comment
Большое спасибо, наконец-то я понял. В частности, для AWS это моя идея: я буду использовать DynamoDB в качестве ES, используя Dynamo Streams, я помещаю события на S3, которые я буду использовать в качестве службы для получения данных. В этом случае темы представляют собой корзины S3, и в основном я запрашиваю подмножество идентификаторов событий. Поскольку я не хочу иметь дублированное хранилище событий, я также рассмотрю что-то вроде TTL или срока действия для объектов S3. Это хорошее решение? Это слишком дорого? - person Christian Paesante; 05.10.2018
comment
Я разобрался, это довольно дешево, но не позволяет получать объекты партиями. Я должен немного больше изучить свою проблему и найти способ решить все. В любом случае, большое спасибо за ваше время и ваши советы! - person Christian Paesante; 05.10.2018
comment
Еще один вопрос: в модели вытягивания у нас обычно есть несколько экземпляров, вытягивающих из одной и той же темы. Мы находимся в модели конкурирующего потребителя. Как осуществляется заказная обработка? Я имею в виду, что учитывая событие, созданное пользователем и удаленное пользователем, если у нас есть служба, использующая эти события, и удаление обрабатывается до создания, у нас есть некоторые проблемы с согласованностью. Как этого избежать? - person Christian Paesante; 07.10.2018