Компания
87,64
рейтинг
22 октября 2013 в 12:02

Разработка → HAPRoxy для Percona или Galera на CentOS. Его настройка и мониторинг в Zabbix tutorial



Очень короткая статья, про то как можно использовать HAProxy в качестве балансировщика для multi-master серверов MySQL, таких как Percona или Galera.



Хочу отметить, что эта инструкция родилась в процессе внедрения Zabbix в стенах компании Acronis.
В процессе экспертизы и проведенных мною исследований, она доказала свое право на жизнь и благополучно служит нам верой и правдой день ото дня.


Для тех кто не знаком с HAProxy, цитата о предназначении продукта:
При увеличении нагрузки или посещаемости проекта, рано или поздно вертикальное маштабирование (увеличение ресурсов сервера, таких как память, скорость диска и т.д) упирается в некий предел и не дает ощутимого прироста. В таком случае в ход идет горизонтальное масштабирование — добавление новых серверов c перераспределением нагрузки между ними.
Кроме увеличения мощности, горизонтальное масштабирование добавляет надежности системе — при выходе из строя одного из серверов, нагрузка будет сбалансирована между работающими и приложение будет жить.


От слов к делу, установка и настройка очень просты:




В предыдущем материале я подробно описал какие предварительные операции я проделывал над чистой CentOS 6.4, мои рекомендации актуальный и тут, все пакеты будут указаны с учетом рекомендаций в предыдущем материале:

Репозитории подключены, система в актуальном состоянии, переходим к установке HAProxy:

# Ставим haproxy
yum install haproxy mariadb-client php-mysql php-cli -y


# Пишем конфиги
mv /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg.old

[root@rs-haproxy ~]# nano /etc/haproxy/haproxy.cfg
global
daemon
maxconn 4096

# Если хочется увидеть отладочную информацию, то этот пункт стоит закоментировать
quiet

# А этот напротив, раскоментировать
# debug

user haproxy
group haproxy

# Мы будем использовать этот сокет для мониторинга в zabbix
stats socket /var/run/haproxy

pidfile /var/run/haproxy.pid

defaults
mode http
option tcplog
log global
option dontlognull retries 3 option redispatch
maxconn 2000
contimeout 5000
clitimeout 50000
srvtimeout 50000
option tcplog

# Укажите действующий адрес на сервера и порт, на котором будет слушать наш haproxy
listen MySQL адрес-на-котором слушаем-:3306

mode tcp

# roundrobin — последовательно пишет во все сервера, это хорошо в режиме чтения но может вызвать проблемы если таким образом записывать в базу
# balance roundrobin

# leastconn этот режим отлично подходит при использовании haproxy в качестве failover прокси, используется последний работающий сервер и только он
balance leastconn

# httpchk заставляет haproxy проверять сервер на его готовность перед отправкая каждого из запросов
option httpchk

# Ниже список серверов, их порт и порт на который будет происходит подключение для проверки жизнеспособности
server адрес адрес:3306 check port 50005 inter 12000 rise 3 fall 3
server адрес адрес:3306 check port 50005 inter 12000 rise 3 fall 3

# Сервера с флагом backup используются только если остальные сервера не доступны
server адрес адрес:3306 check port 50005 inter 12000 rise 3 fall 3 backup


Теперь перейдем к серверам нашей percona или galera

# Настраиваем механизм проверки наших баз данных, для этого понадобиться xinetd
yum install -y xinetd


[root@xtrabackup-node-01 ~]# nano /etc/xinetd.d/mysqlchk
# default: on
# description: mysqlchk
service mysqlchk
{
disable = no
flags = REUSE
socket_type = stream

# порт проверки который мы указали выше
port = 50005

wait = no
user = nobody
server = /usr/bin/clustercheck
log_on_failure += USERID

# Адреса с которых разрешена проверка состояния службы MySQL
only_from = 10.100.100.0/24

per_source = UNLIMITED
}


# Очень важно добавить эту запись, иначе ничего не получиться
root@xtrabackup-node-01 ~]# nano /etc/services
mysqlchk 50005/tcp # mysqlchk


