Когда приложение упирается в лимиты подключений, когда нужно прозрачно разделять чтение и запись, переживать переключения мастер‑узла без простоя и держать под контролем задержки репликации — в игру вступает MySQL‑прокси. На рынке два де‑факто стандарта: MariaDB MaxScale и ProxySQL. Оба решают похожие задачи (read/write split, connection pooling, failover), но делают это по‑разному и адресуют разные приоритеты. В обзоре собрал практические отличия, грабли и рекомендации, как выбрать инструмент под вашу архитектуру.
Зачем вообще нужен MySQL‑прокси
Приложения (особенно PHP‑FPM, Node.js и микросервисы) часто создают всплески соединений. Нативный пуллинг MySQL‑клиента редко спасает, а грамотная маршрутизация запросов к мастер/репликам требует логики, которой лучше заниматься вне приложения. Прокси берёт на себя:
- connection pooling и multiplexing для снижения количества реальных подключений к бэкендам;
- read/write split с соблюдением консистентности «read‑your‑writes»;
- healthchecks, failover и «чёрные списки» проблемных реплик;
- query routing по правилам, тегам, комментариям и метаданным;
- умное ограничение трафика, защита от тяжёлых запросов, кэширование результатов;
- единый эндпоинт для приложений с прозрачной сменой топологии.
Архитектура и модель конфигурации
ProxySQL
ProxySQL — высокопроизводительный MySQL‑прокси, написанный на C++. Конфигурация живёт в встроенных таблицах (админ‑интерфейс говорит на MySQL‑протоколе): вы вносите изменения SQL‑командами, грузите их в runtime и сохраняете на диск. Это даёт удобные атомарные изменения, версионирование и откаты. Ключевые сущности — mysql_servers (бэкенды), hostgroups (группы writer/reader), mysql_query_rules (маршрутизация), mysql_users (пользователи и параметры пула). Есть встроенный монитор бэкендов, поддержка replication hostgroups, Galera и настройки для переключений.
MariaDB MaxScale
MaxScale — модульная платформа проксирования от MariaDB. Конфиг в INI‑подобном файле: разделы для servers, monitors, services, listeners, filters. Плагинная архитектура: readwritesplit, schemarouter, binlogrouter, masking, tee, cache и др. Управление через утилиту MaxCtrl и REST API, горячее применение части настроек. MaxScale особенно глубоко понимает репликацию MariaDB/Galera и предоставляет богатые мониторы топологии.
Если вам близка «конфигурация как данные» и удобные SQL‑миграции параметров — ProxySQL. Если нужна модульная архитектура с фильтрами, CDC/бинлогом и тесной интеграцией с MariaDB — присмотритесь к MaxScale.

