Балансировка нагрузки на кластер MySQL с помощью HAProxy

Введение

Как правило, приложение взаимодействует с кластером, устанавливая соединение с одним из доступных узлов. Если узел базы данных становится недоступен, приложение должно переподключиться к другому узлу базы данных, чтобы продолжать обрабатывать запросы.

Существуют различные способы обеспечения отказоустойчивого соединения с одним или несколькими серверами базы данных MySQL. Один из них заключается в использовании драйвера базы данных, поддерживающего пул соединений, балансировку нагрузки и отработку отказа, например:

  • драйвер JDBC для MySQL (MySQL Connector/J);
  • драйвер, используемый по умолчанию в PHP MySQL для master-slave (mysqlnd-ms).

Эти драйверы позволяют обеспечить прозрачность подключения клиентов к автономному серверу MySQL, решению MySQL Cluster (NDB) или топологии, использующим репликацию MySQL.

Однако при использовании этих драйверов с кластером Galera для MySQL или MariaDB есть ряд проблем, так как они не обладают расширенной информацией о состоянии Galera. Например, узел-донор Galera может находиться в режиме «только для чтения» , когда помогает другому узлу повторно синхронизироваться (если для передачи снимка состояния (SST) используется mysqldump или rsync), или в случае split brain он может быть в состоянии Non-Primary. То есть, существуют случаи, когда даже драйверы с поддержкой пуллинга и балансировки не предоставляют необходимый уровень поддержки кластера.

Часто используемое альтернативное решение заключается в применении балансировщика нагрузки между клиентами и кластером базы данных. Из этой статьи вы узнаете, как с помощью ClusterControl развернуть, настроить и управлять балансировкой нагрузки MySQL с использованием HAProxy.

Статья является переводом и адаптацией англоязычного руководства от Severalnines — разработчика инструмента ClusterControl.

Что такое HAProxy?

HAProxy, или High Availability Proxy, является программным балансировщиком нагрузки TCP/HTTP. Он распределяет рабочую нагрузку по серверам для обеспечения максимальной производительности и оптимизации использования ресурсов. HAProxy поддерживает гибко настраиваемые методы проверки доступности, обработки отказов и восстановления после них.

Приложение, использующее базу данных, может легко перенасытить ее слишком большим количеством одновременно работающих соединений. HAProxy обеспечивает организацию очереди и регулирование соединений с одним или несколькими серверами MySQL и предотвращает перегрузку одного сервера слишком большим количеством запросов. Все клиенты подключаются к экземпляру HAProxy, а обратный прокси-сервер пересылает подключение к одному из доступных серверов MySQL на основе используемого алгоритма распределения нагрузки.

В одном из вариантов настройки HAProxy устанавливается на каждом сервере приложений, выполняющем запросы к базе данных. Такой вариант отлично подходит при наличии нескольких серверов, что позволяет контролировать нагрузку и скрыть организацию кластера СУБД. Приложение подключается к локальному HAProxy (например, устанавив mysql-соединение на 127.0.0.1:3306) и может получить доступ ко всем серверам базы данных. Веб-сервер и HAProxy вместе образуют рабочий блок, поэтому веб-сервер не будет работать, если HAProxy недоступен.

Использование HAProxy для балансировки нагрузки дает следующие преимущества:

  • Все приложения получают доступ к кластеру через указанные IP-адреса. Внутренняя топология кластера базы данных скрывается за HAProxy.
  • Соединения MySQL распределены между доступными узлами БД.
  • Можно добавлять или удалять узлы базы данных без необходимости внесения каких-либо изменений в приложения.
  • Как только достигается максимальное количество соединений с базой данных, новые соединения ставятся в очередь. Это удобный способ ограничения количества запросов на соединение с базой данных, обеспечивающий защиту от перегрузки.

