Learning Platform
Глоссарий Troubleshooting
Урок 15.01 · 22 мин
Средний
Flink CDCDebeziumMySQLChange Data CaptureSnapshotBinlog

Что такое Flink CDC

CDC — это Change Data Capture, технология чтения изменений из транзакционной БД (MySQL binlog, Postgres logical replication, MongoDB oplog) в виде потока событий. Долгое время de-facto-стандартом был Debezium + Kafka Connect: Debezium коннекторы запускаются как Kafka Connect tasks, читают binlog/WAL, публикуют в Kafka. Дальше — обычный Kafka consumer.

Flink CDC — это альтернативная архитектура: тот же самый Debezium engine, но embedded прямо в Flink source task. Никаких отдельных Kafka топиков для CDC, никакого Kafka Connect-кластера. В этом уроке разберём, как это устроено, чем отличается от классического подхода и когда что выбирать.


Классический CDC: Debezium + Kafka Connect

Канонический pipeline в индустрии 2017-2022:

Архитектура Debezium
MySQL -> Debezium connector (в Kafka Connect) -> Kafka topic -> Flink/Spark consumer

Debezium читает MySQL binlog (или Postgres WAL, MongoDB oplog), парсит, преобразует в события before/after JSON или Avro, публикует в Kafka топик dbserver1.inventory.orders. Любой downstream-consumer (Flink job, Spark, аналитика) подписывается на этот топик.

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

  • Reuse — один CDC source, много consumers. Каждая команда читает топик независимо.
  • Buffering — Kafka работает буфером: если downstream упал, Kafka хранит события до его восстановления (зависит от retention).
  • Standard tooling — Debezium UI, Confluent Connect API для управления, мониторинг через Kafka Connect REST.

Недостатки:

  • Лишний компонент — Kafka Connect кластер надо deploy’ить, мониторить, патчить.
  • Сериализация -> десериализация — события Debezium-сериализуется в Kafka, потом Flink десериализует. Это CPU и latency.
  • Snapshot bottleneck — initial snapshot большой таблицы (миллиарды строк) делается одним Connect task. На таблице 1B rows — может занять дни.
  • Координация schema — schema evolution Debezium и downstream-приложений не всегда совпадают.

Flink CDC переворачивает архитектуру: Debezium engine внутри Flink source task. Нет Kafka Connect, нет промежуточного Kafka топика.

MySQL -> Flink source task (with embedded Debezium) -> Flink pipeline -> sink
CREATE TABLE orders_cdc (
  order_id BIGINT,
  customer_id BIGINT,
  amount DECIMAL(10, 2),
  status STRING,
  updated_at TIMESTAMP(3),
  PRIMARY KEY (order_id) NOT ENFORCED
) WITH (
  'connector' = 'mysql-cdc',
  'hostname' = 'mysql.internal',
  'port' = '3306',
  'username' = 'flink_cdc',
  'password' = '...',
  'database-name' = 'shop',
  'table-name' = 'orders',
  'server-id' = '5400-5404',
  'scan.incremental.snapshot.enabled' = 'true'
);

'connector' = 'mysql-cdc' подключает Flink source, который содержит Debezium engine для MySQL. Этот source делает две фазы:

  1. Snapshot — читает существующие строки таблицы и emit их как +I events.
  2. Streaming — переключается на binlog reader, emit insert/update/delete события.
Debezium+Kafka Connect vs Flink CDC
Two architectures for CDC

MySQL

MySQL primary с binlog enabled. Источник изменений для CDC.
binlog

Debezium + Kafka Connect

Debezium connector внутри Kafka Connect worker. Читает binlog одним task, парсит events, публикует в Kafka.
JSON/Avro

Kafka topic

Kafka topic dbserver1.shop.orders. Хранит CDC events. Любой consumer может subscribe.

Flink consumer

Flink job consumer'ит CDC events из Kafka. Десериализует, применяет логику.

MySQL

MySQL primary, тот же source.
binlog

Flink CDC source

Flink source task с embedded Debezium engine. Параллельный snapshot (multi-task), потом switch на binlog. Нет Kafka в середине.
changelog stream

Flink downstream

Flink pipeline — обычный downstream-operator (transform, join, sink). Изменения уже в Flink RowData формате.

Параллельный snapshot

Главное архитектурное преимущество Flink CDC над классическим Debezium — параллельный snapshot (с версии 2.0).

Классический Debezium snapshot:

  • Один Connect task делает SELECT * FROM table (или с offset chunks).
  • На таблице 1B rows × 200 bytes = 200 GB — SELECT * идёт часы или дни.
  • Если упал — начинает сначала (без incremental progress).

Flink CDC параллельный snapshot:

  • Source разделяется на N source subtasks.
  • Каждый subtask берёт chunk диапазона primary key (SELECT * WHERE id BETWEEN ? AND ?).
  • Snapshot N chunks делается параллельно.
  • При checkpoint state сохраняется per-chunk — incremental progress, recovery без full restart.
WITH (
  'connector' = 'mysql-cdc',
  ...
  'scan.incremental.snapshot.enabled' = 'true',     -- параллельный snapshot
  'scan.incremental.snapshot.chunk.size' = '8096',  -- размер chunk (rows)
  'chunk-key.even-distribution.factor.upper-bound' = '1000.0'
);

При parallelism=8 — 8 параллельных chunk readers. Snapshot 1B rows ускоряется в 8x.

TIP

