Frog Proger 10 декабря 2024

💾 CDC vs Outbox: как решить проблему двойной записи в распределенной системе

Когда в системе нет встроенной поддержки транзакций для обеспечения согласованности, приходится искать альтернативные решения. Сравниваем два популярных подхода к обеспечению целостности данных в распределенных системах.
💾 CDC vs Outbox: как решить проблему двойной записи в распределенной системе

Проблема двойной записи возникает, когда необходимо выполнить две или более операции в разных системах или базах данных, которые должны оставаться согласованными, а в системе при этом нет встроенной поддержки транзакций для обеспечения согласованности. Классический пример – когда нужно записать данные в базу данных и опубликовать событие в брокере событий. Если приложение завершается аварийно после завершения транзакции в базе данных, но до того, как событие будет опубликовано, это приведет к несогласованности, поскольку операции происходят в отдельных системах, и транзакции в этом контексте недоступны:

Если не предусмотреть обработку таких ситуаций, двойная запись неизбежна
Если не предусмотреть обработку таких ситуаций, двойная запись неизбежна

Существует два стандартных решения для обработки этой проблемы – захват изменения данных и паттерн Outbox.

Захват изменения данных (CDC)

Захват изменения данных (CDC, Change Data Capture) – это метод, при котором используются журналы транзакций базы данных, содержащие записи обо всех изменениях данных. CDC-инструменты могут читать эти журналы, надежно захватывая все операции вставки, обновления или удаления. Эти данные затем передаются в другие системы, например брокеры сообщений, чтобы обеспечить информирование остальных систем о произошедших изменениях:

CDC-инструменты обнаруживают изменения в почти реальном времени
CDC-инструменты обнаруживают изменения в почти реальном времени

Есть два основных способа реализовать захват изменений:

  • Нативные CDC-функции базы данных. Многие базы данных имеют встроенные CDC-возможности, например, binlog в MySQL или логическая репликация в PostgreSQL. Эти решения обычно проще интегрировать с приложением.
  • Инструменты сторонних производителей. Например, опенсорсный Debezium может подключаться к различным базам данных и отлично работает в разнородных системах.

Преимущества CDC:

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

Недостатки:

  • Настройка и управление инструментами CDC добавляет операционную сложность.
  • Хотя CDC обычно захватывает изменения в реальном времени, небольшая задержка между моментом фиксации изменения и его публикацией в нисходящей части системы все-таки возможна. Это важно учитывать, если ваше приложение требует минимальной задержки.
  • Для того чтобы CDC-пайплайн оставался работоспособным, необходимо обеспечить надежный мониторинг и обработку экстремальных случаев (изменения схемы, перезапуск базы данных и т. п.)
💻 Библиотека программиста
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека программиста»

Паттерн Outbox

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

Приложение изменяет данные в базе и одновременно записывает событие в таблицу Outbox в рамках одной транзакции
Приложение изменяет данные в базе и одновременно записывает событие в таблицу Outbox в рамках одной транзакции

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

Варианты реализации паттерна Outbox:

  • Механизм опроса (поллинг). Фоновый процесс регулярно проверяет таблицу Outbox на новые записи и публикует их.
  • Чтение журналов транзакций. Воркер может следить за изменениями в журнале транзакций, чтобы обрабатывать новые записи в таблице Outbox (этот метод используется реже).

Преимущества паттерна Outbox:

  • Атомарность. Поскольку изменения данных и запись события происходят в одной транзакции, либо обе операции успешны, либо обе откатываются. Это исключает несогласованность.
  • Гарантированная публикация. Даже если приложение или воркер выйдет из строя, событие не потеряется – асинхронный процесс обработает его позже, сохраняя согласованность.
  • Основная логика приложения остается простой, так как публикация событий отделена и происходит асинхронно.

Недостатки:

  • Требуется организовать управление таблицей Outbox – реализовать запуск воркера или фоновой задачи для проверки и публикации событий.
  • Увеличение таблицы Outbox может привести к снижению производительности. Нужно настроить периодические очистки.
  • В зависимости от частоты опроса таблицы или расписания фонового процесса, между фиксацией данных и публикацией события может быть задержка.
  • Необходимо учитывать сценарии отказов, например, повторную обработку событий.

Подведем итоги

Проблема двойной записи возникает в распределенных системах, когда данные необходимо одновременно сохранить в нескольких хранилищах или базах данных, но нет возможности сделать это атомарно, в рамках единой неделимой транзакции. Самые популярные способы решения этой проблемы – инструменты для захвата изменений и паттерн исходящих событий Outbox. Они усложняют архитектуру системы, зато сводят к минимуму последствия сбоев приложения и гарантируют согласованность данных.

***

С какими проблемами синхронизации данных вы сталкивались в своих проектах и как их решали?

Комментарии

ВАКАНСИИ

Добавить вакансию
Разработчик C++
Москва, по итогам собеседования

ЛУЧШИЕ СТАТЬИ ПО ТЕМЕ