ClusterControl поддерживает развертывание HAProxy из пользовательского интерфейса, поддерживая стандартные алгоритмы балансировки, предоставляемые HAProxy:

  • Round Robin. Каждый сервер получает запросы пропорционально своему весу, при этом веса серверов могут меняться на лету.
  • Least Connection. Выбирается сервер с наименьшим количеством активных соединений.
  • Source Hash Scheduling. Сервер для соединения назначается на основе хэша IP-адреса отправителя запроса и весов серверов.

Подробную информацию о каждом алгоритме можно найти в документации HAProxy.

Проверка доступности сервера MySQL

HAProxy может проверить доступность сервера, просто подключившись к порту MySQL (обычно 3306), однако часто этого недостаточно. Возможна ситуация, когда экземпляр запущен, но не может корректно обслуживать запросы. Тогда необходимо выполнить определенные проверки в зависимости от типа кластера — Galera, репликации MySQL или MySQL Cluster.

Скрипт проверки на доступность

Лучший способ проверить, доступен ли сервер MySQL — использовать сценарий, который определяет доступность сервера путем изучения его внутреннего состояния, которое зависит от используемого решения кластеризации. ClusterControl предоставляет собственную версию скрипта проверки на доступность под названием mysqlchk. Он располагается на каждом сервере MySQL, участвующем в балансировке нагрузки, и возвращает код состояния HTTP и/или результат в стандартном потоке вывода (stdout), что полезно для проверки доступности TCP.

Использование mysqlchk для Galera Cluster

Если сервер MySQL исправен, сценарий вернет код состояния HTTP 200 OK с кодом завершения 0. В противном случае вернется HTTP 503 Service not available и код завершения равный 1. Использование xinetd — самый простой способ обеспечить выполнение скрипта проверки на доступность. HAProxy подключается к порту, на котором запущен скрипт, выполняемый в рамках xinetd, и запрашивает статус доступности.

Если в качестве метода проверки используется httpchk, HAProxy будет проверять код состояния HTTP, а если используется tcp-check, он будет проверять наличие ожидаемой строки в потоке данных.

На схеме ниже показан процесс проверки на доступность узла Galera для кластера multi-master:

Файл шаблона скрипта находится на сервере ClusterControl по адресу /usr/share/cmon/templates/mysqlchk.galera. ClusterControl автоматически устанавливает cкрипт mysqlchk на каждый узел, участвующий в балансировке нагрузки.

Использование mysqlchk для кластера с репликацией MySQL

Этот скрипт основан на стандартном mysqlchk, но предназначен для корректного мониторинга бэкенд-серверов, использующих репликацию MySQL. Шаблон доступен в хранилище Github, можно использовать его вместо шаблона по умолчанию в /usr/share/cmon/templates/mysqlchk.mysql до начала развертывания HAProxy. Как и в случае mysqlchk для Galera Cluster, для выполнения скрипта проверки доступности потребуется xinetd.

Скрипт определяет роль репликации MySQL согласно схеме ниже:

Настройка HAProxy для кластера с репликацией MySQL требует двух разных обработчиков HAProxy, например, порт 3307 для записи в Master и порт 3308 для чтения со всех доступных Slave-узлов (включая Master).

Использование mysqlchk-iptables для Galera Cluster

Это фоновый скрипт, который проверяет доступность узла Galera и добавляет порт перенаправления, используя iptables, если узел Galera доступен (вместо возврата HTTP-ответа). Это позволяет другим балансировщикам нагрузки TCP с более ограниченными возможностями проверки на доступность правильно контролировать бэкенд-серверы Galera.

При использовании mysqlchk-iptables вместо HAProxy можно использовать любой обратный прокси-сервер для балансировки запросов между узлами Galera, а именно:

  • nginx 1.9 (—with-stream)
  • keepalived
  • IPVS
  • distributor
  • balance
  • pen

В этой статье мы не будем рассматривать данный скрипт проверки на доступность, поскольку он создан для балансировщиков нагрузки, отличных от HAProxy. Подробнее о нем читайте в отдельной статье.

