Використання Kafka як магазину подій (CQRS) Гарна ідея?


219

Хоча я раніше зустрічався з Кафкою , я нещодавно зрозумів, що Кафку, можливо, можна використовувати як (основу) CQRS , eventstore .

Один з головних моментів, які підтримує Кафка:

  • Захоплення / зберігання події, всі HA звичайно.
  • Паб / під архітектура
  • Можливість відтворення журналу подій, що дозволяє новим абонентам зареєструватися в системі після факту.

Правда, я не на 100% розбираюся в пошуку CQRS / подій, але це здається досить близьким до того, яким має бути магазин подій. Смішна річ: я дійсно не можу знайти те, що Кафка використовується як магазин подій, тому, можливо, мені щось не вистачає.

Отже, чогось не вистачає Кафці, щоб це було гарним заходом подій? Це би спрацювало? Використовуючи це виробництво? Цікавить прозріння, посилання тощо.

В основному стан системи зберігається на основі транзакцій / подій, які система коли-небудь отримувала, замість того, щоб просто зберегти поточний стан / знімок системи, що зазвичай робиться. (Подумайте про це як про головну книгу в бухгалтерському обліку: усі транзакції в кінцевому рахунку складаються до остаточного стану) Це дозволяє всілякі цікаві речі, але просто читайте за наданими посиланнями.


Привіт, Герт-Ян. В ретроспективі, як ви вирішили цю проблему? У мене пов'язане питання (викрите тут: stackoverflow.com/questions/58763727/… ). Більшість людей, які пропонують прийняття Кафки, схоже, покладаються на точки незмінюваності журналу додавання, високої пропускної здатності та гарантії порядку розділів. Я бачу проблеми, пов’язані з швидким пошуком у темах (для "реконструкції"), відсутністю трансакційної атомності та не замовленням через розділи (100% гарантія замовлення передбачає використання лише 1 розділу
вбивство

Зрештою, не переконав це, тому що я закінчив цей бічний проект. Тож жодної чіткої відповіді я не боюся
Geert-Jan

Відповіді:


119

Кафка покликана бути системою обміну повідомленнями, яка має багато подібності до магазину подій, проте цитувати їх вступ:

Кластер Kafka зберігає всі опубліковані повідомлення - незалежно від того, були вони споживані чи ні - протягом певного періоду часу . Наприклад, якщо утримання встановлено на два дні, то протягом двох днів після публікації повідомлення воно доступне для споживання, після чого воно буде відкинуто, щоб звільнити місце. Продуктивність Kafka фактично постійна щодо розміру даних, тому збереження великої кількості даних не є проблемою.

Отже, хоча повідомлення потенційно можуть зберігатися на невизначений термін, очікується, що вони будуть видалені. Це не означає, що ви не можете використовувати це як магазин подій, але може бути краще використовувати щось інше. Погляньте на EventStore для альтернативи.

ОНОВЛЕННЯ

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

Розподіл подій - це стиль дизайну додатків, коли зміни стану реєструються як упорядкована за часом послідовність записів. Підтримка Kafka для дуже великих збережених даних журналу робить його відмінним доповненням для програми, побудованої в цьому стилі.

ОНОВЛЕННЯ 2

Одним із питань використання Kafka для пошуку подій є кількість необхідних тем. Зазвичай у пошуку джерел подій є потік (тема) подій на одну особу (наприклад, користувача, продукту тощо). Таким чином, поточний стан суб'єкта господарювання можна відновити шляхом повторного застосування всіх подій у потоці. Кожна тема Kafka складається з одного або декількох розділів, і кожен розділ зберігається як каталог у файловій системі. Також буде тиск з боку ZooKeeper, оскільки кількість znodes збільшуватиметься.


16
Я дивився на Кафку і мав ще одне занепокоєння: я не помітив нічого про оптимістичну-одночасність. В ідеалі я можу сказати: "Додайте цю подію як пункт N + 1, лише якщо останньою подією об'єкта все ще є N."
Дарієн

2
@Darien: Я, мабуть, іду з налаштуваннями, коли Redis годує Кафку (використовуючи повідомлення Redis ). Оскільки Redis дозволяє отримати оптимістичну одночасність (використовуючи Watch / multi-exec), це має спрацювати
Geert-Jan