# Добавляем службу в автозагрузку и запускаем ее
chkconfig xinetd on
/etc/init.d/xinetd start


# Разрешаем доступ к порту проверки
iptables -A INPUT -p tcp -m state --state NEW -m tcp --dport 50005 -j ACCEPT
service iptables save


# Добавляем права для доступа clustercheck
GRANT PROCESS ON *.* TO 'clustercheckuser'@'localhost' IDENTIFIED BY 'clustercheckpassword!';
flush privileges;


# Проверяем все ли у нас получилось, должно получится что то вроде
[root@xtrabackup-node-01 ~]# /usr/bin/clustercheck
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: close
Content-Length: 40

Percona XtraDB Cluster Node is synced.


# Теперь проверим работу с нашего haproxy хоста
[root@rs-haproxy ~]# telnet адрес 50005
Trying адрес…
Connected to адрес.
Escape character is '^]'.
HTTP/1.1 200 OK
Content-Type: text/plain
Connection: close
Content-Length: 40

Percona XtraDB Cluster Node is synced.
Connection closed by foreign host.


Готово! нужно проделать эту операцию на всех нодах percona/galera

Мониторинг HAProxy для MYSQL в Zabbix



# Это основной инструмент для нашего скрипта, установим его
yum install -y socat


# Настроим sudo для zabbix, если это не было сделано раньше
usermod -s /bin/bash zabbix
echo 'zabbix ALL=(ALL) NOPASSWD: ALL' >> /etc/sudoers
sed -i 's/Defaults\ requiretty/#Defaults\ requiretty/g' /etc/sudoers


# Создаем папку для наших скриптов
mkdir -p /etc/zabbix/scripts/
chmod 750 /etc/zabbix/scripts/


# Собственно сам скрипт
rm -f /etc/zabbix/scripts/haproxy.mysql
nano /etc/zabbix/scripts/haproxy.mysql


if [[ -z $1 || -z $2 ]]; then
 servers=`echo "show stat" | sudo socat /var/run/haproxy stdio | sed 's/,/\ /g' | awk '{print $2}' | grep -v -e "pxname" -e '^$'`
  if [[ -n ${servers} ]]; then
    JSON="{ \"data\":["
    for DEV in ${servers}; do
      JSON=${JSON}"{ \"{#SRV}\":\"${DEV}\"},"
    done
    JSON=${JSON}"]}"
   echo ${JSON}
  fi
  exit 0
else

server="$2"
# echo $server
if [ ${1} = "qcur" ]; then
# echo $1
echo "show stat" | sudo socat /var/run/haproxy stdio | grep "MySQL,${server}"| sed 's/,/\ /g' | awk '{print $3}'
  exit 0
  fi
 if [ ${1} = "qmax" ]; then
echo "show stat" | sudo socat /var/run/haproxy stdio | grep "MySQL,${server}" | sed 's/,/\ /g' | awk '{print $4}'
  exit 0
  fi
if [ ${1} = "scur" ]; then
echo "show stat" | sudo socat /var/run/haproxy stdio | grep "MySQL,${server}" | sed 's/,/\ /g' | awk '{print $5}'
  exit 0
  fi
  if [ ${1} = "smax" ]; then
echo "show stat" | sudo socat /var/run/haproxy stdio | grep "MySQL,${server}" | sed 's/,/\ /g' | awk '{print $6}'
  exit 0
  fi
    if [ ${1} = "econ" ]; then
echo "show stat" | sudo socat /var/run/haproxy stdio | grep "MySQL,${server}" | sed 's/,/\ /g' | awk '{print $14}'
  exit 0
  fi
if [ ${1} = "qlimit" ]; then
echo "show stat" | sudo socat /var/run/haproxy stdio | grep "MySQL,${server}" | sed 's/,/\ /g' | awk '{print $26}'
  exit 0
  fi
  fi


Скрипт сам обнаруживает доступные сервера и передает их zabbix
Проверим это:


[root@rs-haproxy ~]# echo «show stat» | sudo socat /var/run/haproxy stdio | sed 's/,/\ /g' | awk '{print $2}' | grep -v -e «pxname» -e '^$'
FRONTEND
10.100.100.246
BACKEND


