이전 포스팅에서 sentinel 을 이용한 auto failover 에 대해서 알아 보았습니다. 그런데 마지막 부분에 문제가 있었지요. client 가 어떻게 새로 변경된 master 를 찾아서 connection 할 것인가? 입니다. 이 문제를 해결하기 위한 방법인 HAProxy 에 대해서 알아보도록 하겠습니다.



HAProxy 를 이용한 switching


HAProxy 는 사실 redis 랑은 무관합니다. 이것은 L4/L7 의 기능을 제공하는 소프트웨어 로드 밸런서입니다. 오픈소스이고 무료이기 때문에 앞선 문제를 해결하기 위해서 사용할 뿐입니다. 자세한 내용은 개인적으로 찾아 보시기 바랍니다. :)


전체 서버의 구성도는 다음과 같습니다.





HAProxy 설치




먼저 http://karmainearth.tistory.com/143 로 들어가서 다운로드를 받습니다.

저는 여기서 최신 stable 버전인 1.5.12 를 받았습니다.



[und3r@sungwook src]$ sudo wget http://www.haproxy.org/download/1.5/src/haproxy-1.5.12.tar.gz

[sudo] password for und3r:

--2015-05-29 15:12:29--  http://www.haproxy.org/download/1.5/src/haproxy-1.5.12.tar.gz

Resolving www.haproxy.org... 195.154.117.161, 2001:7a8:363c:2::2

Connecting to www.haproxy.org|195.154.117.161|:80... connected.

HTTP request sent, awaiting response... 200 OK

Length: 1344813 (1.3M) [application/x-gzip]

Saving to: “haproxy-1.5.12.tar.gz”


62% [=======================================================>                                   ] 837,945  100%[=================================================================>] 1,344,813    192K/s   in 7.9s


2015-05-29 15:12:38 (166 KB/s) - “haproxy-1.5.12.tar.gz” saved [1344813/1344813]



다운로드를 다 받은 뒤에, 압축을 풀고 해당 폴더로 이동합니다. 그리고 make 를 해주어야 하는데 옵션이 있습니다. 해당 폴더에 있는 README 파일을 열어보면 관련 내용이 나옵니다. 한번씩 읽어보시기 바랍니다.


대략 이런 내용들입니다.


저는 kernel 버전이 2.6.32 인 관계로 linux2628 옵션을 주도록 하겠습니다.



[und3r@sungwook haproxy-1.5.12]$ sudo make TARGET=linux2628


이후 make install 을 하면, 어디에 설치되었는지 정보들이 같이 출력됩니다.


[und3r@sungwook haproxy-1.5.12]$ sudo make install

install -d "/usr/local/sbin"

install haproxy "/usr/local/sbin"

install haproxy-systemd-wrapper "/usr/local/sbin"

install -d "/usr/local/share/man"/man1

install -m 644 doc/haproxy.1 "/usr/local/share/man"/man1

install -d "/usr/local/doc/haproxy"

for x in configuration architecture haproxy-en haproxy-fr; do \

                install -m 644 doc/$x.txt "/usr/local/doc/haproxy" ; \

        done




이제 사용성을 위해서 몇 가지를 좀 해 주어야 합니다.


먼저 /etc 에 haproxy 폴더를 만들어 줍니다.

[und3r@sungwook haproxy-1.5.12]$ sudo mkdir /etc/haproxy



그리고 실행 스크립트를 복사하고 실행권한을 줍니다. 샘플 폴더에 있어요.

[und3r@sungwook haproxy-1.5.12]$ sudo cp ./examples/haproxy.init /etc/init.d/haproxy

[und3r@sungwook haproxy-1.5.12]$ sudo chmod 755 /etc/init.d/haproxy



실행파일인 haproxy 도 /usr/sbin 폴더에 복사해 줍니다.

[und3r@sungwook haproxy-1.5.12]$ sudo cp /usr/local/sbin/haproxy /usr/sbin/haproxy





Redis 를 위한 설정과 실행




자 이제 /etc/haproxy/haproxy.cfg 에 파일을 생성합니다. 그리고 다음과 같이 입력합니다. 참고로 이전 포스팅 환경에 맞게 설정한 것이므로, 여러분 환경에 맞게 수정하시면 됩니다.


defaults REDIS
 mode tcp
 timeout connect  4s
 timeout server  15s
 timeout client  15s
# timeout tunnel 365d

frontend ft_redis_master
 bind *:5000 name redis
 default_backend bk_redis_master

backend bk_redis_master
 option tcp-check
 tcp-check send AUTH\ mypassword\r\n
 tcp-check expect string +OK
 tcp-check send PING\r\n
 tcp-check expect string +PONG
 tcp-check send info\ replication\r\n
 tcp-check expect string role:master
 tcp-check send QUIT\r\n
 tcp-check expect string +OK
 server R1 127.0.0.1:7000 check inter 1s
 server R2 127.0.0.1:7001 check inter 1s
 server R3 127.0.0.1:7002 check inter 1s
 server R4 127.0.0.1:7003 check inter 1s



