Postgres и Kafka, часть 2



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



Сложность в том, что это БД и месседж брокер — разные сервисы и обеспечить их атомарную работу сложно. Есть 3 подхода к решению проблемы:

1️⃣ Убираем кафку

2️⃣ Убираем БД

3️⃣ Добавляем координатор



Первый пункт уже рассмотрели, в этом посте обсудим варианты 2 и 3.



Вариант 2: убираем БД



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

public void saveOrder(…) {

kafkaTemplate.send("orders", new OrderCreated(…));

}



Сервис прекращает быть "главным" и становится обычным потребителем событий. Получает сообщение — делает запись в БД. Другие сервисы тоже получают сообщение и что-то делают.



В случае проблем с сетью стратегия сервиса такая:

1️⃣ Отправь сообщение, пока не получится

2️⃣ Получив сообщение, пиши в БД, пока не получится



Вместо координации двух компонентов мы добиваемся исполнения гарантий на каждом шаге.



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

БД не становится узким местом

Самое долгое время между отправкой сообщения и сохранением в БД среди всех вариантов

Возможна неконсистентность данных и нарушение порядка изменений

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



Если развивать вариант "убираем БД" дальше, придём к Event Sourcing. Это подход, в котором основной источник данных — события, а не БД. Но это уже другая история🧚‍♀️



Вариант 3: добавляем координатор



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



🔸 В базе данных что-то меняется

🔸 Координатор обнаруживает это изменение

🔸 Транслирует изменение в кафку



База может записывать изменения в отдельную таблицу с помощью триггера, materialized view или логической репликации. Координатор может смотреть на таблицу, а может читать логи БД.



Всё это многообразие объединяется термином Change Data Capture (CDC).



Чёткие зоны ответственности. Postgres хранит данные, Kafka шлёт сообщения, координатор координирует

Огромная гибкость, множество вариантов реализации

Возможна дупликация сообщений

Сложность системы увеличивается

Теперь у нас не 2 компонента (БД и Kafka), а гораздо больше. Больше инстансов, настроек, мониторинга и потраченных человеко-часов.



Реализация



Большинство инструментов базируются на Kafka Connect, в том числе популярная CDC система Debezium. Здесь и остановимся, пока всё просто и понятно:) Оценить, насколько глубока кроличья нора, можно в документации Debezium.



Резюме



Для слаженной работы Postgres и Kafka есть три основных подхода. Они отличаются

✍️ гарантиями доставки сообщения

✍️ нагрузкой на БД

✍️ временем между сохранением в БД и доставкой сообщения

✍️ сложностью

✍️ дополнительными возможностями



Выбираем решение по приоритетам, требованиям и нагрузке и ставим огоньки хорошему посту🔥