Перейти к содержанию
Innovialabs

Change Data Capture (CDC) и Debezium: как стримить изменения

Продвинутое3 мин

Коротко

CDC на основе журнала читает журнал транзакций базы и превращает каждую вставку, изменение и удаление в событие; Debezium делает это для PostgreSQL, MySQL и других СУБД и публикует события в Kafka, поэтому хранилище, поисковый индекс и кеш синхронизируются за секунды, а не после следующего пакетного запуска.

Коротко

Change Data Capture (CDC) — захват каждого изменения в базе и доставка его в другие системы. Самый надёжный вариант — CDC на основе журнала: вместо запросов к таблицам он читает журнал транзакций самой базы, тот же, что используется для репликации.

Debezium — open-source платформа для CDC. Она подключается к журналу, превращает каждое изменение строки в событие и обычно публикует его в Apache Kafka, откуда его может читать любое число потребителей.

Три способа захватывать изменения

ПодходКак работаетСлабые места
ЗапросыОпрос WHERE updated_at > last_runНе видит физических удалений, зависит от надёжного timestamp, нагружает базу
ТриггерыТриггеры пишут изменения в таблицу аудитаЛишняя запись в каждой транзакции, триггеры надо поддерживать
ЖурналЧтение WAL (PostgreSQL) или binlog (MySQL)Нужен доступ к журналу и настройка, больше компонентов

CDC на основе журнала видит каждое закоммиченное изменение, включая удаления, в порядке коммитов и почти не добавляет нагрузки на сами таблицы.

Как работает Debezium

Чаще всего Debezium запускается как source-коннектор в Kafka Connect. Для каждой базы он:

  1. Делает необязательный начальный снимок выбранных таблиц.
  2. Переходит к потоковому чтению журнала: в PostgreSQL через слот логической репликации (плагин pgoutput), в MySQL через binlog в формате ROW.
  3. Пишет события в топики Kafka, обычно по топику на таблицу с именем вида prefix.schema.table.
  4. Сохраняет позицию (offset), чтобы продолжить после перезапуска.

Каждое событие содержит состояние строки до и после изменения, тип операции (c создание, u изменение, d удаление, r чтение снимка) и метаданные источника — транзакцию и время.

Подготовка PostgreSQL:

# postgresql.conf
wal_level = logical

Минимальная регистрация коннектора в Kafka Connect:

{
  "name": "shop-connector",
  "config": {
    "connector.class": "io.debezium.connector.postgresql.PostgresConnector",
    "plugin.name": "pgoutput",
    "database.hostname": "db",
    "database.port": "5432",
    "database.user": "debezium",
    "database.password": "${file:/secrets/db.properties:password}",
    "database.dbname": "shop",
    "topic.prefix": "shop",
    "table.include.list": "public.orders,public.customers"
  }
}

Заведите для Debezium отдельного пользователя только с нужными правами на репликацию и чтение.

Доставка изменений дальше

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

  • Хранилище данных (ClickHouse, BigQuery, Snowflake и другие) — через sink-коннекторы или потоковую обработку.
  • Поисковый индекс, например Elasticsearch, — обновляется сразу после изменения товара.
  • Инвалидация кеша в Redis.
  • Другие микросервисы, которые реагируют на бизнес-события.

Если Kafka не нужна, Debezium Server умеет отправлять события напрямую в другие брокеры сообщений, а для JVM-приложений есть встраиваемый движок.

CDC против пакетного ETL для синхронизации хранилища

Пакетный ETLCDC на основе журнала
СвежестьПосле следующего запускаПочти в реальном времени
УдаленияЧасто теряютсяФиксируются
Нагрузка на источникТяжёлые запросы во время запускаЧтение журнала
СложностьНизкая: планировщик и SQLВыше: Kafka, коннекторы, мониторинг
История измененийТолько итоговое состояниеКаждое промежуточное изменение

Пакетный ETL по-прежнему хороший выбор, если достаточно свежести раз в день или раз в час, объём данных умеренный и в команде нет потоковой инфраструктуры. CDC окупается, когда отчёты должны быть свежими, таблицы большие или одни и те же изменения нужны нескольким системам.

Подводные камни

  • Слоты репликации удерживают WAL. Если коннектор остановился, PostgreSQL хранит WAL для слота, и диск может переполниться. Следите за отставанием слота и настройте алерты.
  • Доставка at-least-once. После сбоев события могут повторяться. Делайте потребителей идемпотентными, например upsert по первичному ключу.
  • Изменения схемы должны обрабатывать потребители; рассмотрите schema registry.
  • Порядок гарантирован в пределах ключа (партиции Kafka), а не глобально.
  • Внутренние таблицы раскрывают структуру. Для событий, предназначенных другим сервисам, паттерн outbox (отдельная таблица событий, которую захватывает CDC) даёт стабильный контракт.

Частые вопросы

Нет, но Kafka Connect — самая распространённая схема. Debezium Server и встраиваемый движок позволяют доставлять события в другие системы без Kafka.

Поможем с этим

Если хотите не разбираться самим, а получить результат — этим мы занимаемся каждый день.

Обсудить проект

Читайте также

Есть идея или задача? Расскажите нам

Ответим в течение рабочего дня и предложим решение. Консультация бесплатная.