frontend ft_redis_slave
 bind *:5001 name redis
 default_backend bk_redis_slave

backend bk_redis_slave
 option tcp-check
 tcp-check send AUTH\ mypassword\r\n
 tcp-check expect string +OK
 tcp-check send PING\r\n
 tcp-check expect string +PONG
 tcp-check send info\ replication\r\n
 tcp-check expect string role:slave
 tcp-check send QUIT\r\n
 tcp-check expect string +OK
 server R1 127.0.0.1:7000 check inter 1s
 server R2 127.0.0.1:7001 check inter 1s
 server R3 127.0.0.1:7002 check inter 1s
 server R4 127.0.0.1:7003 check inter 1s



listen stats 0.0.0.0:80       #Listen on all IP's on port 9000
    mode http
    balance
    timeout client 5000
    timeout connect 4000
    timeout server 30000

    #This is the virtual URL to access the stats page
    stats uri /haproxy_stats

    #Authentication realm. This can be set to anything. Escape space characters with a backslash.
    stats realm HAProxy\ Statistics

    #The user/pass you want to use. Change this password!
    stats auth und3r:password

    #This allows you to take down and bring up back end servers.
    #This will produce an error on older versions of HAProxy.
    stats admin if TRUE

어려운 내용이 없으므로, 보시면 아실거라고 생각합니다. 마지막 부분의 listen 은 haproxy 의 모니터링을 위한 페이지(웹) 설정입니다. 보시는것처럼 port 는 80 으로 하였습니다. 여러분 환경에 맞게 수정하시면 됩니다.

비밀번호(auth) 설정 부분 놓치지 않도록 주의하세요



이제 haproxy 서버를 실행해 보겠습니다.

[und3r@sungwook haproxy-1.5.12]$ sudo /etc/init.d/haproxy start

Starting haproxy:                                          [  OK  ]


잘 동작 되었네요. :)



모니터링 페이지를 들어가 보도록 합시다. 위에서 80 번 포트로 지정했으므로 해당 포트로 웹브라우저를 통해 접속하면 됩니다.

주소는 stats uri 값에 넣어준 주소입니다. 위 경우 http://myserver/haproxy_stats 가 되겠네요.


아래처럼 master 전용(포트:5000) 과 slave 전용(포트:5001) 이 제대로 동작하고 있는 것을 볼 수 있습니다.





주의할 점



혹시 blpop 과 같은 blocking command 를 사용하려면, 주의할 점이 있습니다. 바로 위 haproxy 의 설정파일에 주석처리된 'timeout tunnel 365d' 에 해당하는 내용입니다. 이 값은 기본적으로 30s 로 되어 있습니다. 즉 blocking command 를 haproxy 주소로 전송하게되면, client 는 아시다시피 값이 들어올때까지 blocking 상태가 되는데, 30초가 넘어가버리면 연결이 끊어져 버립니다.

이를 방지하기 위해서 timeout 을 365 일로 지정해 주어야 합니다.(주석 풀기) 이 값을 infinite 로 하면 좋은데, 지원하지 않는것 같네요. 그래서 365 일로 설정했습니다. 365 일동안 해당 queue 에 값이 들어오지 않으면 서버와의 연결이 끊어지는 셈이죠.


이렇게 하지 않으면, blpop 상태에서 30초 이내에 값이 들어오지 않으면 Server 와의 연결이 끊어저 버립니다. :)






Redis 검증




이제 client 에서는 쓰기를 할때는 haproxy:5000 번 포트를, 읽기를 할때는 haproxy:5001 번 포트를 사용하면 됩니다. 항상 5000 번 포트는 master 를 가리킵니다. failover 가 되어서 slave 인 R3 가 master 가 되어도, 5000 번 포트로 들어온다면 master 로 승격된 R3 로 연결할 수 있게 됩니다.


현재 master 가 R2 로 되어 있는데, R2(redis:7001) 를 shutdown 시켜서 상황이 어떻게 바뀌는지 확인해 보도록 하겠습니다.


[und3r@sungwook haproxy-1.5.12]$ sudo /etc/init.d/redis_7001 stop

Stopping ...

Redis stopped



이제 haproxy 모니터링 페이지를 새로고침 해보면 다음처럼 바뀐것을 알 수 있습니다. 마스터가 R4 로 변경되었네요.





문제점



위와 같이 서버 구성이 끝났을때, 만약 HAProxy 가 shutdown 되면 어떻게 될까요? 네, redis 가 살아 있다고 하더라도 service 자체 이용이 불가능해 집니다. 그렇기 때문에 HAProxy 를 여러개 두고, L4 Switch 로 묶어줘야 하겠습니다. :)


이것으로 Redis 에 대한 모든 포스팅을 마치도록 하겠습니다.

Cluster 구성하는 방법도 포스팅 하고 싶긴 한데, 이 부분은 나중에 시간이 나면 하도록 하겠습니다.




'Database > Redis' 카테고리의 다른 글

Redis 3부 - Sentinel  (9) 2015.05.29
Redis 2부 - Replication  (4) 2015.05.27
Redis 1부 - 설치  (5) 2015.05.27