MariaDB Galera Cluster: высокая доступность и синхронная репликация для бизнес-приложений
Здравствуйте! Я Евгений Семенов, директор ITFresh. В IT я уже больше 15 лет, и за это время чего только не делал с MySQL и MariaDB-инсталляциями! Поверьте, это не только 'простенькие' серверы на офисных NAS, но и серьёзные трёхузловые Galera-кластеры, которые мы поднимали на Dell Xeon Platinum 8280 с 40G Mellanox прямо в дата-центре МТС. Знаете, на нашей практике одиночный MariaDB сервер обязательно 'сдастся' раз в 1,5-2 года. То диск 'умрет', то память, то обновление ядра 'поломает' систему. И ведь каждый такой сбой выливается в простой от часа до шести! Но Galera? Вот она-то и избавляет от таких 'сюрпризов' раз и навсегда.
Зачем нужен Galera Cluster
Galera Cluster – это не просто ещё один инструмент. Мы считаем его настоящим прорывом, полноценным расширением для MariaDB/MySQL! Он даёт нам синхронную мульти-мастер репликацию. Забудьте о старых master-slave схемах, где бэкап-сервер может отставать на минуты! Главное здесь: Galera подтверждает транзакцию завершенной только тогда, когда её 'одобрили' абсолютно все узлы. Понимаете? И вот именно это даёт нам сразу три ключевых преимущества.
- Zero data loss. Любой узел может умереть в середине транзакции — данные уже на остальных.
- Прозрачный failover. Приложение переключается на другой узел за секунду, без разбора бинлогов и promote.
- Горизонтальное масштабирование чтения. Все узлы отдают свежие данные.
Конечно, есть и небольшая 'плата': это лишний сетевой оверхед при каждом коммите. В локальной сети он составляет примерно 0,5–2 мс на транзакцию. Но для OLTP-приложений, где транзакции обычно маленькие, это вполне терпимо. Не критично.
Требования к инфраструктуре
| Параметр | Минимум | Рекомендация |
|---|---|---|
| Количество узлов | 3 | 3 или 5 |
| CPU на узел | 4 ядра | 8–16 ядер |
| RAM на узел | 8 ГБ | 32–64 ГБ |
| Диск | SSD SATA | NVMe |
| Сеть | 1 Гбит/с | 10+ Гбит/с, отдельный VLAN |
| Задержка между узлами | < 5 мс | < 1 мс |
Важный момент: если ваши узлы находятся на разных площадках, и задержка между ними превышает 10 мс — про Galera можно сразу забыть! В этом случае лучше выбрать асинхронную репликацию или MariaDB Replication Manager. Иначе просто не будет работать как надо.
Установка MariaDB на три узла
# На всех трёх узлах (Ubuntu 22.04)
apt update
curl -LsS https://r.mariadb.com/downloads/mariadb_repo_setup | \
sudo bash -s -- --mariadb-server-version="mariadb-10.11"
apt install mariadb-server mariadb-client galera-4
systemctl stop mariadb
Конфигурация кластера
Основной конфиг /etc/mysql/mariadb.conf.d/60-galera.cnf — одинаковый на всех узлах, кроме параметра wsrep_node_name и wsrep_node_address:
[galera]
wsrep_on = ON
wsrep_provider = /usr/lib/galera/libgalera_smm.so
wsrep_cluster_name = "office_cluster"
wsrep_cluster_address = "gcomm://10.0.10.11,10.0.10.12,10.0.10.13"
# Индивидуально на каждом узле
wsrep_node_name = "db01"
wsrep_node_address = "10.0.10.11"
wsrep_sst_method = mariabackup
wsrep_sst_auth = "sstuser:StrongPassword2026"
wsrep_slave_threads = 4
wsrep_provider_options = "gcache.size=2G; gcs.fc_limit=256"
binlog_format = ROW
default_storage_engine = InnoDB
innodb_autoinc_lock_mode = 2
innodb_flush_log_at_trx_commit = 2
innodb_buffer_pool_size = 16G
bind-address = 0.0.0.0
Первичный запуск кластера
# На первом узле инициализируем новый кластер
galera_new_cluster
# Проверяем
mysql -uroot -p -e "SHOW STATUS LIKE 'wsrep_%';"
# Создаём SST-пользователя
mysql -uroot -p -e "
CREATE USER 'sstuser'@'localhost' IDENTIFIED BY 'StrongPassword2026';
GRANT RELOAD, PROCESS, LOCK TABLES, BINLOG MONITOR ON *.* TO 'sstuser'@'localhost';
FLUSH PRIVILEGES;
"
# На втором и третьем узле — обычный старт
systemctl start mariadb
# Проверяем размер кластера
mysql -uroot -p -e "SHOW STATUS LIKE 'wsrep_cluster_size';"
# wsrep_cluster_size = 3 — всё хорошо
SST vs IST: передача состояния на новый узел
Представьте, новый узел хочет присоединиться к нашему кластеру. Ему же нужно 'знать' текущее состояние базы, верно? Здесь есть два пути: либо SST, когда берётся полная копия, либо IST – это когда передаётся только дельта, то есть разница. Сама Galera, исходя из размера gcache и того, насколько 'отстал' узел, решит, какой метод использовать. Умная штука.
Мы на практике всегда выбираем mariabackup для SST. Почему? Потому что он позволяет делать 'горячее' копирование, и никаких блокировок таблиц! Это же просто спасение. А вот rsync или mysqldump? Это совсем не то: они либо слишком медленные, либо полностью блокируют таблицы. Зачем нам такие проблемы?
# Увеличить gcache, чтобы IST работал чаще
# В 60-galera.cnf
wsrep_provider_options = "gcache.size=8G; gcache.page_size=128M; gcs.fc_limit=256"
Split-brain и восстановление после падения
А что, если сразу два узла из трёх 'упали' одновременно? Такое бывает. Тогда оставшийся узел, к сожалению, теряет кворум и переключается в режим non-primary. Важно понимать: в этот момент база начнёт выдавать ошибки на любой запрос. Это сделано специально, чтобы защититься от так называемого split-brain. Итак, что делать, чтобы всё снова заработало?
# Если мы уверены, что этот узел имеет самые свежие данные
mysql -uroot -p -e "SET GLOBAL wsrep_provider_options='pc.bootstrap=YES';"
# Или полный рестарт как нового кластера
# 1) Посмотреть /var/lib/mysql/grastate.dat на каждом узле
cat /var/lib/mysql/grastate.dat
# safe_to_bootstrap: 1 — можно запускать galera_new_cluster
# 2) Запускаем на узле с наиболее высоким seqno
galera_new_cluster
Наш совет: всегда держите под рукой готовый чек-лист восстановления, со всеми командами. Поверьте, в момент аварии вы будете благодарны себе за это. Руки точно не должны трястись от неуверенности.
MaxScale перед кластером
И вот ещё один критичный момент: ни в коем случае не подключайте ваше приложение напрямую ко всем трём узлам кластера! Честно говоря, это просто ужасная идея. Вы моментально получите ворох проблем: split-brain, конфликты данных, дедлоки... Разве вам это нужно? Единственное верное решение — поставить перед кластером специальный прокси. Он будет сам грамотно распределять все запросы. Например, на нашей практике MariaDB MaxScale, настроенный в режиме readwritesplit, показал себя просто идеально.
# Установка на отдельной виртуалке
apt install maxscale
# /etc/maxscale.cnf (фрагмент)
[server1]
type=server
address=10.0.10.11
port=3306
[Galera-Service]
type=service
router=readwritesplit
servers=server1,server2,server3
user=maxuser
password=MaxUserPass2026
[Galera-Listener]
type=listener
service=Galera-Service
protocol=MariaDBClient
port=3307
Как это работает? Очень просто. Приложение подключается к MaxScale на порт 3307. А дальше уже MaxScale 'решает', куда что отправить: все SELECT-запросы он направит на реплики, чтобы их не перегружать, а записи — только на primary-узел. Вся магия там.
Кейс: HA-кластер для корпоративного портала на 240 пользователей
Хотите реальный кейс? В марте 2026 года к нам обратилась крупная логистическая компания из Москвы. У них был веб-портал для заказов на PHP/Laravel, база MariaDB на 500 ГБ. Вся эта махина работала на одном-единственном сервере, да ещё и 'железо' 2018 года выпуска! Можете представить? В декабре, прямо в самый пик сезона, сервер просто 'лёг' на целых 7 часов. Убытки от простоя? Страшно сказать, но это около 3 миллионов рублей. Вот тут-то мы и внедрили им Galera-кластер.
Что мы сделали? Развернули три мощных виртуалки в дата-центре МТС. Каждая с 8 vCPU, 32 ГБ RAM и 1 ТБ NVMe — всё это на хостах Dell Xeon Platinum 8280, а связка между ними – 40G Mellanox! MaxScale мы вынесли на отдельную виртуалку, настроили там keepalived с VIP для мгновенного failover. В итоге, миграция данных заняла у нас всего 4 часа, а переключение всех порталов клиента — это был 'безболезненный' 20-минутный процесс в выходные.
Итак, какой же итог за первые 3 месяца эксплуатации? Просто отличный! Мы провели два плановых апдейта с rolling restart, и знаете что? Никакого простоя! И был один небольшой инцидент: упал узел из-за сбоя ZFS, но приложение клиента даже не 'почувствовало' этого. Считаем, что это показатель! Что касается стоимости: внедрение обошлось в 185 000 рублей, а ежемесячная поддержка — 35 000 рублей.
Мониторинг Galera
wsrep_cluster_size— число узлов в кластере (должно быть 3).wsrep_cluster_status— Primary при нормальной работе.wsrep_local_state_comment— Synced когда узел в строю.wsrep_flow_control_paused— процент времени flow control. Больше 10% = проблемы с отставанием узла.wsrep_cert_deps_distance— параллелизм репликации, растёт при нагрузке.
# В Zabbix/Prometheus через mariadb_exporter
# Алерты:
# wsrep_cluster_size != 3 — critical
# wsrep_cluster_status != "Primary" — critical
# wsrep_flow_control_paused > 0.1 — warning
Внедрение и сопровождение MariaDB Galera
Проектирую и разворачиваю Galera-кластеры под нагрузку от 100 до 10 000 запросов в секунду. Миграция с одиночной MariaDB, настройка MaxScale/ProxySQL, мониторинг, план аварийного восстановления. Инсталляции в дата-центре МТС на оборудовании Dell Xeon Platinum 8280.
Телефон: +7 903 729-62-41
Telegram: @ITfresh_Boss
Семёнов Евгений Сергеевич, директор АйТи Фреш
FAQ — MariaDB Galera Cluster
- Почему для Galera нужно минимум 3 узла?
- Galera требует кворум. При двух узлах разрыв сети приведёт к split-brain. Три узла гарантируют работу при падении любого одного.
- Что такое SST и IST?
- SST — полная передача базы новому узлу. IST — только недостающие транзакции из gcache.
- Можно ли писать на все узлы?
- Технически да, но это ведёт к deadlock-ам. Настраивайте MaxScale с одним активным писателем.
- Как восстановить кластер после полной остановки?
- Найти узел с наиболее свежими данными (по grastate.dat) и запустить galera_new_cluster. Остальные присоединятся обычным стартом.
- Подходит ли Galera для 1С?
- Нет, 1С не работает с MariaDB. Для корпоративных порталов и CRM — отличный выбор.