Способы проверки доступности

HAProxy определяет доступность сервера, выполняя операцию проверки доступности. HAProxy поддерживает несколько методов проверки бэкенда на доступность, которые можно активировать посредством следующих опций:

  • mysql-check
  • tcp-check
  • httpchk

Проверка mysql-check

Проверка состоит из отправки двух пакетов MySQL: пакета аутентификации клиента и пакета QUIT, чтобы правильно закрыть сеанс MySQL. Затем HAProxy анализирует пакет инициализации «рукопожатия» MySQL и/или пакет ошибок. Это простой, но полезный тест, который позволяет убедиться в том, что соединение с сервером MySQL осуществимо. Для его работы необходимо добавить пользователя MySQL, например так:

USE mysql;
INSERT INTO user (Host,User) values ('<ip_of_haproxy>','<username>');
FLUSH PRIVILEGES;

Обратите внимание, что он не проверяет наличие или согласованность базы данных. Для этого необходимо использовать внешнюю проверку (через xinetd), которая описана в следующем разделе.

Проверка tcp-check

По умолчанию, сервер считается доступным тогда, когда он может принимать периодические TCP-соединения. Это недостаточно надежно, поскольку сервер базы данных может отвечать на запросы на подключение, даже находясь в нерабочем состоянии. Кроме того, существуют проверки, которые необходимо выполнить в зависимости от типа кластеризации — Galera или MySQL Cluster (NDB).

Скрипт mysqlchk, предоставляемый ClusterControl, поддерживает возврат кода состояния HTTP и стандартный вывод (stdout). Используя tcp-check и анализ стандартного вывода, можно расширить возможности скрипта, чтобы обеспечить бОльшую точность определения состояния узла репликации Galera или MySQL. Пример конфигурации ниже демонстрирует использование скрипта:

listen  haproxy_192.168.55.110_3307
        bind *:3307
        mode tcp
        timeout client  10800s
        timeout server  10800s
        balance leastconn
        option tcp-check
        tcp-check expect string is\ running.
        option allbackups
        default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
        server galera1 192.168.55.111:3306 check
        server galera2 192.168.55.112:3306 check
        server galera3 192.168.55.113:3306 check

Приведенные выше строки конфигурации говорят HAProxy, что нужно выполнить проверку доступности с использованием последовательной отправки/ожидания TCP. Он подключается к порту 9200 базы данных и ожидает строку, содержащую «is running». Чтобы проверить вывод mysqlchk, установите подключение по telnet к узлу базы данных от узла HAProxy:

$ telnet 192.168.55.111 9200
Trying 192.168.55.171...
Connected to 192.168.55.171.
Escape character is '^]'.
HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 43
 
<html><body>MySQL is running.</body></html>
 
Connection closed by foreign host.

Можно использовать аналогичную конфигурацию для репликации MySQL, где ожидается строка для Master — «MySQL Master is running». По умолчанию ClusterControl использует httpchk, как описано в следующем разделе.

Проверка httpchk

Для проверки доступности сервера метод httpchk использует статусы протокола HTTP. Использование httpchk является предпочтительным вариантом, поскольку при HTTP-соединении без хранения состояния используется меньше ресурсов.

listen  haproxy_192.168.55.110_3307
        bind *:3307
        mode tcp
        timeout client  10800s
        timeout server  10800s
        balance leastconn
        option httpchk
        option allbackups
        default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
        server galera1 192.168.55.111:3306 check
        server galera2 192.168.55.112:3306 check
        server galera3 192.168.55.113:3306 check

В приведенном выше примере HAProxy будет подключаться к порту 9200, где под управлением xinetd выполняется скрипт проверки доступности. HAProxy будет анализировать статус HTTP. Если сервер исправен, скрипт mysqlchk вернет HTTP 200 OK, в ином случае — HTTP 503 Service not available.

Обнаружение сбоев обслуживания и отказоустойчивость

