Поиск по сайту:

Как использовать HAProxy для настройки балансировки нагрузки MySQL


Прелюдия

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

В этой статье будут использоваться следующие три капли:

Капля 1 — балансировщик нагрузки

Капля 2 — узел 1

Капля 2 — узел 2

Прежде чем продолжить, убедитесь, что все серверы MySQL запущены, работают и правильно реплицируют записи в базу данных.

Подготовьте серверы MySQL

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

root@mysql-1# mysql -u root -p -e "INSERT INTO mysql.user (Host,User) values ('10.0.0.100','haproxy_check'); FLUSH PRIVILEGES;"

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

root@mysql-1# mysql -u root -p -e "GRANT ALL PRIVILEGES ON *.* TO 'haproxy_root'@'10.0.0.100' IDENTIFIED BY 'password' WITH GRANT OPTION; FLUSH PRIVILEGES"

Замените haproxy_root и пароль собственными безопасными значениями. Достаточно выполнить эти запросы на одном мастере MySQL, так как изменения будут реплицироваться на другие.

Установить MySQL-клиент

Клиент MySQL должен быть установлен в дроплете HAProxy для проверки подключения.

root@haproxy# apt-get install mysql-client

Теперь попробуйте выполнить запрос на одном из мастеров от имени пользователя haproxy_root.

root@haproxy# mysql -h 10.0.0.1 -u haproxy_root -p -e "SHOW DATABASES"

Это должно отобразить список баз данных MySQL.

Установка HAProxy

На сервере HAProxy установите пакет.

root@haproxy# apt-get install haproxy

Включите запуск HAProxy сценарием инициализации.

root@haproxy# sed -i "s/ENABLED=0/ENABLED=1/" /etc/default/haproxy

Чтобы проверить, правильно ли сделано это изменение, запустите скрипт инициализации HAProxy без каких-либо параметров.

root@haproxy:~# service haproxy
Usage: /etc/init.d/haproxy {start|stop|reload|restart|status}

Настройка HAProxy

Переименуйте исходный файл конфигурации

mv /etc/haproxy/haproxy.cfg{,.original}

Создайте и отредактируйте новый

nano /etc/haproxy/haproxy.cfg

Первый блок является глобальным и блоком конфигурации по умолчанию.

global
    log 127.0.0.1 local0 notice
    user haproxy
    group haproxy

defaults
    log global
    retries 2
    timeout connect 3000
    timeout server 5000
    timeout client 5000

Дополнительные сведения о каждом из этих параметров описаны в той же статье в разделе «Настройка ведения журнала для HAProxy».

Переходим к основной части конфигурации.

listen mysql-cluster
    bind 127.0.0.1:3306
    mode tcp
    option mysql-check user haproxy_check
    balance roundrobin
    server mysql-1 10.0.0.1:3306 check
    server mysql-2 10.0.0.2:3306 check

В отличие от балансировки нагрузки HTTP, HAProxy не имеет определенного «режима» для MySQL, поэтому мы используем tcp. другой дроплет заставляет его прослушивать 0.0.0.0 или частный IP-адрес.

Нам нужен еще один блок конфигурации, чтобы увидеть статистику балансировки нагрузки. Это совершенно необязательно и может быть опущено, если вам не нужна статистика.

listen 0.0.0.0:8080
    mode http
    stats enable
    stats uri /
    stats realm Strictly\ Private
    stats auth A_Username:YourPassword
    stats auth Another_User:passwd

Замените имена пользователей и пароли в \stats auth. Это заставит HAProxy прослушивать порт 8080 для HTTP-запросов, а статистика будет защищена базовой HTTP-аутентификацией. Таким образом, вы можете получить доступ к статистике по адресу

http://<Public IP of Load Balancer>:8080/

Когда вы закончите настройку, запустите службу HAProxy.

service haproxy start

Используйте клиент mysql для запроса HAProxy.

root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "SHOW DATABASES"

Параметр \-h должен присутствовать с петлевым IP-адресом. Если его не указать или использовать localhost, клиент MySQL подключится к файлу mysql.sock, что не удастся.

Тестирование балансировки нагрузки и аварийного переключения

Чтобы проверить, работает ли балансировка нагрузки, запросите переменную server_id дважды или более.

root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "show variables like 'server_id'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "show variables like 'server_id'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+

Это демонстрирует циклическую балансировку нагрузки с равными весами, теперь мы изменим вес для mysql-2 и посмотрим на результаты.

нано /etc/haproxy/haproxy.cfg

server mysql-2 10.0.0.2:3306 check weight 2

Перезагрузите, чтобы применить это изменение.

service haproxy reload

Запросить server_id несколько раз.

root@haproxy:~# for i in `seq 1 6`
do
mysql -h 127.0.0.1 -u haproxy_root -ppassword -e "show variables like 'server_id'"
done

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+

Теперь балансировка нагрузки работает в соотношении 1:2, при этом одна треть запросов направляется на mysql-1, а две трети — на mysql-2.

Сбой сервера MySQL либо путем остановки службы

root@mysql-1# service mysql stop

или выключение интерфейса.

root@mysql-1# ifconfig eth1 down

Попробуйте запрос «показать переменные» сейчас, чтобы увидеть результат. Следующие записи журнала укажут, когда и как HAProxy обнаружил сбой.

хвост /var/log/haproxy/haproxy.log

Nov 15 00:08:51 localhost haproxy[1671]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 timeout, check duration: 2002ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.

Сокращение интервала аварийного переключения

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

root@mysql-1:~# ifconfig eth1 down &&
date &&
sleep 20 &&
ifconfig eth1 up &&
date

