Ключевые выводы
- Event sourcing для триггерных рассылок — архитектурный подход, при котором каждое изменение состояния системы фиксируется как неизменяемое событие в журнале
- Этот паттерн особенно ценен в CDP, потому что даёт полный аудит-след, возможность переигрывать события и точную замену любых пропущенных коммуникаций
- Альтернатива — CRUD-подход с обновлением состояния «на месте», который проще, но не позволяет восстановить хронологию решений
- Главные риски event sourcing: рост объёма данных, сложность отладки, eventual consistency между event store и проекциями
- Решение применимо для CDP с 5+ млн профилей и плотным engagement-слоем — для меньших проектов overhead не оправдан
Event sourcing для триггерных рассылок — архитектурный паттерн, который превращает CDP из «базы текущего состояния» в «журнал всех решений и действий». При этом подходе каждое событие — клик, покупка, вход в приложение, отправка коммуникации — записывается как неизменяемая запись с timestamp и контекстом, и состояние системы вычисляется как проекция этого журнала.
В этой статье разберём, когда event sourcing для триггерных рассылок оправдан, а когда — преждевременная оптимизация, и как его правильно реализовать в on-prem CDP.
Что такое event sourcing в контексте CDP
Стандартный подход в CDP: есть таблица customer_profiles, в ней колонка last_purchase_date обновляется каждый раз, когда происходит покупка. Если завтра нужно узнать, что у клиента было «вчера в 18:00» — невозможно: данные перезаписаны.
Event sourcing работает иначе: в системе есть журнал событий (event store), и каждая покупка — это новая запись в нём. Состояние клиента (например, last_purchase_date) — это проекция, рассчитанная из событий до конкретной точки времени.
Преимущество в одном предложении: ничего не теряется, всё можно переиграть, точное состояние любой точки времени восстановимо.
Зачем event sourcing для триггерных рассылок
Точное воспроизведение пропущенных кампаний
В реальной эксплуатации регулярно случается: новый сценарий запустили на 100 тысяч клиентов, но первая 10% волна получила некорректное сообщение. С event sourcing достаточно отыграть события и переотправить только тем, у кого статус доставки был неуспешным. Без event sourcing — приходится перепосылать всем 100 тысячам или ничего не делать.
Точный аудит-след для compliance
На запросе Роскомнадзора «покажите, какие коммуникации получал клиент X в марте 2025» с event sourcing ответ — выгрузка из event store за нужный период. Без event sourcing — реконструкция по логам разных систем с пробелами.
Гибкость в развитии сценариев
Появилась новая бизнес-метрика — «среднее время между двумя последними покупками». В CRUD-подходе её нужно начинать считать с момента введения. С event sourcing — отыгрываем все события и получаем метрику для всей истории.
Корректная обработка опоздавших событий
Событие «клик по email» пришло с опозданием в 2 дня (сетевые проблемы у мобильного приложения). В CRUD это создаёт некорректное состояние. В event sourcing — событие просто добавляется в нужное место хронологии.
Архитектура event sourcing для CDP
Event store — основной журнал
Append-only хранилище всех событий. Технически реализуется через:
- Kafka с retention=infinite — стандартный подход, но требует управления партициями
- Apache Pulsar — современная альтернатива с tiered storage
- PostgreSQL с partitioning по дате — для проектов с объёмом до 100 млн событий
- Cassandra или ClickHouse — для очень больших объёмов
Проекции — текущее состояние
Из event store рассчитываются проекции — таблицы текущего состояния, которые читают приложения. Например:
- Profile projection: текущие данные профиля клиента
- Segment projection: к каким сегментам относится клиент сейчас
- Communication projection: какие коммуникации получил клиент
- Loyalty projection: текущий статус, баллы, кэшбэк
Каждая проекция строится отдельно, может пересчитываться независимо, может быть удалена и пересоздана из event store.
Command-query separation (CQRS)
Event sourcing обычно идёт в паре с CQRS — разделением операций записи и чтения. Команды (например, «отправить email») создают новые события в event store. Запросы (например, «какой статус сегмента у клиента X») читают из проекций.
Реализация триггерных рассылок поверх event sourcing
- Событие «купил товар» приходит в event store
- Сценарный движок подписан на этот тип события и вычисляет, нужна ли рассылка
- Команда «отправить email» создаёт событие email_sent_command
- Worker отправки подписан на email_sent_command, выполняет отправку через SMTP
- Событие «email доставлен»/«email открыт» приходит обратно в event store
- Проекция communications обновляется и показывает текущий статус коммуникации
Каждый шаг — это отдельное событие. Если на шаге 4 произошла ошибка отправки, можно retry без потери контекста: событие email_sent_command не теряется, оно остаётся в event store с pending-статусом.
Когда event sourcing оправдан
- База клиентов 5+ млн профилей с активным engagement
- Compliance-требования к аудит-следу всех решений и действий
- Сценарии с возможностью «переиграть» пропущенные кампании или ошибки
- Команда с опытом распределённых систем (3-5 senior-инженеров)
- Желание иметь полную хронологию состояний для product analytics
Когда event sourcing — преждевременная оптимизация
- База клиентов меньше 1 млн профилей — overhead не оправдан
- Команда без опыта event-driven архитектур
- Простые маркетинговые задачи без compliance-аудита
- Жёсткие требования к latency запросов (event sourcing добавляет 50-200мс)
- Отсутствие потребности в repeatability и reproducibility
Главные подводные камни
Рост объёма данных
Событий в event sourcing намного больше, чем строк в CRUD. Проект с 5 млн профилей и 10 событий/день/клиент даёт 50 млн новых событий в день, 1.5 млрд в месяц. Хранить такие объёмы без партиционирования и архивирования — экономически невыгодно.
Eventual consistency
Между событием в event store и обновлением проекции — секунды или минуты. UI и автоматизация должны учитывать, что состояние «отстаёт» от реальности. В простых CRUD-системах этого нет.
Сложность отладки
В event sourcing для понимания «почему клиент попал в такой сегмент» нужно посмотреть всю цепочку событий — это сложнее, чем посмотреть текущую запись в БД. Требуются специальные инструменты — event replay, debug-проекции.
Schema evolution
Поскольку события неизменяемы, изменение схемы события — серьёзная задача. Старые события остаются в старом формате, новые события в новом, и проекции должны работать с обоими. Часто требуется upcasting — программная конвертация старых событий в новый формат при чтении.
Стек инструментов
| Слой | Российские варианты | Open source |
|---|---|---|
| Event store | Yandex MDB Kafka, VK Cloud Kafka | Apache Kafka, Pulsar, EventStoreDB |
| Stream processing | — | Kafka Streams, Flink, Spark |
| Проекции | PostgreSQL, ClickHouse | Cassandra, Elasticsearch |
| CQRS-фреймворк | Кастомная разработка | Axon Framework, EventStoreDB |
| Мониторинг | — | Prometheus, Grafana |
FAQ о event sourcing для триггерных рассылок
Можно ли совместить event sourcing с outbox pattern?
Да, и это часто оптимальная комбинация. Event sourcing — для журнала бизнес-событий, outbox pattern — для гарантированной доставки команд между сервисами. Подробнее об outbox pattern — в нашем материале по архитектуре триггерных рассылок без Kafka.
Сколько стоит event sourcing-инфраструктура?
Минимум 3-5 млн ₽ дополнительно к стандартной CDP-смете на инфраструктуру (Kafka-кластер, расширенное хранилище) и 2-3 млн ₽ на разработку базовой архитектуры. Для среднего проекта это +20-30% к бюджету.
Что такое snapshot-pattern в event sourcing?
Это оптимизация: периодически сохраняется текущее состояние агрегата (например, профиля клиента), и при пересчёте проекции используется ближайший snapshot плюс события после него. Это сокращает время восстановления состояния с минут до секунд.
Можно ли использовать event sourcing только для части системы?
Да, и это часто разумный подход. Например, event sourcing для коммуникаций и сегментации, а CRUD — для базовых данных профиля. Гибридная архитектура снижает риски и позволяет получить преимущества event sourcing там, где они наиболее ценны.
Как тестировать event sourcing-систему?
Через сценарии с заданным набором событий и проверкой результирующего состояния проекций. Важно покрывать тестами не только happy path, но и опоздавшие события, дубликаты, события в неожиданном порядке. Это требует специализированных тестовых фреймворков и часто — отдельной test-роли в команде.
Что в итоге
Event sourcing для триггерных рассылок — мощный архитектурный паттерн, который даёт CDP возможности аудита, repeatability и эволюции, недостижимые в CRUD-подходе. Цена — рост сложности, объёмов данных и команды.
Применять стоит для проектов от 5 млн профилей с серьёзными compliance-требованиями. Для меньших — гибридный подход или классический CRUD с подробным логированием.
Готовы помочь оценить применимость event sourcing к вашему контексту и спроектировать архитектуру — обсудим в формате архитектурной консультации.