Когда происходит сбой в работе узла базы данных, соединения, открытые на этом узле, становятся недоступны. Важно, чтобы HAProxy не перенаправлял новые запросы на подключение к отказавшему узлу.

Существует несколько пользовательских параметров, которые определяют, насколько быстро HAProxy сможет обнаружить, что сервер недоступен. Ниже приведен пример конфигурации HAProxy, развернутой ClusterControl и расположенной в /etc/haproxy/haproxy.cfg:

listen  haproxy_192.168.55.110_3307
        bind *:3307
        mode tcp
        timeout client  10800s
        timeout server  10800s
        balance leastconn
        option httpchk
        option allbackups
        default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
        server galera1 192.168.55.111:3306 check
        server galera2 192.168.55.112:3306 check
        server galera3 192.168.55.113:3306 check

Краткое объяснение каждой строки выше:

  • Раздел listen описывает полный прокси-сервер с его внешними и внутренними частями, объединенными в одном разделе. Здесь же указывается имя экземпляра HAproxy. Следующая строка, описывающая раздел, должна начинаться с отступа.
  • Параметр bind определяет, на каком IP и порту будут обслуживаться запросы от клиентов. В примере указана привязка ко всем IP-адресам на этом хосте через порт 3307. Клиенты должны будут подключиться к порту, заданному в этой строке.
  • Параметр mode задает режим работы HAProxy. Для MySQL экземпляр должен работать в режиме чистого TCP. Будет установлено полнодуплексное соединение между клиентами и серверами, а проверка трафика Layer 7 не будет проводиться.
  • Параметр timeout client определяет максимальное время бездействия на стороне клиента. Рекомендуется задать то же значение, что и для timeout server.
  • Параметр timeout server — максимальное время бездействия на стороне сервера. Рекомендуется задать то же значение, что и для timeout client.
  • Параметр balance определяет алгоритм балансировки нагрузки. ClusterControl поддерживает такие алгоритмы, как Round Robin, Least Connection и Source Hash Scheduling. Least Connection является наиболее предпочтительным вариантом, так как тогда соединение будет устанавливливаться с сервером базы данных с наименьшим числом соединений.
  • Опция option httpchk — задает способ проверки на доступность бэкенда. Позволяет выполнить проверку доступности на основе HTTP. ClusterControl настраивает скрипт, работающий под управлением xinetd, на каждом сервере СУБД, участвующем в балансировке.
  • Опция option allbackups определяет такое поведение, что когда основные серверы недоступны, балансировка нагрузки будет выполняться между backup-серверами.
  • Параметр default-server определяет свойства по умолчанию для серверов, перечисленных в опции server.
    • Атрибут port порт проверки на доступность бэкенда. ClusterControl настраивает процесс xinetd так, чтобы он выполнял скрипт проверки на порту 9200 на каждом сервере базы данных.
    • Inter: интервал между проверками, в примере он составляет 2 секунды.
    • Downinter: интервал между проверками, когда сервер недоступен. В примере он составляет 5 секунд, после чего сервер считается недоступен.
    • Rise: количество проверок, которые должен пройти сервер, чтобы получить статус доступного к работе. Сервер будет считаться доступным после 3 последовательных успешных проверок на доступность.
    • Fall: количество проверок, которые должен пройти сервер, чтобы получить статус отказавшего. Сервер будет считаться недоступным после 2 последовательных неудачных проверок на доступность.
    • Slowstart: через 60 секунд число принятых сервером соединений после перехода в состояние доступности увеличится с 1 до 100% от стандартного динамического предела.
    • Maxconn: HAProxy прекратит принимать соединения, когда число соединений составит 64.
    • Maxqueue: максимальное количество соединений для этого сервера, которые будут ожидать в очереди. При достижении заданного лимита, следующие запросы будут пересылаться на другие серверы, а не ожидать обслуживания неопределенное количество времени.
    • Weight: в Galera все узлы обычно обрабатываются имеют один вес и равнодоступны.
  • Параметр server определяет имя сервера, IP-адрес, порт и параметры сервера. В примере также с помощью опции проверки на каждом сервере добавлена проверка на доступность. Неуказанные параметры такие же, как и у default-server.

