
Привет, меня зовут Максим Рыбалко, я директор по управлению проектами Т1 Иннотех.
На текущий момент мы занимаемся разработкой для сотрудников банка фронтального приложения, в котором они смогут в одном окне видеть всю необходимую информацию, физически хранящуюся в трёх отдельных базах данных. В реализации самого приложения никаких особенностей и сложностей нет, чего не скажешь про его бэкенд.
Итак, задача, стоявшая перед нами — отобразить пользователю общую выборку данных, которые хранятся физически в отдельных кластерах БД.
Варианты реализации
Отправлять несколько запросов с фронта и агрегировать на нём же выборку. Не буду подробно останавливаться на этом варианте, так как уже изначально понятно, что лучше в эту сторону даже не смотреть.
Разработать отдельный микросервис, который будет получать запрос с фронта, сам отправлять три запроса в БД и агрегировать данные для передачи обратно на фронт. Мы так и сделали, однако после оценки трудо‑ и ресурсозатрат решили искать дальше.
Создать отдельную, так называемую отчётную БД, которая будет содержать в себе данные из трёх других БД.
Мы остановились на третьем варианте и дальше стали продумывать, как:
Первично наполнить новую БД.
В дальнейшем непрерывно наполнять её, с сохранением согласованности данных в исходных и целевой базе.
Выбор инструментов
Для первоначальной заливки мы рассматривали несколько вариантов. Первый — стандартное решение от PostgreSQL: pg_dump
каждой таблицы и ручной перенос. Но так как у нас около 80 таблиц общим объёмом под 1,5 ТБ, то посчитав время, которое потребуется, решение отклонили.
Важный момент, который стоит учесть: после первичного наполнения необходимо сразу же обеспечить дальнейшую репликацию в целевую БД — так называемую онлайн‑репликацию, иначе о согласованности данных в источнике и целевой системе можно забыть.
Затем мы рассмотрели готовое решение в банке, которое разработано в рамках импортозамещения для репликации данных после перехода на СУБД PostgreSQL и прочие не зарубежные БД. Это ПО состоит из двух модулей:
Инициализирующий модуль, позволяющий первично наполнить целевую БД из одной или нескольких баз‑источников.
Модуль онлайн‑репликации (Debezium), фиксирующий изменения в источнике и применяющий такие же изменения в целевой БД.


