Использование Kafka в качестве (CQRS) Eventstore. Хорошая идея?

Хотя я уже встречался Kafka, я совсем недавно понял, что Кафка, возможно, может быть использована как (основа) a CQRS, eventstore.

Один из основных моментов, который поддерживает Kafka:

  • Захват/хранение событий, все HA, конечно.
  • Архитектура Pub/sub
  • Возможность воспроизведения журнала событий, который позволяет зарегистрировать новые подписчики в системе после факта.

По общему признанию, я не на 100% разбираюсь в CQRS/Event sourcing, но это кажется довольно близким к тому, что должен быть в магазине событий. Смешная вещь: я действительно не могу так много узнать о том, что Кафка используется как eventstore, поэтому, возможно, мне что-то не хватает.

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

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

Ответ 1

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

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

Таким образом, хотя сообщения могут потенциально сохраняться неограниченно, ожидается, что они будут удалены. Это не значит, что вы не можете использовать это как хранилище событий, но лучше использовать что-то другое. Посмотрите EventStore для альтернативы.

UPDATE

Документация Kafka:

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

ОБНОВЛЕНИЕ 2

Одной из проблем использования Kafka для поиска событий является количество требуемых тем. Как правило, в случае поиска источников есть поток (тема) событий на сущность (например, пользователь, продукт и т.д.). Таким образом, текущее состояние объекта может быть восстановлено путем повторного применения всех событий в потоке. Каждая тема Kafka состоит из одного или нескольких разделов, и каждый раздел хранится как каталог в файловой системе. Также будет давление со стороны ZooKeeper по мере увеличения количества зномов.

Ответ 2

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

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

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

Я немного написал об этом стиле использования Kafka здесь.

Ответ 3

Я продолжаю возвращаться к этому QA. И я не нашел существующие ответы достаточно нюансами, поэтому я добавляю этот.

TL; DR. Да или Нет, в зависимости от вашего использования источника событий.

Я знаю о двух основных видах систем, основанных на событиях.

Нижестоящие процессоры событий = Да

В такой системе события происходят в реальном мире и записываются как факты. Например, складская система для отслеживания поддонов с продуктами. Там в основном нет конфликтующих событий. Все уже произошло, даже если это было не так. (Т.е. поддон 123456 поставлен на грузовик А, но был запланирован на грузовик Б.) Затем позже факты проверяются на наличие исключений с помощью механизмов отчетности. Кафка, кажется, хорошо подходит для такого рода приложений обработки событий.

В этом контексте понятно, почему люди Kafka защищают его как решение для поиска событий. Потому что это очень похоже на то, как оно уже используется, например, в потоках кликов. Тем не менее, люди, использующие термин Event Sourcing (в отличие от Stream Processing), скорее всего, ссылаются на второе использование...

Контролируемый приложением источник правды = Нет

Приложение такого типа объявляет свои собственные события в результате запросов пользователей, проходящих через бизнес-логику. Кафка не работает в этом случае по двум основным причинам.

Отсутствие изоляции объекта

В этом сценарии требуется возможность загрузки потока событий для конкретной сущности. Общая причина этого заключается в создании модели переходной записи для бизнес-логики, используемой для обработки запроса. Делать это нецелесообразно в Кафке. Использование темы для каждой сущности может позволить это, за исключением того, что это не начало, когда могут быть тысячи или миллионы сущностей. Это связано с техническими ограничениями в Kafka/Zookeeper.

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

Вместо Kafka рекомендуется использовать топик для каждого типа, но для этого потребуется загрузка событий для каждого объекта этого типа, чтобы получить события для одного объекта. Поскольку вы не можете сказать по позиции журнала, какие события принадлежат к какому объекту. Даже используя моментальные снимки, чтобы начать с известной позиции в журнале, это может быть значительное количество событий, через которые нужно пройти.

Отсутствие обнаружения конфликта

