В современных высоконагруженных приложениях объём данных и количество запросов к базе данных постоянно растут. Это ставит перед администраторами и разработчиками задачу обеспечения высокой производительности, отказоустойчивости и масштабируемости СУБД. Именно для решения этих задач применяются балансировка и кластеризация MySQL.
Кластеризация MySQL позволяет объединить несколько серверов в единую систему, где данные реплицируются между узлами. Это даёт следующие преимущества:
- Отказоустойчивость. Если один из узлов выходит из строя, другие продолжают обслуживать запросы — приложение не перестаёт работать. В кластере можно автоматически переключать нагрузку на резервные узлы, минимизируя время простоя.
- Распределённое хранение и обработка данных. Данные распределяются по нескольким серверам, что снижает нагрузку на отдельные машины и повышает общую производительность системы.
- Масштабируемость. По мере роста нагрузки можно добавлять новые узлы в кластер, увеличивая ёмкость системы без необходимости замены существующего оборудования.
Балансировка запросов через такие решения, как ProxySQL, играет ключевую роль в оптимизации работы кластера. Её задачи:
- Равномерное распределение нагрузки. Балансировщик направляет запросы к подходящим узлам: записи — на мастер-узел, чтения — на реплики. Это позволяет задействовать все ресурсы кластера и избежать «узких мест».
- Оптимизация производительности. Разделение операций чтения и записи снижает конкуренцию за ресурсы на мастер-узле и ускоряет обработку запросов на репликах.
- Прозрачность для приложений. Приложения взаимодействуют с балансировщиком, не зная деталей топологии кластера. Это упрощает разработку и поддержку, а также позволяет менять конфигурацию кластера без внесения изменений в код приложения.
- Мониторинг и управление отказами. Балансировщик отслеживает состояние узлов и автоматически исключает недоступные серверы из обработки запросов, перенаправляя трафик на работоспособные узлы.
Таким образом, комбинация кластеризации и балансировки MySQL обеспечивает надёжную, высокопроизводительную и масштабируемую среду для работы с данными, что критически важно для современных бизнес‑приложений с высокими требованиями к доступности и производительности.
Предварительные условия
- Установлен и настроен ProxySQL.
- Имеется кластер MySQL, например, на основе Galera Cluster или MySQL InnoDB Cluster (Мой случай).
- Настроены пользователи для подключения к узлам кластера.
Конфигурация ProxySQL
Подключение к административному интерфейсу ProxySQL
Как сменить пароль я в прошлых статьях рассказывал и повторяться не будем. Аналогично и про административный интерфейс и что там тоже MySQL почитайте в предыдущих статьях.
# mysql -u admin -p -h 127.0.0.1 -P 6032
Настройка серверов (узлов кластера)
Добавьте все узлы кластера в ProxySQL (и это тоже уже рассматривали ранее):
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections, max_replication_lag)
VALUES
(1, 'node1.example.com', 3306, 100, 10),
(1, 'node2.example.com', 3306, 100, 10),
(1, 'node3.example.com', 3306, 100, 10);
hostgroup_id = 1— группа серверов для чтения и записи.max_replication_lag— максимальное отставание реплики от мастера (в секундах).
Сохраните изменения:
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
Для верности можно перезагрузить ProxySQL и проверить, что изменения сохранились (это приложение писали наркоманы и тут один принцип, все проверил и забыл как страшный сон и главное оно дальше само работает).
select * from mysql_servers;
Настройка пользователей и параметров
Добавьте пользователей, которые будут подключаться к ProxySQL (Это тоже рассматривали и подробнее в предыдущих заметках):
INSERT INTO mysql_users (username, password, default_hostgroup, default_schema, active, transaction_persistent)
VALUES ('app_user', 'password', 1, 'mydb', 1, 1);
Сохраните:
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL USERS TO DISK;
Задайте частоту опроса переменной @@read_only в миллисекундах (например, каждые 1000 мс = 1 секунда).sql
UPDATE global_variables SET variable_value = 1000 WHERE variable_name = 'mysql-monitor_read_only_interval';
Настройка правил маршрутизации запросов
Разделите запросы на чтение и запись:
INSERT INTO mysql_query_rules (rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES
(1, 1, '^SELECT.*FOR UPDATE', 1, 1), -- Запросы SELECT FOR UPDATE идут на мастер
(2, 1, '^SELECT', 2, 1), -- Все остальные SELECT идут на группу чтения
(3, 1, '^(INSERT|UPDATE|DELETE)', 1, 1); -- INSERT, UPDATE, DELETE идут на мастер
destination_hostgroup = 1— группа для записи (мастер).destination_hostgroup = 2— группа для чтения (реплики).
Сохраните:
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;
Настройка автоматического определения мастера
Создайте пользователя monitor по инструкции из прошлой статьи и вот теперь надо создать группу хостов.
INSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup, check_type, comment) VALUES (1, 2, 'read_only', 'Master/Replica group');
Сохраните:
LOAD MYSQL SERVERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
LOAD MYSQL VARIABLES TO RUNTIME;
SAVE MYSQL VARIABLES TO DISK;
Диагностика состояния кластера
Проверка состояния серверов
SELECT * FROM mysql_servers;
Интерпретация:
status = 'ONLINE'— сервер доступен.status = 'OFFLINE_HARD'— сервер недоступен.status = 'OFFLINE_SOFT'— сервер временно отключён.
Проверка правил маршрутизации
Узел с read_only=0 останется в группе 1 (Master). Узлы с read_only=1 переместятся в группу 2 (Slaves).
SELECT hostgroup_id, hostname, port, status FROM runtime_mysql_servers;
+--------------+----------------+-------+--------+
| hostgroup_id | hostname | port | status |
+--------------+----------------+-------+--------+
| 1 | 213.171.29.99 | 13306 | ONLINE |
| 2 | 185.135.81.157 | 13306 | ONLINE |
| 2 | 45.155.204.127 | 13306 | ONLINE |
+--------------+----------------+-------+--------+
3 rows in set (0.00 sec)
Важные замечания
- Мониторинг: убедитесь, что пользователь мониторинга (monitor) имеет права на выполнение SHOW SLAVE STATUS.
- Таймауты: настройте таймауты в mysql_monitor для быстрого обнаружения сбоев.
- Резервный мастер: в кластерах с несколькими мастерами настройте приоритеты (failover_priority).
- Тестирование: перед внедрением протестируйте конфигурацию в тестовой среде.