2
@Darien Я не фахівець з пошуку подій, але я розумів, що в цілому вам не знадобиться оптимістична паралельність, оскільки події - це визначення записів речей, які вже відбувалися історично.
Іван

4
@John Я думаю, якщо у вас уже є авторитетне впорядкування безконфліктних подій, це означає, що де вони живуть, це ваша реальна технологія магазину подій, і Kafka просто використовується як вторинна система їх розповсюдження.
Дарієн

1
Тут також є цінна інформація: groups.google.com/forum/#!topic/dddcqrs/rm02iCfffUY
manuc66

283

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

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

Я думаю, ви не дуже чуєте про використання Kafka для пошуку подій, перш за все тому, що термінологія пошуку подій, схоже, не дуже поширена в споживчому веб-просторі, де Kafka є найпопулярнішим.

Я написав трохи про цей стиль використання Kafka тут .


2
Збирався розмістити це посилання :) Дивовижне повідомлення в блозі. Було б добре, щоб можна було прокоментувати це, бо у мене багато питань. @ Geert-Jan також погляньте на "архітектуру лямбда", це дуже схоже, і назва дана автором Storm, в основному використовуючи якийсь журнал подій на основі hadoop у багатьох прикладах
Себастьян Лорбер

6
@Jay: Оскільки я відновив інтерес до цієї теми, чи не могли б ви детальніше розібратися у тому, що Kafka, здається, створений таким чином, щоб його опубліковані повідомлення закінчувалися через встановлений проміжок часу? Якщо ви використовуєте Kafka як джерело подій, повідомлення повинні зберігатися нескінченно. Це, мабуть, можна налаштувати, але чи це створюватиме проблему?
Geert-Jan

2
Чи є порівняння між kafka та eventstore? Конкретно мені подобається зосередження уваги на FRP у заході, що називається Projections. Чи є щось подібне в Кафці / Самзі?
CMCDragonkai

4
Мене також цікавить питання @ Geert-Jan до Джея. Кафка не підходить для фактичної трансакційної сторони подій, через те, що потрібен потік подій (теми) на сукупність доменів (думаю, мільйони). Однак, він ідеально підходить для того, щоб події подавались у нього, наприклад, GetEventStore. Але це буде працювати лише з нескінченно затриманими подіями (у нашому випадку), окрім кількох коротких коментарів, це не здається підтримуваним випадком використання Кафки? Я тут помиляюся? Наприклад, Самза припускає, що існує лише два сценарії: утримання на основі часу або збереження на основі ключів. Є й інші ..
Стівен Дрю

3
@eulerfx Якщо припустити, що ми хотіли б використовувати Kafka як сховище для системи, що спричиняє події, як слід реалізувати оптимістичне блокування / одночасність?
Кшиштоф Браницький

51

Я продовжую повертатися до цієї якості. І я не знайшов відповіді наявними досить нюансованими, тому додаю цю.

TL; DR. Так чи ні, залежно від використання джерела події.

Є два основні види систем подій, про які я знаю.

Процесори подальших подій = Так

У такій системі події відбуваються в реальному світі і реєструються як факти. Такі як складова система для відстеження піддонів продуктів. В основному конфліктних подій немає. Все вже сталося, навіть якщо воно було неправильним. (Тобто піддон 123456 поставлений на вантажівку A, але був запланований на вантажівку B.) Потім згодом факти перевіряються на винятки за допомогою механізмів звітності. Kafka, здається, добре підходить для такого роду додатків для обробки подій вниз,

У цьому контексті зрозуміло, чому люди Кафки виступають за це як рішення подій, що займається пошуком подій. Оскільки він досить схожий на те, як він уже використовується, наприклад, потоки клацань. Однак люди, які використовують термін "Подія подій" (на відміну від потокової обробки), ймовірно, посилаються на друге використання ...

Джерело правди, кероване додатком = Ні

Цей вид програми оголошує власні події в результаті запитів користувачів, що проходять через бізнес-логіку. Кафка не спрацьовує в цьому випадку з двох основних причин.

Відсутність ізоляції сутності

