• База знань
  • /
  • Блог
  • /
  • Wiki
  • /
  • ONLINE CHAT
+380 (44) 364 05 71

Стаття також доступна російською (перейти до перегляду).

Що таке Change Data Capture

Зміст

Забезпечення ефективної інтеграції розподілених баз даних є задачею нетривіальною, котра вимагає значних витрат ресурсів, як при розробці системи інтеграції, так і при її експлуатації. Системи такого типу отримали назву CDC (Change Data Capture), що буквально перекладається як «захват змінених даних». Існує безліч підходів, щодо їх реалізації, одним з яких є інструмент Debezium. Його використання дозволяє спростити процес інтеграції та розвантажити веб-додатки, котрі працюють безпосередньо з базами даних. Розглянемо коротко його можливості та продемонструємо процес розгортання на сервері Ubuntu.

Загальні підходи до організації CDC

Зазвичай, такі системи представляють собою набір програмних модулів, котрі реалізують операції реєстрації та передачі змін баз даних, внесених у вихідне сховище. Існує безліч підходів та методів, на базі котрих побудовані та функціонують сучасні CDC-системи. Такі системи водночас можуть працювати на кількох рівнях, починаючи від рівня сховища і закінчуючи рівнями веб-додатку.

Методи «захвату змін» в базі також можуть бути різними. Найбільш розповсюджені з них передбачають використання значень часу внесення змін, номери версій, статуси в строчках таблиць бази даних або ж об’єднання вказаних методів.

Інший розповсюджений метод для передачі змін в трансакційних таблицях передбачає використання тригерів, коли всі події фіксуються у спеціальній таблиці черг.

Ще один відомий підхід – це сканування журналу логів, у котрому, зазвичай, фіксуються всі транзакції будь-якої бази даних. Однак його застосування на практиці у деяких випадках зустрічається зі складностями, пов’язаними із специфікою таких журналів для кожної окремої СУБД.

Але ми хотіли б звернути увагу на деякий загальний для більшості CDC-систем підхід, при котрому реалізація процесу відслідковування та передачі змін виконуються веб-додатками, котрі безпосередньо працюють із СУБД. В результаті, вони стають витратними при розробці та перевантаженими у роботі, що є вкрай неефективно. І тому найкращим варіантом тут може стати використання зовнішнього сервісу, котрий би взяв на себе додаткові функції по фіксації та передачі змін у межах кластеру. Саме таким сервісом і є інструмент Debezium, про котрий ми вже говорили.

Основні відомості про Debezium

Сервіс Debezium відноситься до категорії програмних засобів, котрі беруть на себе функції конектора до багатьох відомих баз даних – PostgreSQL, MongoDB, MySQL та інших, гарантуючи при цьому своєчасне оповіщення під’єднаних клієнтів про внесені зміни до «контролюємої» ним СУБД.

Реалізація «системи оповіщення» є нетрадиційною, оскільки до цього процесу залучається один із розповсюджених брокерів повідомлень – Apache Kafka. І тому відповідний модуль сервісу Debezium так і називається – Kafka Connect.

Окрім того, необхідною умовою роботи сервісу є наявність спеціального програмного середовища, що, зокрема, включає сервіс ZooKeeper, середовище Docker Engine та набір конекторів для кожної з баз даних. Саме на їх основі, а також за допомогою брокера Apache Kafka реалізована своєрідна CDC-система під назвою Debezium.

Слід зазначити, що у подальшому сервіс буде мати веб-інтерфейс для повноцінного керування всіма процесами. За повідомленням розробників нині він знаходиться на стадії тестування.

Нижче будуть розглянуті усі етапи розгортання Debezium на сервері Ubuntu.

Підготовка програмного середовища сервера Ubuntu

Для можливості встановлення та налагодження сумісної роботи компонентів CDC-системи необхідно попередньо підготувати сервер, що включає наступні етапи:

  • Оновлення індексу системних пакетів, а також самих пакетів;
  • Розгортання Docker Engine.

Це нескладні операції, котрі ми вже розглядали у статті, присвяченій системі Docker, і тому не будемо тут на них зупинятися. Там наведені всі необхідні дії та пояснення до них. Зокрема, це стосується питання вибору версії Docker, котра повинна бути останньою, а не взятою із репозиторію. Це важливо.

Також слід зазначити, що інсталяція сервісу можлива і без Docker, але при цьому вона значно ускладнюється.

Після завершення виконання вказаних дій, слід переконатися у наявності активного статусу Docker Engine на сервері. Для цього введемо у терміналі:

$ sudo systemctl status docker

Перевірка статусу Docker Engine

Вихід команди:

? docker.service - Docker Application Container Engine
 	Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
 	Active: active (running) since Tue 2024-08-13 14:15:53 UTC; 4min 8s ago
TriggeredBy: ? docker.socket
   	Docs: https://docs.docker.com
   Main PID: 4029485 (dockerd)
  	Tasks: 9
 	Memory: 25.3M
    	CPU: 410ms
 	CGroup: /system.slice/docker.service
         	??4029485 /usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock

Головний процес запущений (Main PID: 4029485), а значить Docker-система готова до роботи.

Запуск контейнерів із компонентами CDC-середовища

Для функціонування CDC-середовища на базі Debezium, окрім бази даних необхідна наявність кількох активних сервісів, про що вже йшла мова раніше, можна запустити у вигляді компонентів окремих контейнерів, розгорнутих із Docker-шаблонів системи Debezium.

Нижче представлені ці сервіси та БД:

  • Apache ZooKeeper;
  • Apache Kafka;
  • БД MySQL;
  • Клієнт командної строки MySQL;
  • Kafka Connect.

Ми будемо по черзі розгортати кожен із сервісів, а також базу даних у окремих вікнах терміналу, встановлюючи при цьому для кожного з них інтерактивний режим роботи. У такому разі стандартний ввід та вивід терміналу буде під’єднуватися до контейнеру. Це дасть змогу візуально контролювати проходження всіх операцій оновлення даних для кожного з’єднання.

Запуск Apache ZooKeeper

Це відомий сервіс, котрий виконує функції координатора роботи розподілених систем. Запустимо контейнер із цією програмою із вказаного у команді шаблону. Для цього введемо в терміналі:

$ docker run -it --rm --name zookeeper -p 2181:2181 -p 2888:2888 -p 3888:3888 quay.io/debezium/zookeeper:2.7

Тут опція -it – встановлює інтерактивний режим роботи з контейнером; --rm – програмування автоматичного видалення контейнеру після завершення роботи; --name zookeeper – задає ім’я контейнеру; -p порт1:порт2 – співставлення портів контейнеру та хоста, це потрібно щоб зовнішні програми могли взаємодіяти із сервісом; quay.io/debezium/ – місцезнаходження шаблону програми.

Скріншоти процесу розгортання контейнеру та його результати наведені нижче.

Запуск ZooKeeper

Статус ZooKeeper

Розгортання ZooKeeper

Отже, ZooKeeper запущений та налаштований на прослуховування порту 2181. Ознакою цього є наявність наступних строчок на виході:

Status: Downloaded newer image for quay.io/debezium/zookeeper:2.7
Starting up in standalone mode
/usr/bin/java
ZooKeeper JMX enabled by default
Using config: /zookeeper/conf/zoo.cfg
 
2024-08-13 14:29:47,780 - INFO  [main:o.a.z.s.q.QuorumPeerConfig@177] - Reading configuration from: /zookeeper/conf/zoo.cfg
 
2024-08-13 14:29:47,786 - INFO  [main:o.a.z.s.q.QuorumPeerConfig@440] - clientPortAddress is 0.0.0.0:2181
 
2024-08-13 14:29:47,806 - INFO  [main:o.a.z.s.ZooKeeperServerMain@123] - Starting server
 
2024-08-13 14:29:47,816 - INFO  [PurgeTask:o.a.z.s.DatadirCleanupManager$PurgeTask@139] - Purge task started.
 
2024-08-13 14:29:48,261 - INFO  [main:o.a.z.s.NIOServerCnxnFactory@660] - binding to port  0.0.0.0/0.0.0.0:2181

Запуск Apache Kafka

Це є високошвидкісний брокер повідомлень, котрий забезпечує безперешкодний зв’язок між елементами розподілених систем. Ми вже розглядали роботу цієї програми у одній із наших попередніх статей, і тому не будемо тут на ній докладно зупинятися.

Відкриємо нове вікно терміналу та запустимо сервіс за допомогою наступної команди:

$ docker run -it --rm --name kafka -p 9092:9092 --link zookeeper:zookeeper quay.io/debezium/kafka:2.7

Тут опція --link zookeeper:zookeeper – вказує контейнеру на місцезнаходження сервісу ZooKeeper. Призначення усіх інших параметрів розглянуте нами раніше.

Нижче наведені скріншоти процесу розгортання контейнеру.

 Запуск нового вікна Zookeeper