Согласно приведенным выше настройкам сервер MySQL не проходит проверку на доступность, когда:

  • HAProxy не смог подключиться к порту 9200 сервера MySQL;
  • подключение к порту 9200 устанавливается, но возвращает код ответа HTTP, отличный от «HTTP/1.1 200 OK» (метод httpchk).

Логика обработки состояний отказа и доступности следующая:

  • Каждые 2 секунды HAProxy выполняет проверку на доступность порта 9200 внутреннего сервера (port 9200 inter 2s).
  • Если проверка на доступность не пройдена, начинается отсчет fall. Через 5 секунд, если вторая попытка оказалась безуспешной, HAProxy отметит сервер MySQL как недоступный (downinter 5s ... fall 2).
  • Cервер MySQL автоматически исключается из списка доступных серверов.
  • Как только сервер MySQL возвращается в рабочий режим, если проверка на доступность завершается успешно, запускается отсчет rise, который проверяет, была ли успешной следующая по порядку попытка подключения. Если количество успешных ответов достигнет 3, сервер будет считаться доступным (rise 3).
  • Сервер MySQL автоматически включается в список доступных серверов.
  • Сервер MySQL начинает постепенно принимать соединения в течение 60 секунд (slowstart 60s).
  • Сервер MySQL полноценно работает.

Разделение операций чтения/записи с помощью HAProxy

HAProxy как балансировщик нагрузки MySQL работает на уровне TCP. Он не понимает запросы MySQL, которые работают на более высоком уровне и пересылаются серверам MySQL. В связи с этим HAProxy пользуется особой популярностью в рамках установок с репликацией multi-master, таких как Galera Cluster и MySQL Cluster, где все бэкенд-серверы MySQL равнодоступны. Все серверы MySQL могут обрабатывать перенаправленные операции чтения/записи. Работа на транспортном уровне также требует меньше вычислительных затрат по сравнению с балансировкой нагрузки обратным прокси, понимающим запросы SQL, таким как MaxScale или ProxySQL.

Все же это не означает, что HAProxy не подходит для установок с репликацией master-slave. Однако, распределение операций в этом случае происходит сложнее. Операции записи направляются только на Master, в то время как операции чтения могут быть направлены любому узлу, пока узел не начинает отставать.

Чтобы HAProxy мог обрабатывать операции чтения и записи по отдельности, необходимо:

  • Настроить проверку на доступность и роль сервера MySQL. Скрипт проверки должен:
    • сообщить о роли в репликации (master, slave или none);
    • сообщить об отставании узла slave (если есть slave);
    • должен быть доступен через HAProxy (настраивается через xinetd или порт пересылки).
  • Создать два обработчика HAProxy, один для чтения и один для записи:
    • обработчик операций чтения служит для передачи всем узлам запросов чтения;
    • обработчик операций записи служит для передачи операций записи единственному Master.
  • Модифицировать приложение, для поддержки отправки операции чтения и записи соответствующему обработчику:
    • создайте/измените приложение, чтобы отправлять операции чтения и записи соответствующим обработчикам;
    • используйте коннектор приложения, который поддерживает встроенное разделение для операций чтения/записи. Для Java можно использовать Connector/J, для PHP — php-mysqlnd для master-slave. Это сведет к минимуму изменения на стороне приложения.

Интеграция HAProxy с ClusterControl

ClusterControl интегрирован с HAProxy для упрощения развертывания и управления балансировщиком нагрузки в сочетании с кластерным бэкендом MySQL, таким как Galera или MySQL NDB Cluster. Также можно добавить существующий/уже развернутый экземпляр HAProxy в ClusterControl, чтобы отслеживать и управлять им напрямую из пользовательского интерфейса ClusterControl.