Read/Write split и консистентность
Оба прокси поддерживают read/write split. Ключевой вопрос — «read‑your‑writes»: как обеспечить, чтобы после INSERT/UPDATE приложение читало собственные изменения, не попав на отстающую реплику.
- ProxySQL: маршрутизирует по правилам (регексы, заголовки, комментарии), поддерживает «transaction stickiness»: пока открыта транзакция, сессия закреплена за writer. Можно учитывать задержку репликации и принудительно отправлять SELECT на writer при превышении порога. Есть комментарии‑подсказки для выборочной маршрутизации.
- MaxScale:
readwritesplitотслеживает команды протокола, транзакционную семантику и может принудительно маршрутизировать SELECT на master после записи в пределах настраиваемого окна. Поддерживает маршрутизацию с учётом «weights», нагрузки и lag из мониторинга.
В 90% PHP‑проектов надёжнее включать режим «все запросы внутри транзакции на writer», а вне транзакций — читать с реплик с ограничением по лагу. Оба прокси это умеют.
Connection pooling и multiplexing
Пуллинг — одна из главных причин ставить прокси: он сглаживает всплески подключений, экономит дескрипторы и снижает CPU/контекст‑свитчи на СУБД. Здесь ProxySQL исторически силён: гибкие лимиты соединений на пользователя/хостгруппу, условное мультиплексирование (сессии отдаются в пул, если нет открытых транзакций/prepared‑состояния), агрессивные таймауты и защита от штормов соединений. MaxScale также реализует пулы, но UX и глубина тюнинга обычно скромнее, зато есть фильтры для дополнительного контроля (например, ограничение сложных запросов до бэкенда).
Если основная боль — «слишком много соединений» и непредсказуемые пики от веб‑приложений, ProxySQL даёт очень тонкие ручки. Если важнее конвейер фильтров и комплексные политики на уровнях сервисов — MaxScale.
Failover, мониторинг топологии и совместимость
Failover бывает автоматический и управляемый снаружи (например, через Orchestrator или скрипты). Оба прокси поддерживают собственные мониторы и переключения.
- ProxySQL: режимы для классической репликации, GTID, Galera; здоровье и lag в таблицах статистики; можно делегировать промоушен внешним инструментам, а прокси только переобучать на новый writer. Встроенный scheduler для периодических задач.
- MaxScale: мониторы mariadbmon и galeramon умеют детектировать роль узлов, лаг, сетевые проблемы и автоматически переключать мастер. Поддерживаются принципы «демоушен»/«реабилитация» узлов, чёткая интеграция с MariaDB‑фичами.
По совместимости ProxySQL более «нейтрален»: Oracle MySQL, Percona Server, MariaDB, Aurora MySQL; у MaxScale фокус на MariaDB, но он работает и с MySQL‑совместимыми кластерами (детали мониторинга могут отличаться). Если строите отказоустойчивость на GTID и семисинхронной репликации, загляните в разбор семисинхронного GTID‑failover. Для кластеров Galera пригодится обзор MariaDB Galera Cluster.
Маршрутизация запросов и политика
ProxySQL даёт мощную систему mysql_query_rules: матчинги по регексу, user/schema, длине запроса, комментариям, хинтам, TTL кэша для конкретных шаблонов, «stickiness» и приоритеты. Это удобно для точечных правил, канареек, обхода проблемных реплик и feature‑флагов на уровне SQL. MaxScale реализует маршрутизацию через роутеры и фильтры: readwritesplit, schemarouter, regex filter, tee для дубля запроса на аналитический контур, masking для сокрытия полей. Для многих задач достаточно включить нужный фильтр и описать список.
Кэширование на уровне прокси
У обоих решений есть кэш результатов. ProxySQL поддерживает кэш по правилам (SQL‑шаблоны, TTL), хранит в памяти — удобно для часто повторяющихся SELECT с короткой свежестью (например, справочники). MaxScale имеет cache filter с возможностью хранения в памяти или на диске, тонкой инвалидацией и политиками согласованности. Если кэш — критичная часть архитектуры и нужна гибкая инвалидация, MaxScale предлагает более «коробочное» решение, но в большинстве сценариев кэша ProxySQL достаточно.