Онлайн‑репликация с использованием Debezium работает так:
Включение CDC (Change Data Capture):
В исходной SQL‑базе данных включается отслеживание изменённых данных (CDC).
В таблицах, которые нужно реплицировать, тоже включается CDC.
Настройка коннектора источника Debezium:
Коннектор источника Debezium считывает обновления CDC с сервера SQL.
Обновления CDC отправляются в разделы топиков Apache Kafka.
Настройка коннекторов приёмника JDBC:
Коннекторы приёмника JDBC извлекают данные из топиков Kafka.
Обновления записываются в целевые базы данных.
Создание топиков Kafka:
Топики Kafka создаются для запуска Kafka Connect.
Коннекторы Debezium и фактическая репликация данных запускаются на этих топиках.
Настройка атрибутов коннекторов:
В исходном коннекторе Debezium указывается таблица с поддержкой CDC с помощью атрибута
table.whitelist
.Атрибут
snapshot
заполняет топик Kafka всеми записями исходной базы данных при создании коннектора.В коннекторе приёмника указываются топики, из которых будут извлекаться данные, и таблицы‑приемники с помощью атрибутов
topics
иname.format
.
Преобразования сообщений (SMT):
SMT‑преобразователи, такие как
ExtractNewRecordState
иRegexRouter
, могут быть настроены для преобразования сообщений до их сохранения в топиках Kafka или целевых базах данных.
Пример конфигурации для коннектора источника Debezium:
{
"connector.class": "io.debezium.connector.sqlserver.SqlServerConnector",
"database.hostname": "your-sql-server-hostname",
"database.port": "1433",
"database.user": "your-sql-server-user",
"database.password": "your-sql-server-password",
"database.server.name": "your-sql-server-name",
"database.history.kafka.bootstrap.servers": "kafka-broker-host:9092",
"database.history.kafka.topic": "dbhistory",
"table.whitelist": "dbo.your_table1,dbo.your_table2",
"snapshot.mode": "initial",
"snapshot.initial.mode": "include_new_values",
"transforms": "unwrap",
"transforms.unwrap.type": "io.debezium.transforms.UnwrapFromEnvelope"
}
Пример конфигурации для коннектора приёмника JDBC:
{
"connector.class": "io.debezium.connector.jdbc.JdbcSinkConnector",
"tasks.max": "1",
"topics": "your-kafka-topic",
"connection.url": "jdbc:postgresql://your-postgresql-host:5432/your-database",
"connection.user": "your-postgresql-user",
"connection.password": "your-postgresql-password",
"transforms": "unwrap",
"transforms.unwrap.type": "io.debezium.transforms.UnwrapFromEnvelope",
"transforms.unwrap.drop.tombstones": "false",
"transforms.route.topic.format": "your-postgresql-table",
"transforms.route.topic.regex": ".*"
}
Преимущества и недостатки Debezium
Во время работы с Debezium мы обнаружили как преимущества, так и некоторые недостатки. Сначала недостатки:
Наличие определённых навыков. Несмотря на простоту установки, настройка Debezium может быть сложной и требует определённых знаний, которые не всегда описаны в документации.
Зависимость от Kafka. Debezium тесно интегрирован с Kafka, и любые проблемы с Kafka могут повлиять на работу Debezium.
Зависимость от структуры. В случае расхождения структуру источника и приёмника онлайнрепликация останавливается до исправления расхождения.
Теперь о достоинствах:
Поддержка широкого спектра СУБД. Debezium поддерживает множество популярных систем управления базами данных, включая MSSQL, Oracle, PostgreSQL, Scylla, ClickHouse, Hadoop и другие. Это делает платформу универсальным решением для различных проектов.
Гибкая конфигурация. Платформа предоставляет множество параметров и настроек, что позволяет адаптировать её под конкретные требования проекта. В том числе возможность оптимизации производительности и настройки взаимодействия между компонентами.
Гарантия фиксации всех изменений. Debezium гарантирует фиксацию всех изменений в базе данных, включая добавления и удаления данных. Это обеспечивает целостность данных и минимизирует риск потери информации.
Обработка событий в реальном времени. Платформа обрабатывает события изменений данных в режиме реального времени, что особенно важно для систем, требующих высокой оперативности, например, финансовых систем.
Интеграция с Apache Kafka. Debezium интегрируется с Apache Kafka, что позволяет использовать его как центральное хранилище для событий изменений данных. Это упрощает дальнейшую обработку и анализ.
Возможность развертывания различными способами. Платформа может быть развёрнута с помощью Apache Kafka Connect, сервера Debezium или движка Debezium, что позволяет выбрать наиболее подходящий способ в зависимости от требований проекта и инфраструктуры.
Оптимизация производительности. Debezium предоставляет возможности для оптимизации производительности через настройку параметров и использование различных коннекторов.
Поддержка различных форматов данных. Платформа поддерживает различные форматы данных, такие как JSON и Apache Avro, что позволяет гибко настраивать сериализацию и десериализацию данных.
Мониторинг и управление. Debezium предоставляет инструменты для мониторинга и управления изменениями данных, что позволяет оперативно реагировать на возможные проблемы и оптимизировать работу системы.
Масштабируемость. Платформа легко масштабируется, что позволяет увеличивать или уменьшать количество коннекторов и топиков Kafka в зависимости от нагрузки и требований проекта.
Шифрование. Поддержка протокола шифрования TLS (mTLS).
Работа в контейнерной среде. Возможность использования в контейнерной среде: Kubernetes, openshift.
Разнообразие ОС. Возможность использования различных ОС в том числе Astra Linux.
Результат и выводы о проекте
Использование Debezium позволило нам эффективно решить задачу по созданию отчётной БД, которая содержит данные из трёх отдельных источников. Переливка 1,5 ТБ данных с учётом развёртывания и настройки заняла 7 часов.
Благодаря поддержке CDC и интеграции с Apache Kafka мы обеспечили непрерывное и согласованное наполнение БД, что является критически важным для нашего проекта. В результате мы получили гибкое и масштабируемое решение, которое позволяет нам оперативно реагировать на изменения в исходных базах данных и предоставлять пользователям актуальную информацию в одном окне.