Для настройки HAProxy перейдите в ClusterControl > Manage > Load Balancer > Install HAProxy и введите нужную информацию:

  • HAProxy Address. IP-адрес или имя узла HAProxy. ClusterControl должен иметь возможность подключаться по SSH без пароля.
  • Listen Port. Порт, который будет прослушивать экземпляр HAProxy. Этот порт будет использоваться для подключения к серверам MySQL с балансировкой нагрузки.
  • Policy. Алгоритм балансировки нагрузки. Поддерживаемые значения:
    • lessconn — соединение устанавливается с сервером с наименьшим числом соединений;
    • roundrobin — каждый сервер используется по очереди, в соответствии со своим весом;
    • source — IP-адрес клиента хэшируется и делится на общий вес, поэтому он всегда будет попадать на один и тот же сервер, пока ни один сервер не выйдет из строя или отключится.
  • Install from Package Manager. Для Redhat используется диспетчер пакетов YUM. Для Debian используется команда APT.
  • Build from Source. Будет использоваться последний доступный пакет исходных кодов:
    • ClusterControl скомпилирует последний доступный исходный пакет, загруженный с http://www.haproxy.org/#down.
    • Эта опция требуется только в том случае, когда необходимо использовать последнюю версию HAProxy, или если возникли проблемы с менеджером пакетов дистрибутива ОС. В репозиториях пакетов некоторых старых версий ОС нет HAProxy .
  • Overwrite Existing /usr/local/sbin/mysqlchk on targets. Если сценарий mysqlchk уже существует, ClusterControl перепишет его. Если сценарий настроен под конкретные потребности, требуется снять этот флажок.
  • Show Advanced Settings. Дополнительные настройки:
    • Stats Socket. Расположение файла сокета UNIX для запроса статистики. По умолчанию используется /var/run/haproxy.socket, изменять его не рекомендуется.
    • Admin Port. Порт для доступа к странице статистики HAProxy. По умолчанию 9600.
    • Admin User. Пользователь с правами администратора для доступа к странице статистики.
    • Admin Password. Пароль для пользователя-администратора.
    • Backend Name. Имя обработчика для бэкенда. Без пробелов.
    • Timeout Server. Максимальное время бездействия на стороне сервера заданное в секундах.
    • Timeout Client. Максимальное время бездействия на стороне клиента заданное в секундах.
    • Max Connections Frontend. Максимальное количество одновременных подключений к HAProxy.
    • Max Connection Backend per instance. Ограничение числа подключений, которые могут быть сделаны от HAProxy к каждому серверу MySQL. Соединения, полученные после достижения этого значения, HAProxy поставит в очередь. Рекомендуется установить значение меньше, чем max_connectionsдля MySQL, чтобы не допустить переполнения сообщениями.
    • Xinetd allow connections from. Сеть, которой разрешено подключаться к скрипту проверки доступности, выполняемому в рамках xinetd на сервере MySQL.
  • Server Instances. Список серверов MySQL в кластере.
  • Include. Включить сервер в балансировку нагрузки.
  • Role. Выберите, является ли узел активным (Active) или резервным (Backup). В режиме резервного копирования сервер будет использоваться для балансировки нагрузки, только когда все остальные активные серверы недоступны.

Когда поля в диалоговом окне заполнены, нажмите «Install HAProxy», чтобы запустить задание развертывания:

В процессе работы задания ClusterControl выполняет следующие задачи:

  • устанавливает вспомогательные пакеты,
  • настраивает балансировщик,
  • настраивает скрипт mysqlchk (из шаблона) на каждом узле Galera,
  • устанавливает и настраивает xinetd в /etc/xinetd.d/mysqlchk,
  • регистрирует узел HAProxy в ClusterControl.

Отследить прогресс развертывания можно в ClusterControl > Logs > Jobs, как показано в примере ниже:

По умолчанию для обслуживания входящих соединений HAProxy будет слушать порт 3307, распределяя запросы между серверами MySQL, входящими в кластер.

Поскольку при балансировке соединения к серверам MySQL будут открываться не с серверов приложений, а с сервера HAProxy, необходимо добавить права для тех же пользователей, которые используются приложениями, но для IP-адресов, используемых серверами HAProxy:

mysql> GRANT ALL PRIVILEGES ON mydb.* TO 'appuser'@'ha.pr.ox.yip' IDENTIFIED BY 'password';

ClusterControl автоматически перезапускает процесс HAProxy в случае сбоя.

Резервирование HAProxy с помощью Keepalived

Поскольку подключение всех приложений к кластеру обслуживается через HAProxy, этот узел становится единой точкой отказа, чтобы этого избежать можно настроить два идентичных экземпляра HAProxy (один активный и один резервный) и использовать Keepalived для реализации VRRP между ними. VRRP предоставляет активному серверу HAProxy виртуальный IP-адрес и в случае сбоя передает его резервному серверу.

При добавлении Keepalived в схему инфраструктура будет выглядеть примерно так:

В этом примере в качестве балансировщика нагрузки перед кластером базы данных используются два узла с переключением IP-адресов. Виртуальный IP-адрес (VIP) будет передаваться между HAProxy №1 (Master) и HAProxy №2 (Backup). Когда HAProxy №1 выходит из строя, VIP передается HAProxy №2, а как только HAProxy №1 снова запускается, VIP возвращается к HAProxy №1, так как он имеет более высокий приоритет. Процесс восстановления после сбоев происходит автоматически и контролируется посредством Keepalived.

Для установки Keepalived необходимо как минимум два экземпляра HAProxy. Нажмите «Install HAProxy», чтобы установить еще один экземпляр HAProxy, а затем перейдите в ClusterControl > Manage > Load Balancer > Install Keepalived, чтобы установить или добавить существующий экземпляр Keepalived, как показано на следующем снимке экрана:

Убедитесь в том, что сетевая среда поддерживает VRRP (протокол IP 112) для проверки доступности соединения между двумя узлами. Также, если установлен Keepalived версии 1.2.8 и новее, можно разрешить Keepalived работать в среде без многоадресной рассылки, настроив одноадресную рассылку. ClusterControl будет использовать данный режим по умолчанию.

Более подробно о том, как ClusterControl настраивает Keepalived, что ожидать при аварийном переключении и восстановлении после отказа, читайте в статье.

Статистика HAProxy

Помимо развертывания и управления, ClusterControl также дает возможность просматривать статистику HAProxy из пользовательского интерфейса в разделе ClusterControl > Nodes > choose the HAProxy node, как на снимке ниже:

Можно включить/отключить сервер от балансировки нагрузки, отметив/сняв галочку с кнопки-флажка в столбце «Включено». Это очень полезно, когда нужно, чтобы приложение преднамеренно пропустило подключение к серверу, например, для проведения технического обслуживания или тестирования и проверки новых параметров конфигурации или оптимизированных запросов.

Также можно получить доступ к оригинальной странице статистики HAProxy, подключившись к порту 9600 на узле HAProxy:

Как видно из легенды таблицы, зеленые строки указывают на то, какие серверы доступны, а красные — какие недоступны. Когда сервер становится доступным, справа появляется столбец регулирования (Thrtle), в котором отражается прогресс запуска (slowstart 60s). Этот сервер будет постепенно получать соединения, его вес будет динамически регулироваться в течение 60 секунд, пока не достигнет ожидаемого значения (weight 100):

Устранение неполадок и обходные пути

В этом разделе приведены рекомендации для решения некоторых распространенных проблем, возникающих при настройке MySQL с HAProxy, Keepalived и ClusterControl.

Взаимные блокировки MySQL в Galera (Deadlocks)

