Що таке ProxySQL і навіщо він потрібен
ProxySQL — це проксі-сервер рівня SQL, який стоїть між застосунком і серверами MySQL або MariaDB. Він приймає з'єднання від клієнта на порту 6033, розбирає кожен запит і вирішує, на який сервер його надіслати. Головне завдання ProxySQL — розподіл читання і запису: запити на запис (INSERT, UPDATE, DELETE) ідуть на майстер, а SELECT-запити розподіляються між репліками.
Без проксі таку логіку доводиться прописувати в коді застосунку: тримати два підключення, вручну обирати з'єднання під тип запиту. ProxySQL знімає це навантаження із застосунку і переносить його на окремий шар, який можна змінювати без правки коду.
Як ProxySQL розподіляє читання і запис
В основі лежать три сутності: mysql_servers, mysql_users і mysql_query_rules. Сервери групуються у hostgroups — зазвичай група 10 для запису (майстер) і група 20 для читання (репліки). Query rules — правила з регулярними виразами, які перевіряють текст запиту і призначають йому hostgroup.
- Запит починається з SELECT — прямує у hostgroup читання.
- Запит містить SELECT ... FOR UPDATE — прямує на запис, щоб не читати застарілі дані.
- INSERT, UPDATE, DELETE і DDL завжди прямують у hostgroup запису.
Встановлення ProxySQL на Ubuntu та Debian
ProxySQL встановлюється з окремого репозиторію, у стандартних репозиторіях Ubuntu його зазвичай немає. Пакет беруть зі сторінки релізів проєкту ProxySQL на GitHub. Після встановлення сервіс слухає два порти: 6032 для адміністрування і 6033 для клієнтських підключень.
wget -O /tmp/proxysql.deb repo.proxysql.com/deb/proxysql_2.6.0-ubuntu22_amd64.deb
dpkg -i /tmp/proxysql.deb
systemctl enable --now proxysql
mysql -u admin -padmin -h 127.0.0.1 -P 6032Налаштування серверів і hostgroups
Після входу в адміністративний інтерфейс додають сервери і користувачів. Пароль користувача в ProxySQL повинен збігатися з паролем на реальному MySQL-сервері — проксі не зберігає окрему базу облікових даних, а лише передає з'єднання далі.
| Параметр | Значення | Призначення |
|---|---|---|
| hostgroup_id 10 | майстер | приймання запису і транзакцій |
| hostgroup_id 20 | репліки | приймання SELECT-запитів |
| max_connections | 200 | ліміт підключень до сервера |
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (10, '10.0.0.11', 3306);
INSERT INTO mysql_servers(hostgroup_id, hostname, port) VALUES (20, '10.0.0.12', 3306);
INSERT INTO mysql_users(username, password, default_hostgroup) VALUES ('app', 'secret', 10);
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;Query rules: як спрямувати запити на потрібні сервери
Правила додаються в таблицю mysql_query_rules і застосовуються за порядком номерів. Перший збіг перемагає, тому специфічні правила ставлять вище загальних. Налаштування перевіряють перед тим, як переключати бойовий трафік через реплікацію master-slave, щоб проксі бачив актуальний список реплік.
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES (100, 1, '^SELECT.*FOR UPDATE', 10, 1);
INSERT INTO mysql_query_rules(rule_id, active, match_pattern, destination_hostgroup, apply)
VALUES (200, 1, '^SELECT', 20, 1);
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL QUERY RULES TO DISK;Як перевірити, що балансування працює
Після завантаження правил варто поспостерігати за статистикою проксі: скільки запитів пішло на кожен hostgroup і чи немає помилок підключення до реплік. У разі налаштованої GTID-реплікації, ProxySQL уміє автоматично визначати зміну майстра через модуль ProxySQL Cluster або скрипт-перевірку.
- Таблиця stats_mysql_query_digest показує, які запити і на який hostgroup ідуть найчастіше.
- Таблиця mysql_server_connect_log фіксує помилки підключення до серверів.
- Команда SHOW MYSQL STATUS в інтерфейсі 6032 виводить лічильники активних з'єднань.
Поширені помилки під час налаштування ProxySQL
Більшість проблем пов'язана не із самим проксі, а з оточенням навколо нього.
- Пароль користувача в mysql_users не збігається з паролем на сервері MySQL — з'єднання падає з помилкою доступу.
- Забули виконати LOAD ... TO RUNTIME — зміни видно в конфігурації, але вони не застосовуються до трафіку.
- Репліка відстає від майстра, а SELECT пішов на неї — застосунок читає застарілі дані. Тут допомагає моніторинг затримки реплікації.
- Ліміт max_connections на сервері MySQL менший, ніж сумарне навантаження від проксі — зростає кількість помилок Too many connections.
Підсумок: чек-лист впровадження ProxySQL
- Встановити ProxySQL і перевірити доступ до портів 6032 та 6033.
- Додати сервери в mysql_servers із правильними hostgroup_id.
- Синхронізувати користувачів і паролі з реальними серверами MySQL.
- Написати query rules від часткових випадків до загальних і завантажити їх у runtime.
- Налаштувати перевірку статусу реплік і затримки перед бойовим запуском.