Цей сценарій потребує можливості завантаження потоку подій для конкретного об'єкта. Загальною причиною цього є побудова моделі перехідного запису для бізнес-логіки, яка використовується для обробки запиту. Робити це в Кафці недоцільно. Використання теми за особою може дозволити це, за винятком випадків, коли це не для початківців, коли може бути тисячами або мільйонами організацій. Це пов'язано з технічними обмеженнями в Kafka / Zookeeper.

Однією з головних причин використовувати перехідну модель запису таким чином - це зробити зміни в логіці бізнесу дешевими та зручними для розгортання.

Використовувати тему за типом рекомендується замість Kafka, але це вимагатиме завантаження подій для кожного об'єкта цього типу просто для отримання подій для однієї сутності. Оскільки за позицією журналу ви не можете визначити, які події належать до якої сутності. Навіть використовуючи Знімки, щоб почати з відомого положення журналу, це може бути значна кількість подій, які слід провести.

Відсутність виявлення конфлікту

По-друге, користувачі можуть створювати умови перегонів за рахунок одночасних запитів проти одного і того ж об'єкта. Зберігати конфліктні події та вирішувати їх після факту може бути дуже небажано. Тому важливо вміти запобігати конфліктним подіям. Щоб масштабувати завантаження запитів, звичайно використовувати служби без громадянства, запобігаючи конфліктам запису за допомогою умовного запису (записуйте лише якщо останньою подією сутності було #x). Aka Оптимістична паралельність. Кафка не підтримує оптимістичну одночасність. Навіть якби він підтримував його на рівні теми, для ефективності його потрібно було б зробити аж до рівня сутності. Щоб використовувати Kafka та запобігати конфліктним подіям, вам потрібно буде використовувати видатний, серіалізований автор на рівні програми. Це значна архітектурна вимога / обмеження.

Додаткова інформація


Оновлення за коментарем

Коментар видалено, але питання було на кшталт: що тоді люди використовують для зберігання подій?

Схоже, більшість людей здійснюють власну реалізацію пам’яті для подій поверх існуючої бази даних. Для нерозподілених сценаріїв, таких як внутрішні бек-енди або окремі продукти, добре задокументовано, як створити магазин подій на базі SQL. А ще існують бібліотеки, окрім баз даних різного роду. Існує також EventStore , який побудований для цієї мети.

У розподілених сценаріях я бачив пару різних реалізацій. Проект Jet's Panther використовує Azure CosmosDB з функцією Змінити подачу для сповіщення слухачів. Ще одна подібна реалізація, про яку я чув про AWS, використовує DynamoDB з функцією Streams для сповіщення слухачів. Ключем розділу, ймовірно, повинен бути ідентифікатор потоку для найкращого розподілу даних (щоб зменшити кількість перевищення резервів). Однак повне відтворення через потоки в "Динамо" є дорогим (читати та дорожче). Таким чином, ця імпульс також була налаштована для "Динамо", щоб скидати події на S3. Коли новий слухач приходить в Інтернеті, або наявний слухач хоче повну повтор, він буде читати S3, щоб наздогнати його першим.

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

Кафка все ще дуже корисна в розподілених сценаріях. Розкривати події кожної служби іншими службами - це нетривіальна проблема. Магазин подій не побудований для цього зазвичай, але саме це робить Кафка добре. Кожна служба має власне внутрішнє джерело істини (це може бути зберігання подій чи іншим способом), але слухає Кафку, щоб знати, що відбувається "зовні". Служба може також розміщувати події в Кафці, щоб інформувати «зовні» про цікаві речі, які робила служба.


1
@Dominik я згадував EventStore в розділі "Оновлення" (2-й абзац). Я повернусь назад і зв’яжу. Я спробував це, і він має вражаючі парфуми. Для нашої невеликої команди наразі не введення іншої бази даних вважалося важливішим, отже, Postgres (який також використовується для перегляду). Цілком можливо, що ми перейдемо до EventStore у майбутньому або у майбутні продукти.
Кейсі

2
@KaseySpeakman Теми не збігаються з розділами. Тема має один або кілька розділів. Гарантовано, що в будь-який момент в розділі буде лише один споживач на групу. Розділіть ваші сутності таким чином, щоб цим скористатися. Вам не потрібна тема на сутність або навіть розділ на сутність. Вам просто потрібно розділити їх таким чином, щоб гарантувати, що всі команди, адресовані одній суті, йдуть на один і той же розділ.
Ендрю Ларссон