Во-вторых, пользователи могут создавать условия гонки из-за одновременных запросов к одному и тому же объекту. Может быть весьма нежелательно сохранять конфликтующие события и разрешать их по факту. Поэтому важно уметь предотвращать конфликтующие события. Для масштабирования загрузки запроса обычно используют службы без сохранения состояния, предотвращая конфликты записи с использованием условных записей (запись только в том случае, если последним событием объекта был #x). Ака Оптимистичный Параллелизм. Кафка не поддерживает оптимистичный параллелизм. Даже если бы он поддерживал это на уровне темы, он должен был бы пройти весь путь до уровня сущности, чтобы быть эффективным. Чтобы использовать Kafka и предотвращать конфликтующие события, вам нужно использовать сериализованную запись с сохранением состояния на уровне приложения. Это существенное архитектурное требование/ограничение.

Дальнейшая информация


Обновление за комментарий

Комментарий был удален, но вопрос был что-то вроде: что люди тогда используют для хранения событий?

Кажется, что большинство людей катят свою собственную реализацию хранилища событий поверх существующей базы данных. Для нераспределенных сценариев, таких как внутренние серверные или автономные продукты, хорошо документировано, как создать хранилище событий на основе SQL. И есть библиотеки, доступные поверх различных видов баз данных. Существует также EventStore, который построен для этой цели.

В распределенных сценариях я видел несколько разных реализаций. Проект Jet Panther использует Azure CosmosDB с функцией изменения фида для уведомления слушателей. Еще одна похожая реализация, о которой я слышал в AWS, - это использование DynamoDB с функцией Streams для уведомления слушателей. Ключ раздела, вероятно, должен быть идентификатором потока для лучшего распределения данных (чтобы уменьшить объем избыточного выделения ресурсов). Однако полное воспроизведение через потоки в "Динамо" обходится дорого (для чтения и с точки зрения затрат). Так что это подразумевалось также для Dynamo Streams для выгрузки событий на S3. Когда новый слушатель подключается к сети или существующий слушатель хочет полного воспроизведения, он будет читать S3, чтобы наверстать упущенное.

Мой текущий проект - мультитенантный сценарий, и я перевернул свой собственный поверх Postgres. Нечто подобное Citus кажется подходящим для масштабируемости, разделения по tentant + stream.

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

Ответ 4

Вы можете использовать Kafka как хранилище событий, но я не рекомендую это делать, хотя это может показаться хорошим выбором:

  • Kafka гарантирует только по крайней мере один раз доставить, и в хранилище событий есть дубликаты, которые нельзя удалить. Обновление: здесь вы можете узнать, почему так сложно с Kafka и какие-то последние новости о том, как, наконец, добиться такого поведения: https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how -apache-Кафка-делает-то/
  • Из-за неизменности нет возможности манипулировать хранилищем событий, когда приложение развивается, и события должны быть преобразованы (есть, конечно, методы, такие как повышение, но...). Как только можно сказать, что вам никогда не нужно преобразовывать события, но это неверное предположение, может возникнуть ситуация, когда вы делаете резервную копию оригинала, но вы обновляете их до последних версий. Это допустимое требование в архитектуре, управляемой событиями.
  • Нет места для сохранения снимков сущностей/агрегатов, а повторение будет медленнее и медленнее. Создание моментальных снимков должно быть полезно для хранения событий с долгосрочной точки зрения.
  • Учитывая, что разделы Kafka распределены, и их трудно контролировать и сопоставлять с базами данных. Базы данных проще :-)

Итак, прежде чем вы сделаете свой выбор, вы подумаете дважды. Хранилище событий как комбинация интерфейсов прикладного уровня (мониторинг и управление), хранилище SQL/NoSQL и Kafka в качестве брокера - лучший выбор, чем оставлять Kafka для выполнения обеих ролей, чтобы создать полное полнофункциональное решение.

Магазин событий - это сложный сервис, который требует больше, чем может предложить Kafka, если вы серьезно относитесь к применению источников событий, CQRS, Sagas и других моделей в управляемой событиями архитектуре и сохраняете высокую производительность.

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

Пожалуйста, ознакомьтесь с фреймворком eventuate.io с открытым исходным кодом, чтобы узнать больше о потенциальных проблемах: http://eventuate.io/

Дополнение от 08.02.028

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

  1. Не используйте Spring - это здорово (я сам это использую), но одновременно и тяжелый, и медленный. И это вовсе не платформа для микросервисов. Это "просто" структура, которая поможет вам реализовать один (много работы за этим...). Другие рамки - это просто "легкий" REST или JPA или по-разному сфокусированные рамки. Я рекомендую, вероятно, лучшую в своем классе платформу для микросервиса с открытым исходным кодом, которая возвращается к чистым корням Java: https://github.com/networknt

Если вы задаетесь вопросом о производительности, вы можете сравнить себя с существующим набором тестов. https://github.com/networknt/microservices-framework-benchmark

  1. Не используйте Kafka вообще :-)) Это наполовину шутка. Я имею в виду, что Кафка великолепна, это еще одна система брокеров. Я думаю, что будущее в брокерских системах обмена сообщениями. Вы можете быть удивлены, но быстрее системы Kafka :-), конечно, вы должны перейти на более низкий уровень. Посмотрите на Хронику.

  2. Для хранилища событий я рекомендую превосходное расширение Postgresql под названием TimescaleDB, которое фокусируется на высокопроизводительной обработке данных таймсеров (события являются таймсерами) в большом объеме. Конечно, CQRS, Event sourcing (воспроизведение и т.д.) Встроены в систему light4j из коробки, которая использует Postgres как низкое хранилище.

  3. Для обмена сообщениями попробуйте посмотреть хронологию Queue, Map, Engine, Network. Я имею в виду избавиться от этих старомодных решений, ориентированных на брокеров, и пойти с системой микросообщений (встроенной). Очередь хроники на самом деле даже быстрее, чем Кафка. Но я согласен, что это не все в одном решении, и вам нужно сделать некоторую разработку, иначе вы пойдете и купите версию Enterprise (заплатите одну). В итоге усилия по созданию из "Хроники" вашего собственного уровня обмена сообщениями будут оплачиваться путем устранения бремени сохранения кластера Kafka.

Ответ 5

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

Что касается:

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

Это может быть сложно. Я подробно рассказал об этом здесь: fooobar.com/questions/722342/...

Ответ 6

Да, Kafka хорошо работает в модели источников событий, особенно CQRS, однако вы должны позаботиться о настройке TTL для тем и всегда помнить, что kafka не был разработан для этой модели, однако мы можем очень хорошо его использовать.