С 2014 года в России реализуется программа импортозамещения, которая распространяется в том числе на программное обеспечение и системы управления базами данных, поднимая вопросы оптимальной миграции. В этой статье мы, специалисты департамента разработки «Консист Бизнес Групп», расскажем про особенности проекта Debezium для обеспечения миграции баз данных с разбором нагрузочного тестирования миграции.
Одной из ключевых категорий программного обеспечения являются системы управления базами данных. Аналитический центр TAdviser провел опрос 100 респондентов – ИТ-руководителей федеральных и региональных ведомств, а также компаний крупного бизнеса различных отраслей. Согласно опросу, наиболее популярными СУБД в крупном бизнесе и государственном секторе являются Oracle (81%) и Microsoft SQL (64%).
С учетом программы импортозамещения это говорит о значительном объеме работ, необходимых для миграции на свободно распространяемые СУБД – например, PostgreSQL и MySQL – или СУБД из Единого реестра российского ПО. Текущая стоимость СУБД ведущих вендоров и их технической поддержки также стимулирует интерес к переходу, поднимая задачи и проблемы миграции баз данных.
Варианты, задачи и проблемы миграции
Типовыми способами миграции баз данных являются единовременный и постепенный, каждый из которых имеет свои плюсы и минусы.
При единовременном подходе развертывается стенд с приемником базы данных (БД-приемник) нового вендора, осуществляется доработка программных модулей уровня БД, выполняется миграция данных. После этого исходная база данных отключается – она больше не нужна. При таком подходе к моменту миграции БД-приемник должен быть полностью готов. Это не позволяет использовать гибкие методологии, увеличивая вероятность ошибок в реализации функционала и затягивания миграции.
При постепенной миграции поднимается копия приложения, которая работает с новой базой данных, в основном на просмотр. Ввод данных осуществляется в существующую базу данных. При этом данные из существующей БД передаются в новую при помощи CDC-систем.
С одной стороны, возникают дополнительные затраты на поддержку копии приложения, работающего с новой версией БД (в особенности, если приложение активно развивается), с другой – появляется возможность итеративной доработки новой базы данных и постепенного ввода ее функционала. Вывод из эксплуатации старой версии базы данных и соответствующего приложения осуществляется после полной доработки функционала новой базы данных.
При осуществлении миграции с одной СУБД на другую обычно решаются следующие три задачи – миграция структуры таблиц, миграция программного кода (при наличии) и миграция данных.
При миграции структуры таблиц создаются объекты, соответствующие логической структуре хранения БД-источника, но с учетом особенностей физической реализации БД-приемника. Сложности могут возникать, если в БД-приемнике отсутствует функционал, на который завязано приложение – например, отсутствуют партиции, последовательности, некоторые виды триггеров. В этом случае приходится осуществлять доработку уже не на уровне базы данных, а на уровне приложения.
Миграцию структур могут осуществлять такие программные средства, как, например, ora2pg, если речь идет о миграции данных с Oracle в PostgreSQL. Можно также сформировать структуру данных в ручном режиме с использованием словарей данных в исходной БД простой заменой типов данных на целевые.
Самым сложным этапом является миграция программного кода. Поскольку диалекты встроенных процедурных языков могут существенно отличаться как по синтаксису, так и по наличию встроенных объектов БД, программных средств, способных к переносу кода не так много. Это все тот же ora2pg (с Oracle в PostgreSQL), а также Ispirer MnMTK (c MSSQL Server в PostgreSQL) и некоторые другие. В большинстве же случаев программный код, за исключением очень примитивных случаев, приходится писать заново.
После миграции структуры можно проводить миграцию данных. Миграция может осуществляться либо при помощи специализированных ETL-средств, либо при помощи файлов с данными, которые выгружаются и загружаются непосредственно самими базами данных. При этом возможна как единоразовая миграция, так и постоянная актуализация данных в целевой БД. Эта возможность обеспечивается средствами CDC (Change Data Capture).
Средства обеспечения миграции данных
CDC – это подход, позволяющий определять, захватывать и передавать измененные, добавленные и удаленные данные в каких-либо источниках данных. В нашем случае источником данных является существующая база данных. Для определения измененных данных в СУБД существуют различные способы – использование временных меток, версий и статусов строк, триггеров для захвата изменений, сканирование журналов транзакций.
CDC-системы отличаются как по функциональным возможностям, так и по стоимости. Это могут быть как проприетарные системы (Oracle Golden Gate, MS SQL Server Integration Services, Talend, Informatica Power Center), так и свободно распространяемые, к которым относятся Pentaho Data Integration (Kettle Spoon) и Debezium. Посмотрим внимательнее на проект Debezium.
Debezium – распределенная платформа, которая распространяется под лицензией Apache 2.0 и используется для организации обмена данными при миграции данных или модернизации существующих систем. Debezium «превращает» базы данных в потоки сообщений, благодаря чему приложения могут видеть и реагировать немедленно на каждое изменение строки.
Debezium построен поверх Apache Kafka и предоставляет коннекторы, совместимые с Kafka Connect, для мониторинга различных баз данных. Платформа записывает историю изменений данных в базе в журнальные файлы Kafka, откуда потом их могут корректно захватывать приложения. Даже если приложение аварийно прекратит работу, оно не потеряет ничего – после старта приложение продолжит обрабатывать события, которые остались необработанными до остановки.
Архитектура Debezium
Debezium чаще всего работает вместе с Apache Kafka Connect, Apache Kafka Connect – среда, обеспечивающая взаимодействие коннекторов-источников (source connectors), отправляющих записи в Kafka, таких как Debezium, и коннекторов-приемников (sink connectors), которые получают данные из Kafka и отправляют в другие системы.
Коннекторы для MySQL и PostgreSQL настроены на захват изменений баз данных. Каждый коннектор Debezium устанавливает соединение с исходной базой данных (рис. 3):
коннектор MySQL использует клиентскую библиотеку для доступа к binlog;
коннектор PostgreSQL читает из потока логической репликации;
Kafka Connect работает как отдельный сервис поверх брокера Kafka.
По умолчанию изменения из каждой таблицы базы данных пишутся в свой отдельный топик Kafka, имя которого включает в себя имя таблицы. Если необходимо, можно скорректировать имя топика передачи при помощи конфигурирования трансформации маршрутизации топика Debezium. Например, можно направлять записи в топик, имя которого отличается от имени таблицы, или направлять записи из нескольких таблиц в один топик.
После того, как изменение будет отправлено в Apache Kafka, различные коннекторы экосистемы Kafka Connect могут отправить сообщения в другие системы и базы данных (например, Elasticsearch), хранилища данных и системы аналитики или кэширования (например, Infinispan). В зависимости от выбранного коннектора приемника может потребоваться настройка нового преобразования Debezium для извлечения состояния записи. Этот преобразователь сообщений Kafka Connect распространяет структуру after из события изменения Debezium в коннектор приемника.
Другой способ развернуть Debezium – использовать сервер Debezium. Это настраиваемое, готовое к использованию приложение, которое передает события изменений из исходной базы данных в различные инфраструктуры обмена сообщениями.
Сервер Debezium настроен на использование одного из коннекторов-источников Debezium для захвата изменений из исходной базы данных. События изменений могут быть преобразованы в различные форматы (например, JSON или Apache Avro), а затем отправлены в одну из множества инфраструктур обмена сообщениями (Amazon Kinesis, Google Cloud Pub/Sub или Apache Pulsar).
Альтернативным способом использования коннекторов Debezium является встроенный механизм. В этом случае Debezium будет запускаться не через Kafka Connect, а как библиотека, встроенная в ваши пользовательские Java-приложения. Это может быть полезно либо для использования событий изменений в самом приложении без необходимости развертывания полных кластеров Kafka и Kafka Connect, либо для потоковой передачи изменений альтернативным брокерам обмена сообщениями (таким, как Amazon Kinesis).
Нагрузочное тестирование передачи данных
Рассмотрим пример использования Debezium для оперативной передачи изменяющихся данных из СУБД Oracle в другую СУБД (тексты конфигурационных файлов предоставим оперативно по запросу, обращайтесь). Для начала необходимо загрузить, установить и настроить Kafka и Kafka Connect.
Настройка заключается в редактировании конфигурационных файлов для всех создаваемых нод Kafka. После этих настроек нужно установить DebeziumConnector. Коннектор захватывает изменения уровня строк в СУБД Oracle при помощи API LogMiner или XStream. Debezium поддерживает Rest API для создания и мониторинга работоспособности подключений к БД. Примером конфигурации может служить json-файл, в котором указываются параметры подключения к СУБД, параметры Kafka, топик для сохранения данных, схемы/таблицы отслеживать изменения и др.
После этого остается реализовать функционал забора данных из топика Kafka в целевую СУБД. Это возможно сделать как при помощи скрипта (например, на Python с использованием функций Kafka), так и при помощи etl-средств, которые могут работать с топиками Kafka (Pentaho DI, NiFi, Airbyte и др.). Мы провели нагрузочное тестирование Debezium (таблица 1).
Для сравнения производительности был параллельно организован стенд c Oracle Golden Gate (таблица 2).
Нагрузочное тестирование мы проводили путем организации массовой и единичной вставки, обновления, удаления записей в таблицах, содержащих поля с основными типами данных с использованием apache jmeter (рис. 5).
В результате мы обнаружили, что при невысокой нагрузке Debezium хорошо справляется с фиксацией и передачей данных, однако с ростом нагрузки поведение Debezium оставляло желать лучшего и существенно проигрывало Oracle GG.
Вероятная причина – в особенностях внутренней реализации Debezium. Также было обнаружено, что не все типы данных Debezium может передавать без ошибок.
Выводы
Программа импортозамещения значительно увеличила интерес к свободно распространяемому программному обеспечению, в частности, в области СУБД. Одним из средств, участвующих в переходе с СУБД одного вендора на другую, являются CDC-системы.
Одной из самых известных CDC-систем с открытым исходным кодом является Debezium. Система основана на стеке продуктов Kafka и реализована на языке Java. При этом рассматривать Debezium только как средство поддержки миграции между различными СУБД, как это описано здесь, не следует. В первую очередь, Debezium – это полноценная, интенсивно развивающаяся CDC-система, которая способна заменить существующие проприетарные системы захвата изменений.
Тестирование работы этой CDC-системы позволила выявить ряд недостатков:
при достаточно простой установке настройка имеет определенные сложности (в т.ч. не описанные в документации);
не поддерживается часть типов данных (например, XML/JSON, CLOB);
невысокая производительность по сравнению с Oracle Golden Gate на среднем/высоком уровне нагруженности системы.
Несмотря на выявленные недостатки Debezium, стоит не забывать, что продукт является свободно распространяемым и с открытым исходным кодом. Это позволяет при наличии java-разработчиков провести доработку системы как в части поддержки необходимых типов данных, так и в части повышения производительности обмена данными.