1
@KaseySpeakman Багато організацій можуть ділитися одним розділом. Хто сказав, що вам потрібно завжди завантажувати стан сутності безпосередньо з магазину подій, відтворюючи події? Є й інші способи досягти тієї самої концепції, не суворо слідуючи послідовному виконанню Грега Янга.
Ендрю Ларссон

1
@AndrewLarsson Якщо ви не розділите на сутність, то як ви будете запобігати конфліктним подіям на рівні сутності? Оскільки ми повернулися повним колом до конфліктних ситуацій, то, можливо, вам слід опублікувати власну статтю на носії або щось про те, як ви використовували Kafka для пошуку подій (а не потокової обробки) у виробництві. Принцип роботи з розділом за типом та без контролю за сумісністю на рівні сутності. Я б прочитав це, і я навіть не кохав би вас у коментарях, якби я не погодився.
Кейсі

2
@KaseySpeakman Використовувати Кафку таким чином непросто. Але якщо ви знаходитесь в масштабі, де ви серйозно розглядали CQRS та події Sourcing, то ви знаходитесь в масштабі, де ви не можете дозволити собі робити речі легким способом. Ваша модель одночасності безпосередньо впливає на ваш масштаб - не вибирайте її довільно. Крім того, HTTP не є надійним транспортом, і, знову ж таки, якщо ви в такому масштабі, ви не можете дозволити собі витратити час на вирішення втрачених та / або дублюючих проблем із повідомленнями. Це все можна вирішити, використовуючи Kafka між клієнтом та командним процесором, але так, це відбувається ціною складності.
Ендрю Ларссон

20

Ви можете використовувати Kafka як магазин подій, але я не рекомендую цього робити, хоча це може виглядати як вдалий вибір:

  • Kafka гарантує лише принаймні один раз доставку, і у магазині подій є дублікати, які неможливо видалити. Оновлення: Тут ви можете прочитати, чому так важко з Кафкою та деякі останні новини про те, як нарешті досягти такої поведінки: https://www.confluent.io/blog/exactly-once-semantics-are-possible-heres-how -apache-kafka-do-it /
  • Через незмінність немає способу маніпулювати сховищем подій, коли додаток розвивається і події потрібно трансформувати (звичайно, є такі методи, як оновлення, але ...). Колись можна сказати, що вам ніколи не потрібно перетворювати події, але це неправильне припущення, може виникнути ситуація, коли ви створюєте резервну копію оригіналу, але ви оновите їх до останніх версій. Це дійсна вимога в архітектурах, керованих подіями.
  • Немає місця для збереження знімків об'єктів / агрегатів та повторного відтворення стане повільніше та повільніше. Створення знімків - це обов'язково для довгострокової перспективи для магазину подій.
  • Дані розділи Kafka розподілені, і їх важко керувати та створювати резервні копії порівняти з базами даних. Бази даних просто простіші :-)

Отже, перед тим, як зробити свій вибір, подумайте двічі. Магазин подій як комбінація інтерфейсів прикладного рівня (моніторинг та управління), магазин SQL / NoSQL та Kafka як брокер є кращим вибором, ніж залишати Kafka виконувати обидві ролі для створення повноцінного повного рішення.

Магазин подій - це комплексний сервіс, який вимагає більше, ніж те, що може запропонувати Kafka, якщо ви серйозно ставитесь до застосування джерел подій, CQRS, Sagas та інших моделей у архітектурі, керованій подіями, і залишаєтеся високими.

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

Будь ласка, подивіться на сторінку відкритого коду мікросервісів eventuate.io, щоб дізнатися більше про потенційні проблеми: http://eventuate.io/

Оновлення станом на 8 лютого 2018 року

Я не включаю нову інформацію з коментарів, але погоджуюся з деякими з цих аспектів. Це оновлення детальніше про деякі рекомендації щодо платформи, керованої подіями мікросервісу. Якщо ви серйозно ставитесь до надійної конструкції мікросервісу та найвищої можливої ​​продуктивності в цілому, я дам вам кілька підказок, які можуть вас зацікавити.

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

