В этом туториале вы узнаете, как прокси сервер базы данных MariaDB MaxScale может использоваться в качестве прозрачного разделителя операций чтения/записи для ваших SQL-запросов.
Разделение чтения/записи — это метод перенаправления операций чтения и записи на несколько серверов баз данных, позволяющий выполнять балансировку нагрузки на основе запросов. Реализовать это на уровне приложения сложно, поскольку это связывает код или параметры конфигурации с базовой топологией базы данных. Например, вам может потребоваться определить разные пулы соединений для каждого сервера в кластере базы данных.
MariaDB MaxScale — это расширенный прокси сервер базы данных, который можно использовать в качестве разделителя операций чтения/записи, направляющего операторы SELECT
на узлы реплики, а операторы INSERT
/UPDATE
/DELETE
— на основные узлы. Это происходит автоматически, без необходимости изменения кода вашего приложения или даже конфигурации — с MaxScale для вашего приложения база данных выглядит как БД с одним узлом.
В этом туториале вы узнаете, как настроить репликацию базы данных MariaDB с одним основным и двумя узлами репликами, а также как настроить MaxScale, чтобы скрыть сложность базовой топологии.
Самое приятное: вы научитесь всему этом, не выходя из браузера!
Веб-сайт Play With Docker
Play With Docker (PWD) — это веб-сайт, который позволяет создавать виртуальные машины с предустановленным Docker и взаимодействовать с ними прямо в браузере. Войдите в систему и начните новую сессию.
Всего будет использовано 5 узлов:
node1 : Основной сервер
node2 : Сервер реплики A
node3 : Сервер реплики B
node4 : Прокси сервер базы данных MaxScale
node5 : Тестовая машина (например, эквивалент веб-сервера)
Примечание. Несмотря на то, что базы данных в контейнерах Docker хорошо подходят для самых простых сценариев и сред разработки, это может быть не лучшим вариантом для производственных сред. Корпорация MariaDB в настоящее время не предлагает поддержку развертывания Docker в производственных средах. Для производственных сред рекомендуется использовать MariaDB Enterprise (в облаке или локально) или MariaDB SkySQL (в настоящее время доступна на AWS и GCP).
Запуск основного сервера
Добавьте новый экземпляр с помощью соответствующей кнопки:
На node1 запустите основной сервер MariaDB следующим образом:
docker run --name mariadb-primary \
-d \
--net=host \
-e MARIADB_ROOT_PASSWORD=password \
-e MARIADB_DATABASE=demo \
-e MARIADB_USER=user \
-e MARIADB_PASSWORD=password \
-e MARIADB_REPLICATION_MODE=master \
-e MARIADB_REPLICATION_USER=replication_user \
-e MARIADB_REPLICATION_PASSWORD=password \
bitnami/mariadb:latest
Эта команда создает контейнер, на котором запущен сервер MariaDB Community, с пользователем базы данных для репликации (replication_user
). Реплики будут использовать этого пользователя для подключения к основному.
Запуск серверов реплик
Создайте два новых экземпляра (node2 и node3) и выполните следующую команду на них обоих:
docker run --name mariadb-replica \
-d \
--net=host \
-e MARIADB_MASTER_ROOT_PASSWORD=password \
-e MARIADB_REPLICATION_MODE=slave \
-e MARIADB_REPLICATION_USER=replication_user \
-e MARIADB_REPLICATION_PASSWORD=password \
-e MARIADB_MASTER_HOST=<PRIMARY_IP_ADDRESS> \
bitnami/mariadb:latest
Замените <PRIMARY_IP_ADDRESS>
на IP-адрес узла node1. IP-адрес можно найти в списке экземпляров.
Теперь у вас есть кластер, состоящий из одного основного узла и двух реплик. Все записи, которые вы выполняете на первичном узле (node1), автоматически реплицируются на все узлы реплики (node2 и node3).
Запуск MaxScale
MaxScale — это прокси базы данных, понимающий SQL. Это позволяет ему направлять операции записи на основной узел и операции чтения на реплики с балансировкой нагрузки. Ваше приложение может подключаться к MaxScale с помощью одной конечной точки, как если бы это была база данных с одним узлом.
Создайте новый экземпляр (node4) и запустите MaxScale следующим образом:
docker run --name maxscale \
-d \
--publish 4000:4000 \
mariadb/maxscale:latest
Вы можете настроить MaxScale с помощью конфигурационных файлов, но в этом руководстве мы будем использовать командную строку, чтобы убедиться, что вы понимаете каждый шаг. В менее эфемерных средах следует использовать конфигурационные файлы, особенно в оркестрованных развертываниях, таких как Docker Swarm и Kubernetes.
Запустите новую оболочку на узле node4:
docker exec -it maxscale bash
Вам необходимо создать объекты server
в MaxScale. Это базы данных MariaDB, к которым MaxScale направляет операции чтения и записи.
Замените <NODE_1_IP_ADDRESS>
, <NODE_2_IP_ADDRESS>
и <NODE_3_IP_ADDRESS>
на IP-адреса соответствующих узлов (node1, node2 и node3) и выполните следующие команды:
maxctrl create server node1 <NODE_1_IP_ADDRESS>
maxctrl create server node2 <NODE_2_IP_ADDRESS>
maxctrl create server node3 <NODE_3_IP_ADDRESS>
Далее необходимо создать monitor
в MaxScale для проверки состояния кластера. Выполните следующую команду:
maxctrl create monitor mdb_monitor mariadbmon \
--monitor-user root --monitor-password 'password' \
--servers node1 node2 node3
Примечание. Не используйте пользователя root в производственных средах! Это нормально в этой временной лабораторной среде, но в других случаях создайте нового пользователя базы данных для MaxScale и предоставьте ему соответствующие права.
Теперь, когда MaxScale осуществляет мониторинг серверов и делает эту информацию доступной для других модулей, вы можете создать MaxScale service
. В этом случае сервис использует маршрутизатор MaxScale, чтобы операции чтения и записи направлялись на нужный тип сервера в кластере (основной или реплику). Для создания нового сервиса выполните следующую команду:
maxctrl create service query_router_service readwritesplit \
user=root \
password=password \
--servers node1 node2 node3
Наконец, необходимо создать MaxScale listener
(слушатель). Этот тип объекта определяет порт, который MaxScale использует для получения запросов. Вы должны связать слушатель с маршрутизатором. Выполните следующую команду для создания нового слушателя:
maxctrl create listener \
query_router_service query_router_listener 4000 \
--protocol=MariaDBClient
Обратите внимание, как слушатель настроен на использование порта 4000. Это тот же порт, который вы опубликовали при запуске Docker контейнера.
Проверьте, что серверы запущены и работают:
maxctrl list servers
Вы должны увидеть нечто похожее на следующее:
Тестирование установки
Чтобы протестировать кластер, создайте новый экземпляр (node5) и запустите контейнер Ubuntu:
docker run --name ubuntu -itd ubuntu
Этот контейнер эквивалентен, например, машине, на которой размещено веб-приложение, подключающееся к базе данных. Запустите новую сессию Bash на этой машине:
docker exec -it ubuntu bash
Обновите каталог пакетов:
apt update
Установите SQL-клиент MariaDB, чтобы вы могли выполнять SQL-код:
apt install mariadb-client -y
Подключитесь к базе данных, а точнее к прокси серверу базы данных MaxScale:
mariadb -h 192.168.0.15 --port 4000 -u user -p
Как видите, все выглядит так, как будто MaxScale представляет собой единую базу данных. Создайте следующую таблицу:
CREATE TABLE demo .message ( ТЕКСТ содержимого );
Мы хотим вставлять строки, содержащие уникальный идентификатор сервера экземпляра MariaDB, который фактически выполняет операцию вставки. Вот как это сделать:
INSERT INTO demo.message VALUES \
(CONCAT("Write from server ", @@server_id)), \
(CONCAT("Write from server ", @@server_id)), \
(CONCAT("Write from server ", @@server_id));
Теперь давайте посмотрим, какой сервер MariaDB выполнял операции записи и чтения:
SELECT *, CONCAT("Read from server ", @@server_id) FROM demo.message;
Выполните предыдущий запрос несколько раз. Вы должны получить результат, подобный этому:
В моем кластере все записи выполнялись сервером с ID 367, который является основным узлом.
Чтения выполнялись серверами с идентификаторами 908 и 308, которые являются узлами репликами. Вы можете подтвердить значения идентификатора, выполнив на основном узле и узле реплике следующие команды:
docker exec -it mariadb-primary mariadb -u root -p \
--execute="SELECT @@server_id"
docker exec -it mariadb-replica mariadb -u root -p \
--execute="SELECT @@server_id"
Что дальше?
В этом руководстве мы сосредоточились на базовом разделении чтения/записи, но MaxScale может сделать гораздо больше.
Например, обеспечивать безопасность топологии серверной базы данных, выполнять автоматическое восстановление после отказа, выполнять балансировку нагрузки на основе соединений, импортировать и экспортировать данные из Kafka и в него и даже преобразовывать команды NoSQL/MongoDB API в SQL. MaxScale также включает REST API и веб-интерфейс GUI для выполнения операций. Ознакомьтесь с документацией, чтобы узнать больше о MaxScale.