Статус розгортання zookeeper

Процес розгортання Zookeeper

Процес розгортання Zookeeper

Сервіс Kafka запущений та готовий до роботи сумісно із ZooKeeper. На це, зокрема, вказують наступні строчки інформаційних повідомлень:

2024-08-13 15:56:12,068 - INFO  [main:Logging@66] - [SocketServer listenerType=ZK_BROKER, nodeId=1] Enabling request processing.
 
2024-08-13 15:56:12,075 - INFO  [main:Logging@66] - Awaiting socket connections on 172.17.0.3:9092.
 
2024-08-13 15:56:12,120 - INFO  [main:AppInfoParser$AppInfo@124] - Kafka version: 3.7.0
 
2024-08-13 15:56:12,121 - INFO  [main:AppInfoParser$AppInfo@125] - Kafka commitId: 2ae524ed625438c5
 
2024-08-13 15:56:12,122 - INFO  [main:AppInfoParser$AppInfo@126] - Kafka startTimeMs: 1723564572107
 
2024-08-13 15:56:09,606 - INFO  [main:Logging@66] – starting
 
2024-08-13 15:56:09,607 - INFO  [main:Logging@66] - Connecting to zookeeper on 172.17.0.2:2181
 
2024-08-13 15:56:09,626 - INFO  [main:Logging@66] - [ZooKeeperClient Kafka server] Initializing a new session to 172.17.0.2:2181.
 
zookeeper.connect = 172.17.0.2:2181
 
2024-08-13 15:56:09,703 - INFO  [main:Logging@66] - [ZooKeeperClient Kafka server] Connected.

Розгортання MySQL

Нам потрібно розгорнути сервер бази даних, зміни в котрій повинен відслідковувати програмний засіб Debezium. Ми маємо в наявності готову базу MySQL із ім’ям inventory зі своїм набором таблиць. Саме її ми будемо використовувати для прикладу.

Створимо нове вікно терміналу та введемо в командній строчці наступну команду

$ docker run -it --rm --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=debezium 
-e MYSQL_USER=mysqluser -e MYSQL_PASSWORD=mysqlpw quay.io/debezium/example-mysql:2.7

Запуск серверу MySQL та створення нового користувача

Опція -e використовується тут для створення користувача та пароля для нього. Усі інші параметри відомі.

Процес запуску серверу MySQL

Отже, сервер бази даних запущений та готовий до роботи. Ознакою цього є наступні строки інформаційних повідомлень:

2024-08-13T16:24:08.719257Z 0 [System] [MY-015015] [Server] MySQL Server - start.
 
2024-08-13T16:24:09.017860Z 0 [System] [MY-010116] [Server] /usr/sbin/mysqld (mysqld 8.2.0)
starting as process 1
 
2024-08-13T16:24:09.057668Z 1 [System] [MY-013576] [InnoDB] InnoDB initialization has started.
 
2024-08-13T16:24:11.022457Z 0 [System] [MY-011323] [Server] X Plugin ready for connections.
Bind-address: '::' port: 33060, socket: /var/run/mysqld/mysqlx.sock
 
2024-08-13T16:24:11.022532Z 0 [System] [MY-010931] [Server] /usr/sbin/mysqld: ready for
connections. Version: '8.2.0'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  MySQL
Community Server - GPL.

Запуск клієнта MySQL

Розгорнемо новий контейнер із шаблону mysql:8.2 для активації в ньому клієнта командної строки MySQL. Це дасть змогу отримати доступ до екземпляру нашої бази із ім’ям inventory.

Для цього створимо нове вікно терміналу, де введемо наступну команду:

$ docker run -it --rm --name mysqlterm --link mysql mysql:8.2 sh -c 'exec mysql 
-h"$MYSQL_PORT_3306_TCP_ADDR" -P"$MYSQL_PORT_3306_TCP_PORT" -uroot -p"$MYSQL_ENV_MYSQL_ROOT_PASSWORD"'

Тут опція --name mysqlterm вказує на ім’я контейнеру; опція --link mysql вказує на ім’я контейнеру, з котрим встановлюється зв’язок.

Процес розгортання контейнеру наведений нижче.

Розгортання нового контейнеру

В результаті запрошення командної строчки змінилося на наступне:

mysql>

Це означає, що клієнт MySQL готовий до роботи. Також виведена інформація про встановлене з’єднання:

Your MySQL connection id is 8
Server version: 8.2.0 MySQL Community Server - GPL