Параллельный snapshot не только быстрее, но и resumable. При failure снапшота уже скачанные chunks не теряются — recovery начинается с unfinished chunks. На таблице 100M+ это огромное преимущество перед классическим Debezium, который начинал snapshot заново.


Exactly-once семантика

Flink CDC дает exactly-once для всего pipeline без двойной транзакции (которая нужна в Debezium+Kafka).

В классической схеме у вас две точки exactly-once:

  1. Debezium -> Kafka (через Debezium transaction metadata).
  2. Kafka -> Flink -> sink (через Flink checkpoint).

Между этими двумя — Kafka, и атомарность delivery не гарантируется (есть at-least-once случаи).

В Flink CDC:

  • Source с embedded Debezium emit events напрямую в Flink pipeline.
  • Flink checkpoint включает позицию binlog (gtid или log file + position).
  • При recovery Flink восстанавливает binlog position из checkpoint и continue.

Один checkpoint покрывает source -> pipeline -> sink. End-to-end exactly-once без посредников.


Когда использовать что

Debezium + Kafka Connect, когда:

  • Multiple consumers: один CDC source, 5 downstream-сервисов читают разными способами. Kafka буфер обязателен.
  • Buffering против outage: downstream может падать на дни, Kafka хранит CDC events до восстановления.
  • Существующий Kafka Connect deploy: уже работает, инфраструктура есть, добавить Debezium тривиально.
  • Schema registry первого класса: Confluent stack даёт хорошую schema-evolution-pipeline.

Flink CDC, когда:

  • Single consumer: один Flink job обрабатывает CDC. Зачем тогда промежуточный Kafka.
  • Big snapshots: таблицы миллиарды rows, параллельный snapshot — ключевая фича.
  • End-to-end exactly-once: важно атомарно перенести изменения из БД в downstream (Iceberg, Paimon, другая БД).
  • Минимум инфраструктуры: не хочется поддерживать отдельный Kafka Connect кластер.

Поддерживаемые БД

В Flink CDC проекте (на 2026):

  • MySQL — MySQL 5.6+, MariaDB. Параллельный snapshot.
  • PostgreSQL — Postgres 10+. Через logical decoding (pgoutput или wal2json).
  • MongoDB — через change streams (Mongo 4.0+, replica set required).
  • Oracle — через LogMiner. Поддержка чуть менее зрелая.
  • SQL Server — через CDC tables.
  • TiDB — через TiCDC.
  • OceanBase, PolarDB-X — китайские БД, активно поддерживаются.
  • DB2 — через DB2 transaction log.

Все коннекторы используют один и тот же Debezium engine под капотом, разница — в подключении к binlog/WAL/oplog конкретной БД.


Помимо source-коннекторов, Flink CDC проект (с версии 3.0) включает CDC pipeline framework — декларативный YAML-формат для CDC-pipelines:

source:
  type: mysql
  hostname: mysql.internal
  port: 3306
  username: flink_cdc
  password: ...
  tables: shop.orders, shop.products
  server-id: 5400-5404

sink:
  type: paimon
  catalog.warehouse: s3://lake/paimon/
  catalog.metastore: hive

pipeline:
  name: shop-cdc-to-paimon
  parallelism: 4

Запускается через bin/flink-cdc.sh shop-pipeline.yaml. Это полностью декларативный pipeline без Java/Scala кода. Подробнее в следующих уроках.


Попробуй сам

  1. Сравни время snapshot 100M rows таблицы Debezium-классиком vs Flink CDC с parallelism=8. Что повлияет на разницу?
  2. Подумай, можно ли использовать Flink CDC, если несколько downstream-сервисов хотят читать CDC. Какие компромиссы?
  3. Что произойдёт, если Flink CDC job упадёт во время snapshot фазы? А во время binlog фазы?
Проверка знанийKnowledge check
Команда мигрирует pipeline с Debezium+Kafka Connect на Flink CDC. Текущий setup: Debezium -> Kafka топик orders_cdc -> 3 разных Flink job (для Iceberg sink, для аналитики, для notifications). Можно ли просто заменить Debezium на 3 отдельных Flink CDC source — по одному на каждый job?
ОтветAnswer
Технически можно, но это создаст 3 раза большую нагрузку на MySQL binlog reader, и потенциальные проблемы с server-id collision (каждая MySQL slave subscription использует уникальный server-id; 3 Flink CDC jobs = 3 разных server-id, MySQL это переварит, но binlog reading нагрузка 3x). Если 3 consumers независимы и каждый имеет свою бизнес-логику с разной latency — есть аргумент за переход. Но более правильный подход: оставить Debezium+Kafka на ingestion, и upgrade'ить 3 downstream-job на Flink, читающих CDC events из Kafka топика. Это сохраняет single-source-of-truth (Kafka топик), кеширует CDC events на отказы downstream, и не создаёт дополнительную нагрузку на MySQL. Если же downstream только один — Flink CDC идеален, убирая лишний Kafka слой. Правило большого пальца: если в pipeline > 2 consumers — оставляйте Kafka буфер; если 1 consumer — Flink CDC выигрывает по infrastructure simplicity.

Проверьте понимание

Результат: 0 из 0
Концептуальный
Вопрос 1 из 4. В чём ключевое архитектурное отличие Flink CDC от классического Debezium + Kafka Connect?

Закончили урок?

Отметьте его как пройденный, чтобы отслеживать свой прогресс

Войдите чтобы оценить урок

Прогресс модуля
0 из 4