웹사이트 검색

HAProxy를 사용하여 MySQL 부하 분산을 설정하는 방법


전주곡

HAProxy는 HTTP 및 TCP 서버의 부하를 분산할 수 있는 오픈 소스 소프트웨어입니다. 마스터-마스터 복제에서 로드 밸런싱은 모든 백엔드에 대한 읽기 및 쓰기를 모두 포함합니다.

이 문서에서는 다음 세 개의 물방울이 사용됩니다.

드롭릿 1 - 로드 밸런서

물방울 2 - 노드 1

물방울 2 - 노드 2

계속하기 전에 모든 MySQL 서버가 실행 중이고 데이터베이스 쓰기를 올바르게 복제하고 있는지 확인하십시오.

MySQL 서버 준비

HAProxy에 대한 두 명의 추가 사용자를 생성하여 MySQL 서버를 준비해야 합니다. 첫 번째 사용자는 HAProxy에서 서버의 상태를 확인하는 데 사용됩니다.

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

HAProxy에서 MySQL 클러스터에 액세스하려면 루트 권한이 있는 MySQL 사용자가 필요합니다. 모든 서버의 기본 루트 사용자는 로컬로만 로그인할 수 있습니다. 루트 사용자에게 추가 권한을 부여하여 이 문제를 해결할 수 있지만 루트 권한을 가진 별도의 사용자를 두는 것이 좋습니다.

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_rootpassword를 자신의 보안 값으로 바꾸십시오. 변경 사항이 다른 마스터에 복제되므로 하나의 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

init 스크립트에 의해 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를 사용합니다. 루프백 주소에서만 수신 대기하도록 HAProxy를 설정했습니다(응용 프로그램이 동일한 서버에 있다고 가정). 다른 물방울은 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의 가중치를 변경하고 결과를 확인하겠습니다.

nano /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/3이 mysql-1로 가고 2/3가 mysql-2로 가는 1: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는 이 오류를 감지하고 클러스터에서 제거하는 데 시간이 걸립니다. 이 섹션에서는 이 시간을 제어하는 방법을 살펴보겠습니다. 먼저 이 값을 측정하는 방법을 살펴보겠습니다. 한 가지 방법은 일정 시간 동안 iptables를 사용하여 MySQL 포트를 차단한 다음 규칙을 제거하고 로그를 확인하는 것입니다.

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의 차이)가 걸렸습니다. 이는 서버 매개변수 rise, fall 및 inter에 의해 결정됩니다.

rise 매개 변수는 서버가 작동 선언되기 위해 통과해야 하는 검사 수를 설정합니다. 기본값은 2입니다.

fall 매개변수는 서버가 dead로 선언되기 위해 통과해야 하는 검사 수를 설정합니다. 기본값은 3입니다.

inter 매개변수는 이러한 검사 사이의 간격을 설정합니다. 기본값은 2000밀리초입니다.

이 정보를 종합하면 서버는 2초 간격으로 수행되는 3개의 연속 검사에 실패해야 죽은 것으로 간주됩니다. 따라서 위의 예에서 다음과 같은 일이 발생했을 것입니다.

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초로 줄이고 낙하 테스트 횟수도 줄입니다.

nano /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일 때 테스트 간격을 설정합니다.

그 설명은 혼란스러울 수 있으므로 예를 들어 보겠습니다.

nano /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\ 매개변수를 지정하지 않았으므로 기본값은 2000ms입니다. 이 구성으로 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초("inter\ 간격)입니다. 그런 다음 테스트 1 <- 사이의 간격을 확인하십시오. > 테스트 2 및 테스트 2 <-> 테스트 3, 단 1초입니다(\fastinter 간격). 서버가 DOWN에서 UP으로 이동할 때도 같은 간격을 볼 수 있습니다. 따라서 "fastinter\는 이러한 검사 사이의 간격을 제어합니다.

그렇다면 다운인터란 무엇일까요? 서버가 DOWN 선언되면 HAProxy는 2초마다(또는 inter에 언급된 간격) 서버를 계속 확인합니다. 불필요한 네트워크 리소스를 사용하고 있다고 생각되면 다운 인터를 5000으로 설정하면 HAProxy가 5초에 한 번만 다운 서버를 확인하게 됩니다.

중요한

우리가 이전에 수행한 테스트는 HAProxy가 mysql-1에 SYN 패킷을 전송하여 연결을 시작했을 때 RST 패킷(SYN + ACK 대신)을 수신했음을 의미하는 패킷을 거부했습니다. 이것이 로그 항목에 \연결 거부\가 언급된 이유입니다. 이 경우에는 fall, inter 및 fastinter 값만 장면에 나타납니다.

대신 HAProxy가 SYN을 보낸 후 아무 것도 수신하지 않으면 연결 시간이 초과됩니다. 이 경우 위에서 언급한 매개변수 외에도 "timeout\ 지속 시간이 장면에 나타납니다. 이 상황은 다음과 같은 경우에 발생할 수 있습니다.

  • iptables는 DROP으로 설정됩니다
  • 개인 인터페이스가 다운됨
  • 사설 네트워킹 인프라에 문제가 있습니다.

추가 자료

공식 문서 http://cbonte.github.io/haproxy-dconv/configuration-1.4.html

제출자: 제신A