Якщо вам цікаво ефективність, ви можете порівняти себе з існуючим набором тестів. https://github.com/networknt/microservices-framework-benchmark

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

  2. Для магазину подій я рекомендую покращене розширення Postgresql під назвою TimescaleDB, яке фокусується на високопродуктивній обробці даних тимчасових журналів (події є тимчасовими серіями) у великому обсязі. Звичайно, CQRS, пошук подій (функції повторення тощо) вбудовані у фреймворк light4j, який використовує Postgres як низький обсяг пам’яті.

  3. Для обміну повідомленнями спробуйте переглянути чергову хроніку, карту, двигун, мережу. Я маю на увазі позбутися цього старомодного брокера, орієнтованого на рішення, та перейдіть із системою мікрообміну повідомленнями (вбудованою). Черга на хроніку насправді навіть швидша за Кафку. Але я погоджуюся, що це не все в одному рішенні, і вам потрібно зробити якусь розробку, інакше ви перейдете і придбаєте Enterprise версію (платну). Врешті-решт, зусилля, спрямовані на те, щоб створити з хроніки, ваш власний шар обміну повідомленнями буде виплачено, знявши тягар підтримки кластеру Kafka.


Цікавий вид. Хочете детальніше розглянути кілька моментів? > Kafka гарантує лише принаймні один раз доставку, і у магазині подій є дублікати, які неможливо видалити. Ви, здається, маєте на увазі, що існує така річ, як рівно один раз пологи. afaik (і я майже в цьому впевнений) у розподіленій системі такого немає. 2) Що стосується вашого пункту 2: класична школа (події пошуку / dddd) вважає, що події за своєю суттю незмінні. Тобто вони трапляються, не можна змінити минуле. Яке власне використання - випадок їх зміни в ретроспективі? Дякую!
Герт-Ян

1.) Hazelcast, щоб забезпечити, що кожне повідомлення буде оброблене один раз і лише один раз. 2.) Мені не подобається щось подібне до _V2 у службовому коді, тож ви або зробите резервну копію для архівування та відтворення старих подій у їхніх нових версіях (у вас все ще є оригінальна правда), або ви можете приховати / вбудувати цю функціональність безпосередньо у Event Зберігайте функціональність знімків, тому є одна точка оновлення -> магазин подій. Які ваші рішення щодо цього?
kensai

1) принаймні один раз + ідентифікація споживача. Тобто: перевірте, чи подію вже бачили. Якщо так, пропустіть. Або ще краще, зробіть самовпевнені дії. Звичайно, це не завжди можливо. 2) Я ніколи не стикався з необхідністю проводити версії подій. Я завжди розглядаю самі події як джерело істини і включаю всю інформацію, яка мені коли-небудь знадобиться. Роблячи це, я ніколи не стикався з ситуацією, коли мені потрібна інша структура подій та / або дані про подію. Але, можливо, ymmv. Цікавить слухати, у яких ситуаціях вам насправді знадобиться оновити події.
Герт-Ян

1.) може бути вибором. 2.) тоді ваші структури даних були ідеальними з самого початку :-) пощастило вам, ха-ха. Мені це може і не знадобитися в моєму поточному проекті, але я будую цілу платформу на вилках eventuate.io, об'єднаних з деякими високоефективними підходами JEE, взяті лише з light eventuate 4j ... вся ця дискусія не є місцем для коментарів щодо stackoverflow , але якщо вас цікавить дайвінг глибше, я рекомендую цю статтю: leanpub.com/esversioning/read
Kensai

1
Kafka підтримує рівно один раз доставку зараз, до речі. Оновлення кулі 1
OneCricketeer

8

Так, ви можете використовувати Kafka як магазин подій. Це працює досить добре, особливо з впровадженням Kafka Streams , що забезпечує рідний спосіб переробки ваших подій у накопичений стан, який ви можете запитувати .

Щодо:

Можливість відтворення журналу подій, що дозволяє новим абонентам зареєструватися в системі після факту.

Це може бути хитро. Я детально висвітлював це тут: https://stackoverflow.com/a/48482974/741970


0

Так, Kafka добре працює в моделі пошуку подій спеціально CQRS, однак ви подбаєте, встановлюючи TTL для тем і завжди майте на увазі, що Kafka не розроблений для цієї моделі, проте ми можемо дуже добре її використовувати.


0

Я думаю, ви повинні подивитися на рамки аксонів разом з їх підтримкою для Kafka

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.