Кластер Galera имеет известные ограничения, одним из которых является то, что он использует оптимистическую блокировку всего кластера. Это может вызвать откат некоторых транзакций. С увеличением числа доступных для записи узлов Master частота отката транзакций может увеличиться, особенно если в одном и том же наборе данных есть конфликт записи. Конечно, можно повторить транзакцию, и, возможно, она будет выполнена при повторных попытках, но это увеличит задержку транзакции. Однако некоторые архитектурные решения, применяемые в приложениях, подвержены возникновению ситуации взаимной блокировки (deadlock).

Решение состоит в том, чтобы создать еще один обработчик, включающий единственный узел, предназначенный для обработки проблемных операций, и сообщить приложению, чтобы он отправлял такие запросы ему.

В следующем примере показаны фрагменты обработчиков HAProxy, предназначенных для выполнения операций чтения/записи в равнодоступном кластере на порту 3307 и операций чтения/записи с выделенным сервером на порту 3308:

listen  haproxy_192.168.55.110_3307_multi
        bind *:3307
        mode tcp
        timeout client  10800s
        timeout server  10800s
        balance leastconn
        option httpchk
        option allbackups
        default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
        server galera1 192.168.55.111:3306 check
        server galera2 192.168.55.112:3306 check
        server galera3 192.168.55.113:3306 check
 
listen  haproxy_192.168.55.110_3308_single
        bind *:3308
        mode tcp
        timeout client  10800s
        timeout server  10800s
        balance leastconn
        option httpchk
        option allbackups
        default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
        server galera1 192.168.55.111:3306 check
        server galera2 192.168.55.112:3306 check backup
        server galera3 192.168.55.113:3306 check backup

Подробнее об этом читайте в статье.

Сервер MySQL не доступен

Обычно это происходит, когда HAProxy закрыл соединение по тайм-ауту, или соединение закрыто на стороне сервера. Иногда можно увидеть данное состояние, когда сервер перегружен и соединение столкнулось с одним из следующих тайм-аутов (следующие значения используются по умолчанию для переменных MySQL в ClusterControl):

  • connect_timeout — 10 с;
  • deadlock_timeout_long — 50000000 с;
  • deadlock_timeout_short — 10000 с;
  • delayed_insert_timeout — 300 с;
  • innodb_lock_wait_timeout — 50 с;
  • interactive_timeout — 28800 с;
  • lock_wait_timeout — 31536000 с;
  • net_read_timeout — 30 с;
  • net_write_timeout — 60 с;
  • slave_net_timeout — 3600 с;
  • thread_pool_idle_timeout — 60 с;
  • wait_timeout — 28800 с.

Мы рекомендуем настроить значения net_read_timeout и net_write_timeout с тем же значением, что и для timeout client и timeout server в файле конфигурации HAProxy.

Оборудование разной производительности

Если у вас используется оборудование разной производительности, определение веса для каждого сервера позволит сбалансировать нагрузку на сервер. Все серверы получат нагрузку, пропорциональную их весу относительно суммы всех весов, поэтому чем больше вес, тем выше нагрузка. Рекомендуется начинать со значений, которые могут как увеличиваться, так и уменьшаться, например, от 10 до 100, чтобы оставалась возможность для последующих корректировок.

Производительность репликации Galera определяется самым медленным узлом в кластере. Допустим, в кластере с тремя узлами производительность третьего узла составляет половину производительности двух других узлов. Рекомендуется уменьшить вес этого сервера наполовину, чтобы он получал достаточное количество соединений и не тянул вниз других участников из-за работы в полную силу:

...
default-server port 9200 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100
server galera1 192.168.55.111:3306 check
server galera2 192.168.55.112:3306 check
server galera3 192.168.55.113:3306 check weight 50

Стоит отметить, что для кластеров Galera рекомендуется использовать серверы одной производительности. Решение с регулированием веса поможет только в том случае, если доля запросов чтения данных существенно превышает долю запросов записи данных.