Наблюдаемость и эксплуатация
ProxySQL предоставляет богатые таблицы статистики (latency per backend/rule, количество соединений, ошибки, переполнения пулов). Админ‑порт — это MySQL‑интерфейс, так что метрики можно забирать теми же инструментами, что и для СУБД. Горячая смена конфигурации (load to runtime, save to disk) — сильная сторона. MaxScale даёт REST API, MaxCtrl, расширенную телеметрию по сервисам, фильтрам и роутерам. Оба неплохо интегрируются с экосистемой мониторинга через экспортеры и плагины.
Безопасность, TLS и SQL‑санитария
Оба прокси поддерживают TLS между клиентом и прокси, а также прокси и бэкендом, верификацию сертификатов и отдельные списки разрешённых шифров. Для SQL‑санитарии: ProxySQL способен блокировать запросы по правилам (регексы, длина, типы), лимитировать heavy‑SELECT; MaxScale имеет фильтры на уровне протокола, включая masking и firewall‑подобные политики. Если у вас жёсткие требования к шифрованию, оформите действующие SSL-сертификаты для MySQL‑трафика и включите проверку цепочки на обоих плечах.
Производительность и накладные расходы
Оба решения стремятся к минимальной латентности и высокой пропускной способности. На практике накладные расходы определяются активными функциями: мультиплексирование, фильтры, кэширование, сложные правила. ProxySQL обычно демонстрирует отличные результаты в сценариях высокой конкаррентности с интенсивным пуллингом, MaxScale — стабильно быстрый и предсказуемый при сложной маршрутизации и цепочках фильтров. Любые цифры зависят от паттернов запросов, RTT до бэкендов и параметров TCP, поэтому бенчмаркйте на своей нагрузке.
Лицензирование и поддержка
ProxySQL распространён как open source, вокруг него активное комьюнити и коммерческая поддержка от интеграторов. MariaDB MaxScale — исходники доступны, лицензия с условиями коммерческого использования в продакшене (BSL‑модель, меняющаяся со временем). Если важна формальная поддержка в одном вендоре для MariaDB‑стека, аргумент в пользу MaxScale. Если нужен максимально свободный стек и независимость — аргумент в пользу ProxySQL.
Практические сценарии выбора
- Нужно быстро снять проблему с «too many connections», приручить PHP‑FPM шторма, добавить read/write split и простые правила: чаще подойдёт ProxySQL.
- Нужна конвейерная обработка запросов (masking, tee, cache), тесная интеграция с MariaDB/Galera и управление через единый роутер/монитор: чаще MaxScale.
- Множественные кластера (MySQL, Percona, MariaDB), гибкие правила на уровне запросов, feature‑флаги и канарейки на SQL: ProxySQL.
- Требуется binlog/CDC на уровне прокси, фильтрация и аудирование: MaxScale.
Минимальные примеры конфигурации
ProxySQL: два хоста, writer+reader, read/write split
-- Админ-подключение к ProxySQL и базовые параметры
-- Добавляем сервера и хостгруппы
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections) VALUES (10, 'db-writer', 3306, 200);
INSERT INTO mysql_servers (hostgroup_id, hostname, port, max_connections) VALUES (20, 'db-reader1', 3306, 200);
-- Пользователь приложения
INSERT INTO mysql_users (username, password, default_hostgroup, transaction_persistent, max_connections) VALUES ('app', 'secret', 10, 1, 200);
-- Связка хостгрупп репликации (writer/readers)
INSERT INTO mysql_replication_hostgroups (writer_hostgroup, reader_hostgroup, check_type, max_writers, writer_is_also_reader) VALUES (10, 20, 'read_only', 1, 0);
-- Маршрутизация: записи на writer, SELECT вне транзакций на reader
INSERT INTO mysql_query_rules (rule_id, match_pattern, destination_hostgroup, apply) VALUES (1, '^SELECT', 20, 1);
INSERT INTO mysql_query_rules (rule_id, match_pattern, destination_hostgroup, apply) VALUES (2, '^(INSERT|UPDATE|DELETE|REPLACE|BEGIN|COMMIT|ROLLBACK)', 10, 1);
-- Порог лага: при превышении шлём SELECT на writer
SET mysql-monitor_replication_lag_interval = 1000;
UPDATE global_variables SET variable_value='1000' WHERE variable_name='mysql-monitor_connect_interval';
-- Загрузить в runtime и сохранить
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;
MariaDB MaxScale: readwritesplit с монитором
[maxscale]
threads=auto
[db1]
address=db-writer
port=3306
protocol=MariaDBBackend
[db2]
address=db-reader1
port=3306
protocol=MariaDBBackend
[MariaDB-Monitor]
type=monitor
module=mariadbmon
servers=db1,db2
user=maxscale_mon
password=secret
monitor_interval=1000ms
[RWS-Service]
type=service
router=readwritesplit
servers=db1,db2
user=app
password=secret
max_slave_replication_lag=1s
transaction_replay=true
[RWS-Listener]
type=listener
service=RWS-Service
protocol=MariaDBClient
port=4006
Это лишь стартовые точки. На проде вы добавите TLS, healthcheck‑параметры, таймауты, лимиты соединений, правила обхода реплик с большим lag и худшими метриками.
Консистентность и подводные камни
- Транзакции: любая «утечка» транзакции (неявный BEGIN) ломает мультиплексирование и может вызывать неожиданные задержки. Следите за автокоммитом и поведением драйверов.
- Prepared statements: часть клиентов держит prepared‑состояние, что снижает эффект multiplexing. Проксируйте с учётом этого и поднимайте больше соединений к бэкендам.
- Репликационный lag: не меряйте только Seconds_Behind_Master, агрегируйте метрики на прокси, учитывайте лаг в правилах маршрутизации.
- Большие SELECT: лимитируйте время и размер ответов, применяйте кэширование, не бойтесь принудительно отправлять такие запросы на writer при необходимости согласованности.
HA самого прокси
Прокси — это новый слой. Чтобы не превратить его в SPOF, ставьте минимум два экземпляра с балансировкой на уровне L4/L7, VIP или DNS‑rotation. Оба решения поддерживают конфигурацию в стиле Active‑Active. Следите за симметрией конфигов, синхронизируйте изменения (для ProxySQL — экспорт/импорт таблиц конфигурации; для MaxScale — конфиг‑файлы и MaxCtrl/REST). Не забывайте про health‑checks на уровень выше (reverse‑proxy/ingress), чтобы исключать деградировавшие экземпляры прокси. Чаще всего прокси размещают на отдельном VDS рядом с СУБД по сети с минимальным RTT.
Тюнинг по шагам
- Начните с чистого read/write split без кэша и сложных фильтров. Проверьте латентность и нагрузку на бэкенд.
- Включите адаптивный pooling и multiplexing, найдите баланс таймаутов и лимитов соединений.
- Добавьте защитные правила: reject тяжёлых запросов, ограничение размера ответов, маршрутизация по lag.
- Подключите кэш для горячих SELECT с коротким TTL. Измерьте hit‑ratio и латентность.
- Постройте оповещения по метрикам прокси: рост ошибок руля, переполнения пула, ухудшение P95.
Миграция без простоя
Классический путь: развернуть прокси параллельно, направить на него тестовый трафик с canary‑подсетей/инстансов, включить диагностический режим (tee/логирование), проверить корректность маршрутизации и только потом переключить основной трафик. Обратно совместимое TLS и повторная проверка прав пользователей обязательны. Для ProxySQL удобно применять миграции конфигурации SQL‑скриптами; для MaxScale — подготовить конфиг и сценарий развёртывания с шаблонизацией.
Краткая матрица выбора
- Главная боль — connection pooling и гибкие правила на уровне SQL: ProxySQL.
- Нужны фильтры, CDC/бинлог‑маршрутизация и плотная интеграция с MariaDB/Galera: MaxScale.
- Гетерогенные кластера и vendor‑neutral подход: ProxySQL.
- Единая поддержка от вендора MariaDB и коробочные политики безопасности: MaxScale.
Выводы
ProxySQL и MariaDB MaxScale — зрелые и производительные решения класса mysql proxy. Оба умеют read/write split, failover, connection pooling и широкий спектр политик. Разница — в философии: ProxySQL — это «конфигурация как данные», агрессивная оптимизация соединений и чрезвычайно гибкая маршрутизация. MaxScale — модульный конвейер с фильтрами, богатой осведомлённостью о MariaDB‑топологиях и удобными сервисами поверх протокола. Правильный выбор — не «кто быстрее на синтетике», а «кто проще и надёжнее решит ваши конкретные требования» и лучше впишется в ваш процесс эксплуатации, мониторинга и обновлений.