Активуємо нашу базу даних:

mysql> use inventory;

Активація БД MySQL

Переглянемо список наявних у ній таблиць:

mysql> show tables;

Список наявних таблиць

Переглянемо дані однієї із таблиць:

mysql> SELECT * FROM products;

Перегляд конкретної таблиці

Таким чином, ми з’ясували, що клієнт працює та переконалися у існуванні заповненої бази даних.

Запуск Kafka Connect

Після того, як ми розгорнули контейнер із сервером MySQL та під’єдналися до нашої бази за допомогою клієнта командної строчки, ми можемо запустити сервіс Kafka Connect. Сервіс надає REST API інтерфейс для керування конектором Debezium для БД MySQL.

Запустимо контейнер із компонентом Kafka Connect. Для цього відкриємо нове вікно терміналу та введемо в ньому наступну команду:

$ docker run -it --rm --name Connect -p 8083:8083 -e GROUP_ID=1 
-e CONFIG_STORAGE_TOPIC=my_connect_configs -e OFFSET_STORAGE_TOPIC=my_connect_offsets 
-e STATUS_STORAGE_TOPIC=my_connect_statuses --link kafka:kafka --link mysql:mysql quay .io/debezium/connect:2.7

Тут опція -e використовується для встановлення змінних програмного середовища, необхідних для використання шаблону Debezium; Опції --link kafka:kafka --link mysql:mysql необхідні для встановлення зв’язку контейнера із іншими контейнерами, на котрих запущені сервер MySQL та брокер повідомлень Kafka.

Процес розгортання контейнеру наведений нижче.

Процес розгортання контейнеру

процес розгортання Kafka Connect

Процес розгортання Kafka Connect

Таким чином, нами був успішно запущений сервіс Kafka Connect, котрий готовий приймати підключення. Ознакою цього є, зокрема, наступні строчки інформаційних повідомлень, у котрих виводиться інформація про встановлене з’єднання та створений робочий кластер:

2024-08-13 17:01:24,807 INFO   ||  [Worker clientId=connect-172.17.0.6:8083, groupId=1]
Herder started   [org.apache.kafka.connect.runtime.distributed.DistributedHerder]
 
2024-08-13 17:01:24,854 INFO   ||  [Worker clientId=connect-172.17.0.6:8083, groupId=1]
Cluster ID: RpSwNrtZTyG2HU1BHRARVA   [org.apache.kafka.clients.Metadata]
 
2024-08-13 17:01:30,747 INFO   ||  [Worker clientId=connect-172.17.0.6:8083, groupId=1]
Starting connectors and tasks using config offset -1
[org.apache.kafka.connect.runtime.distributed.DistributedHerder]
 
2024-08-13 17:01:30,748 INFO   ||  [Worker clientId=connect-172.17.0.6:8083, groupId=1]
Finished starting connectors and tasks
[org.apache.kafka.connect.runtime.distributed.DistributedHerder]

Тепер перевіримо зв’язок із сервісом Kafka Connect шляхом відправлення API-запитів на порт 8083 хоста системи Docker. Для цього створимо нове вікно терміналу, у котрому введемо наступну команду:

$ curl -H "Accept:application/json" localhost:8083/

Перевірка зв'язку зх контейнером

Відповідь:

"version":"3.7.0","commit":"2ae524ed625438c5","kafka_cluster_id":"RpSwNrtZTyG2HU1BHRARVA"}

Тепер перевіримо список зареєстрованих у Kafka Connect з’єднань:

$ curl -H "Accept:application/json" localhost:8083/connectors/

Запуск зареєстрованих з'єднань

Відповідь: [] No connectors are currently registered with Kafka Connect. Це значить, що жодне з'єднання не зареєстровано.

Розгортання Debezium для MySQL

Після того як сервер БД MySQL та клієнт командної строчки запущені та встановлене підключення до екземпляру створеної нами бази даних із ім’ям inventory, можна переходити до розгортання Debezium. Це дозволить моніторити створений нами екземпляр БД MySQL.

Зареєструємо Debezium-конектор із поточною конфігурацією, після чого він почне відслідковувати binlog серверу БД MySQL, у котрому, зазвичай, фіксуються усі транзакції, котрі відбуваються. При будь якій зміні у строках таблиць БД буде генеруватися відповідне повідомлення.

Для цього створимо нове вікно терміналу, де введемо наступну команду:

$ curl -i -X POST -H "Accept:application/json" -H "Content-Type:application/json"
localhost:8083/connectors/ -d '{ "name": "inventory-connector", "config": 
{ "connector.class": "io.debezium.connector.mysql.MySqlConnector", "tasks.max": "1",
"database.hostname": "mysql", "database.port": "3306", "database.user": "debezium",
"database.password": "dbz", "database.server.id": "184054", "topic.prefix": "dbserver1",
"database.include.list": "inventory", "schema.history.internal.kafka.bootstrap.servers":
"kafka:9092", "schema.history.internal.kafka.topic": "schemahistory.inventory" } }'

Реєстрація Debezium-конектора

Вихід команди:

HTTP/1.1 201 Created
Date: Tue, 13 Aug 2024 17:37:20 GMT
Location: http://localhost:8083/connectors/inventory-connector
Content-Type: application/json
Content-Length: 500
Server: Jetty(9.4.53.v20231009)
{"name":"inventory-connector","config":
{"connector.class":"io.debezium.connector.mysql.MySqlConnector","tasks.max":"1",
"database.hostname":"mysql","database.port":"3306","database.user":"debezium",
"database.password":"dbz","database.server.id":"184054","topic.prefix":"dbserver1",
"database.include.list":"inventory","schema.history.internal.kafka.bootstrap.servers":
"kafka:9092","schema.history.internal.kafka.topic":"schemahistory.inventory","name":
"inventory-connector"},"tasks":[],"type":"source"}

У наведених записах міститься вся інформація про поточну конфігурацію конектора Debezium.

Переконаємося в тому, що inventory-connector є у списку конекторів. Для цього введемо наступну команду:

$ curl -H "Accept:application/json" localhost:8083/connectors/

inventory-connector серед списку конекторів

Відповідь: ["inventory-connector"]. Тобто, у списку з’явився новий конектор, як і передбачалося.

Переглянемо список його завдань:

$ curl -i -X GET -H "Accept:application/json" localhost:8083/connectors/inventory-connector

Список завдань конектора

Відповідь:

HTTP/1.1 200 OK
Date: Tue, 13 Aug 2024 17:47:43 GMT
Content-Type: application/json
Content-Length: 544
Server: Jetty(9.4.53.v20231009)
 
{"name":"inventory-connector","config":
{"connector.class":"io.debezium.connector.mysql.MySqlConnector","database.user":
"debezium","topic.prefix":"dbserver1","schema.history.internal.kafka.topic":
"schemahistory.inventory","database.server.id":"184054","tasks.max":"1","database.hostname":
"mysql","database.password":"dbz","name":"inventory-connector",
"schema.history.internal.kafka.bootstrap.servers":"kafka:9092","database.port":"3306",
"database.include.list":"inventory"},"tasks":[{"connector":"inventory-connector","task":0}],"type":"source"}

Можна переконатися, що на даний час виконується лише одне завдання ("task":0), оскільки MySQL фіксує всі свої дії лише у одному журналі. І тому конектору потрібен лише один споживач інформації для отримання впорядкованої інформації про всі події, що відбуваються.

Контроль за роботою Kafka Connect

Одразу після реєстрації конектора генерується значний об’єм інформації у журналі контейнеру із сервісом Kafka Connect, у котрому фіксуються всі його дії.

Нижче наведені скріншоти із згенерованими Kafka Connect інформаційними повідомленнями.

Журнал Kafka Conect

Журнал Kafka Conect

Журнал Kafka Conect

Переглядаючи виведені інформаційні повідомлення можна прослідкувати за поведінкою Kafka Connect, починаючи з моменту його створення і закінчуючи початком відслідковування файлу binlog серверу MySQL.

Дата-центр  FREEhost.UA  пропонує  хмарний  VPS  хостинг  з  Docker та зручним інтерфейсом керування Docker Portainer. Вже за кілька хвилин після оплати замовлення, повністю налаштований сервер готовий до роботи.

Підписуйтесь на наш телеграм-канал https://t.me/freehostua, щоб бути в курсі нових корисних матеріалів.

Дивіться наш канал Youtube на https://www.youtube.com/freehostua.

Ми у чомусь помилилися, чи щось пропустили?

Напишіть про це у коментарях, ми з задоволенням відповімо та обговорюємо Ваші зауваження та пропозиції.

Дата: 21.08.2024
Автор: Олександр Ровник
Голосування

Авторам статті важлива Ваша думка. Будемо раді його обговорити з Вами:

comments powered by Disqus
navigate
go
exit
Дякуємо, що обираєте FREEhost.UA