# Минимальные настроки для нашего zabbix-agent
echo Timeout=30 >> /etc/zabbix/zabbix_agentd.conf
echo Include=/etc/zabbix/zabbix_agentd.d/ >> /etc/zabbix/zabbix_agentd.conf


# Применяем права на исполнение новому скрипту
chown zabbix:zabbix -R /etc/zabbix/scripts/
chmod +x /etc/zabbix/scripts/haproxy.mysql


# Передаем zabbix наши UserParameter
mkdir -p /etc/zabbix/zabbix_agentd.d/
rm -f /etc/zabbix/zabbix_agentd.d/haproxy.mysql.conf
touch /etc/zabbix/zabbix_agentd.d/haproxy.mysql.conf

echo 'UserParameter=haproxy.mysql[*],/etc/zabbix/scripts/haproxy.mysql "$1" "$2"' >> /etc/zabbix/zabbix_agentd.d/haproxy.mysql.conf


Теперь проверим правильно ли работает наш скрипт:
su zabbix

# Вот так работает наше автоматическое обнаружение серверов
bash-4.1$ /etc/zabbix/scripts/haproxy.mysql

{ «data»:[{ "{#SRV}":«FRONTEND»},{ "{#SRV}":«10.100.100.246»},{ "{#SRV}":«BACKEND»},]}


# Спросим любые данные
bash-4.1$ /etc/zabbix/scripts/haproxy.mysql qcur FRONTEND
115


Похоже что все в порядке! Перезагружаем службу и любуемся логами
/etc/init.d/zabbix-agent restart && tail -f -n 100 /var/log/zabbix/zabbix_agentd.log


Вот так выглядит наш шаблон под haproxy


Тут можно скачать шаблон для импорта в zabbix

Спасибо за внимание!

Автор: @SyCraft
Acronis
рейтинг 87,64

Комментарии (14)

  • 0
    может, конечно, придираюсь, но разрисовали бы что-ли архетектуру кластера, логику работы.
    • 0
      Обновил статью, добавил достаточно наглядное изображение
      • 0
        красота!
        • 0
          То что нужно?
          • 0
            на мой субъективный взгляд — да. просто помню когда только начинал разбираться с темой, не всегда легко было представить по конфигам систему и движение трафика, особенно в случае отказа нодов или когда ноды начинают «дёргаться». всега пригодится иметь схему перед глазами.
            • 0
              Обращайтесь если будет дополнительные вопросы
  • 0
    Так у вас что же, репликация master-master на mysql нодах?

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

    С-нно по этой схеме плюс один сервер = дополнительный прогон данных по сети.
    Т.о. у вас получилась то же вертикальное расширение, но в другом масштабе.
    • 0
      Это multi-master
      Сеть не является узким местом в таких системах, зато чтение происходит с разных нод перконы и чем их больше тем быстрее чтение, запись медленнее чем в одиночном варианте mysql но есть failover
      по сути, это raid1 мира баз данных
  • 0
    >> zabbix ALL=(ALL) NOPASSWD: ALL
    это еще что за жесть?
    • 0
      Поверьте, это так надо))
    • 0
      Не самое безопасное решение, но работает
      • 0
        поторопился с первым каментом, напишу более развернуто. я протестую против ALL в конце,
        я бы сделал так «zabbix ALL=(root) NOPASSWD: /usr/bin/socat»
        а то ваш вариант приравнивает аккаунт zabbix'а почти к руту.

        вот тоже неплохой пример если уже есть определенная политика в отношении sudo для других пользователей

        Cmnd_Alias ZABBIX = /bin/cmd1, /sbin/cmd2, /usr/sbin/cmd3
        zabbix ALL=(root) NOPASSWD: ZABBIX
        • 0
          в принципе можно просто chmod-ом настроить права для необходимого софта (в данном случае socat)
        • 0
          Все так, но у нас забиск использует не только этот скрипт и много специфичного софта в системе, можно конечно перечислить в sudoer все, но в данном контексте это не нужно

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.

Самое читаемое Разработка