Fri Nov 15 00:37:09 IST 2013
Fri Nov 15 00:37:29 IST 2013

Порт 3306 был заблокирован на 20 секунд, сейчас посмотрим лог-файл.

root@haproxy:~# tail /var/log/haproxy.log
Nov 15 16:49:38 localhost haproxy[1275]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Nov 15 16:49:56 localhost haproxy[1275]: Server mysql-cluster/mysql-1 is UP, reason: Layer7 check passed, code: 0, info: "5.5.31-0+wheezy1-log", check duration: 1ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.

Потребовалось 6 секунд, чтобы обнаружить сбой (разница между 16:49:38 и 16:49:32) и 4 секунды, чтобы определить, что сервер доступен (разница между 16:49:56 и 16:49:52). Это определяется параметрами подъема, падения и интер.

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

Параметр падения устанавливает количество проверок, которые сервер должен пройти, чтобы быть объявленным мертвым. По умолчанию 3.

Параметр inter задает интервал между этими проверками. По умолчанию 2000 миллисекунд.

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

16:49:32 - Port 3306 on mysql-1 was blocked
16:49:34 - Check - Failed - Failure No. 1
16:49:36 - Check - Failed - Failure No. 2
16:49:38 - Check - Failed - Failure No. 3 (server removed and event logged)

И когда правило брандмауэра было удалено.

16:49:52 - Firewall rule removed port 3306 accessible
16:49:54 - Check - Passed - Success No. 1
16:49:56 - Check - Passed - Success No. 2 (server added to cluster and event logged)

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

нано /etc/haproxy/haproxy.cfg

server mysql-1 10.0.0.1:3306 check fall 2 inter 1000
server mysql-2 10.0.0.2:3306 check fall 2 inter 1000

Иногда вы можете не захотеть перегружать частную сеть слишком большим количеством «тестовых» пакетов, особенно если у вас большое количество серверов MySQL. В таких случаях вам пригодятся параметры fastinter и downinter.

Параметр fastinter устанавливает интервал между проверками, когда сервер переходит в состояние UP или DOWN.

Параметр downinter устанавливает интервал тестирования, когда сервер находится в состоянии DOWN.

Это объяснение может сбивать с толку, поэтому мы рассмотрим его на примере.

нано /etc/haproxy/haproxy.cfg

server mysql-1 10.0.0.1:3306 check fastinter 1000
server mysql-2 10.0.0.2:3306 check fastinter 1000

Поскольку мы не указали параметр «inter», по умолчанию он равен 2000 мс. С этой конфигурацией мы перезапустим HAProxy и повторим тест.

root@mysql-1:~# iptables -A INPUT -p tcp --dport 3306 -j REJECT &&
date &&
sleep 20 &&
iptables -D INPUT -p tcp --dport 3306 -j REJECT &&
date
Fri Nov 15 17:18:48 IST 2013
Fri Nov 15 17:19:08 IST 2013

Проверьте файл журнала HAProxy.

root@haproxy:~# tail /var/log/haproxy.log
Nov 15 17:18:52 localhost haproxy[1353]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Nov 15 17:19:11 localhost haproxy[1353]: Server mysql-cluster/mysql-1 is UP, reason: Layer7 check passed, code: 0, info: "5.5.31-0+wheezy1-log", check duration: 1ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.

Теперь требовалось всего 4 секунды (по сравнению с 6 ранее), чтобы обнаружить сбой, и 3 секунды (по сравнению с 4), чтобы определить, что сервер работает. За кадром произошло вот что.

17:18:48 - Port 3306 blocked
17:18:50 - Check - Failed - Failure No. 1
17:18:51 - Check - Failed - Failure No. 2
17:18:52 - Check - Failed - Failure No. 3 (server removed and event logged)

И когда порт был разблокирован.

17:19:08 - Firewall rule removed
17:19:10 - Check - Passed - Success No. 1
17:19:11 - Check - Passed - Success No. 2 (server added to cluster and event logged)

Сначала обратите внимание на интервал между событием блокировки порта (17:18:48) и первой проверкой (17:18:50), он составляет 2 секунды («интервал между»). Затем обратите внимание на интервал между тестом 1 <- > Тест 2 и Тест 2 <-> Тест 3, это всего 1 секунда (интервал fastinter). Такие же интервалы можно заметить при переходе сервера из DOWN в UP. Так \fastinter контролирует интервал между этими проверками.

Так что же такое даунтер? Когда сервер объявлен DOWN, HAProxy продолжает проверять его каждые 2 секунды (или интервал, указанный в параметре inter). Если вы чувствуете, что используете ненужные сетевые ресурсы, установив для downinter значение 5000, HAProxy заставит HAProxy проверять DOWN-сервер только один раз в 5 секунд.

Важный

Тесты, которые мы проводили ранее, отклоняли пакеты, что означает, что когда HAProxy инициировал соединение, отправив пакет SYN в mysql-1, он получил пакет RST (вместо SYN + ACK). Вот почему в записи журнала упоминается «Отказ в соединении». В этом случае на сцену выходят только значения fall, inter и fastinter.

Вместо этого, если HAProxy ничего не получил после отправки SYN, время ожидания соединения истекло. В этом случае помимо вышеперечисленных параметров на сцену выходит продолжительность «тайм-аута». Такая ситуация может возникнуть, если

  • iptables настроен на DROP
  • частный интерфейс не работает
  • проблема с частной сетевой инфраструктурой

Дальнейшее чтение

Официальная документация http://cbonte.github.io/haproxy-dconv/configuration-1.4.html

Прислал: Джесин А