대용량 분산 아키텍쳐
http://www.slideshare.net/Byungwook/1-34910291
대용량 분산 아키텍쳐
http://www.slideshare.net/Byungwook/1-34910291
Ncloud에서 하드웨어로 구성된 기존의 로드 밸런서(load balancer)를 대체할 수 있는 솔루션을 찾던 중 소프트웨어 로드 밸런서인 HAProxy를 검토하게 됐습니다. HAProxy를 검토하면서 정리한 자료와 사내 개발용 Ncloud(ncloud.nhncorp.com) 서비스에 HAProxy를 적용한 사례를 공유하려 합니다.
HAProxy를 이해하기 위해서 우선 로드 밸런서의 기본 개념을 이해하고 HAProxy의 동작 방식을 알아보겠습니다. 그리고 HAProxy로 설계 가능한 구조를 알아보겠습니다.
HAProxy는 기존의 하드웨어 스위치를 대체하는 소프트웨어 로드 밸런서로, 네트워크 스위치에서 제공하는 L4, L7 기능 및 로드 밸런서 기능을 제공한다. HAProxy는 설치가 쉽고 또한 환경 설정도 어렵지 않으므로 서비스 이중화를 빠르게 구성하고 싶다면 HAProxy를 추천한다.
로드 밸런싱이란 부하 분산을 위해서 가상(virtual) IP를 통해 여러 서버에 접속하도록 분배하는 기능을 말한다. 로드 밸런싱에서 사용하는 주요 기술은 다음과 같다.
이제 일반적인 로드 밸런서의 동작 방식을 설명하고 HAProxy를 설명하겠다.
로드 밸런서의 동작을 간단하게 설명하면, 네트워크에서 IP 주소와 MAC 주소를 이용해 목적지(destination) IP 주소를 찾아가고 출발지로 되돌아오는 구조이다. 이 글에서는 4가지의 로드 밸런서 동작 방식을 설명하겠다. 일반적인 로드 밸런서의 동작을 참조하기 위한 것이므로 정확하게 이해하지 못해도 상관없다.
사용자가 서비스를 요청하면 L4로 전달된 목적지 IP 주소를 real server IP 주소로 변조하고 MAC 주소를 변조해서 목적지를 찾아가는 방식이다.
Bridge/Transparent Mode와 유사하지만 출발지(source) MAC 주소도 변조된다.
사용자가 real server에 접근할 때 목적지 IP는 L4 스위치 IP를 바라본다. L4에 도달하면 L4가 클라이언트에게 받은 목적지 IP 주소를 L4 IP 주소에서 real server IP와 real server MAC 주소로 변조한다. 되돌아가는 IP는 L4의 IP pool의 IP 주소로 변조한다.
사용자가 real server에 접근할 때 출발지와 목적지의 IP 주소를 변조하지 않고, L4에서 관리하는 real server의 MAC 주소 테이블을 확인해서 MAC 주소만 변조한다.
HAProxy는 기본적으로 reverse proxy 형태로 동작한다. 우리가 브라우저에서 사용하는 proxy는 클라이언트 앞에서 처리하는 기능으로, forward proxy라 한다. reverse proxy의 역할을 간단히 설명하면, 실제 서버 요청에 대해서 서버 앞 단에 존재하면서, 서버로 들어오는 요청을 대신 받아서 서버에 전달하고 요청한 곳에 그 결과를 다시 전달하는 것이다.
HAProxy의 동작 방식을 알아보고 HAProxy를 이용해서 어떤 구조로 확장할 수 있는지 알아보겠다.
HAProxy의 동작 흐름은 다음과 같다.
HAProxy는 기본적으로 VRRP(Virtual Router Redundancy Protocol)를 지원한다. HAProxy의 성능상 초당 8만 건 정도의 연결을 처리해도 크게 무리가 없지만, 소프트웨어 기반의 솔루션이기 때문에 HAProxy가 설치된 서버에서 문제가 발생하면 하드웨어 L4보다는 불안정할 수 있다. 따라서 HA 구성으로 master HAProxy에 문제가 생기는 경우에도 slave HAProxy에서 서비스가 원활하게 제공될 수 있는 구성을 알아보겠다.
다음 그림과 같은 구성에서는 가상 IP 주소를 공유하는 active HAProxy 서버와 standby HAProxy 서버가 heartbeat를 주고 받으면서 서로 정상적으로 동작하는지 여부를 확인한다. active 상태의 서버에 문제가 발생하면 standby HAProxy가 active 상태로 변경되면서 기존 active HAProxy의 가상 IP 주소를 가져오면서 서비스가 무정지 상태를 유지한다. 다만 1초 정도의 순단 현상은 발생할 수 있다.
HA로 설정된 HAProxy의 동작 흐름이 단일 HAProxy와 다른 점은 최초 접근 시 쿠키에 바로 서버 정보를 입력하지 않고 서버에서 jsessionid가 전달될 때 서버 정보를 합쳐서 전달한다는 것이다.
HAProxy와 기존 하드웨어 스위치를 이용해서 더 확장된 형태의 고가용성 구조를 설계할 수가 있다. 다음과 같은 형태의 구성도 가능하다.
클라이언트에서 연결되는 부분은 가상 IP 주소 + L4의 구성으로 하드웨어 이중화를 구축하고, L4에서 서버 앞 단에 HAProxy를 구축해서 HAProxy를 더 확장할 수 있는 구조로 설계할 수 있다.
global 서비스가 증가되면서 IDC 간 이중화 및 global 환경에서의 무정지 서비스를 위한 DR(Disaster Recovery, 재해 복구) 시스템 구축이 필수 요구사항이 되었다. GSLB + HAProxy를 이용하면 global한 무정지 서비스 구축이 가능하다.
GSLB 구축에 L4 스위치를 사용할 수도 있지만 GSLB 구성용 L4는 고가의 장비이다. 따라서 L4를 이용한 GSLB 대신 DNS(BIND)를 이용한 구축 형태는 다음과 같다.
이상 로드 밸런서의 동작 원리와 HAProxy를 이용한 다양한 구축 방법에 대해서 알아보았다. 이제 실제 HAProxy를 설치하기 위한 옵션 및 설치 방법에 대해서 알아보겠다.
사내 개발자용 Ncloud 시스템은 DNS에서 RR(Round Robin) 기능을 통해 이중화된 서비스로 운영하고 있었다. 그런데 DNS의 경우 팀에서 관리하는 시스템도 아니고 서버 증설 또는 제거를 위해서 매번 관리 시스템을 통해서 작업하는 것이 번거로웠다. 또한 HAProxy의 실제 적용을 테스트하기 위해서 우리가 관리하는 시스템에 적용했는데, 이 적용 및 운영 사례를 살펴보겠다.
사내 Ncloud 시스템의 DNS RR을 HAProxy로 교체하여 <그림 6>과 같이 앞에서 설명한 HA 구성과 동일한 형태로 구성했다. 그 결과 기존 DNS로 구성할 때보다 서버 증설 및 삭제에 있어 유연성이 증가했으며 HA 구성으로 서비스 안정성도 높아졌다.
그런데 서버 반영 후 애플리케이션 서버에서 클라이언트 IP 주소를 찾아서 처리하는 로직에 문제가 발생했다. 확인 결과 사용자의 요청이 HAProxy를 거치면서 클라이언트 IP 주소 정보가 HAProxy의 정보로 변조되어 보이는 상황이었다.
이 문제가 발생하지 않도록 하기 위해서 HAProxy에서 제공하는 X-Forwarded-For 옵션을 적용하고 Apache 서에는 mod_rpaf 모듈을 설치해서 애플리케이션 서버가 HTTP 헤더에서 클라이언트 IP 주소를 조회하면 실제 클라이언트 IP 주소가 반환되도록 보완했다.
실제 적용 후 서버 L7 check가 잘 되고 있는지 HAProxy가 제공하는 어드민 페이지에서 확인했고, 클라이언트 IP 주소 문제 외에 별다른 이슈는 발생하지 않았다.
Ncloud는 동시 접속자가 많은 시스템이 아니라 성능에 대해 크게 문제될 부분이 없었지만 HAProxy가 설치되는 서버의 사양에 따라 어느 정도 성능이 제공되는지 확인하기 위해 성능을 측정했다. 여기에서는 nGrinder(http://www.nhnopensource.org/ngrinder/) 테스트 결과와 해외 사례를 공유한다.
HAProxy의 중요 옵션과 단점에 대해서 간단하게 알아보겠다. 자세한 설치 방법 및 서비스에 사용되는 설정은 마지막에 설명해 놓았으니 실제 설치가 필요한 경우에 참고하기 바란다.
HAProxy의 경우 튜닝 옵션을 비롯하여 매우 많은 옵션을 지원하므로 여기에서는 실제 구축 시 필요한 옵션만 간략하게 알아보겠다.
옵션을 변경하려면 haproxy.cfg 파일을 수정한다. 실제 수정 방법은 설치 방법에서 설명한다. 더 자세한 설명이 필요하면 다음 웹 페이지에서 확인하기 바란다.
다음은 전역 옵션(global) 섹션과 기본 옵션(defaults) 섹션, 프록시 옵션 섹션(listen)의 주요 옵션에 관한 설명이다.
로드 밸런싱의 경우 round robin 방식을 일반적으로 사용하지만 다른 여러 방식이 있다. 옵션에 적용할 수 있는 로드 밸런싱 알고리즘은 다음과 같다.
1.4.22 안정화 버전에서는 기본 기능으로 SSL을 지원하지 않고 있다. 1.4.22 버전에서 HTTP와 HTTPS를 같이 지원하려면 Apache + mod_ssl + HAProxy를 구성해서 Apache를 reverse-proxy-cache로 사용한다. only HTTPS 모드이면 stunnel을 설정하고 사용할 수 있다.
현재 개발 중인 1.5_dev 버전은 에서는 정식으로 SSL을 지원할 예정이다.
HAProxy 설치를 위한 소스 파일 다운로드와 설치 절차는 다음과 같다.
$ wget http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.22.tar.gz
$ tar xvfz haproxy-1.4.22.tar.gz
$ cd harproxy-1.4.22
$ make TARGET=linux26 ARCH=x86_64
$ make install
$ cd examples
$ cp haproxy.init /etc/rc.d/init.d/haproxy
$ chmod 755 /etc/rc.d/init.d/haproxy
$ mkdir -p /etc/haproxy/
$ cp /생성위치/haproxy-1.4.22/examples/haproxy.cfg /etc/haproxy/
$ mkdir -p /etc/haproxy/errors/
$ cp /생성위치/haproxy-1.4.22/examples/errorfiles/* /etc/haproxy/errors/
$ cd /usr/sbin
$ ln -s /usr/local/haproxy/sbin/haproxy haproxy
$ vi /etc/haproxy/haproxy.cfg
haproxy.cfg 파일은 다음 설정 예제를 참고해서 수정하면 된다.
#서버 정보
#LB ip 10.101.22.33
#server-1 10.101.27.49
#server-2 10.101.26.50
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
uid 99
gid 99
daemon
log-send-hostname
#debug
#quiet
defaults
log global
listen webfarm 10.101.22.33:80
mode http
option httpchk GET /l7check.html HTTP/1.0
option log-health-checks
option forwardfor
option httpclose
cookie SERVERID rewrite
cookie JSESSIONID prefix
balance roundrobin
stats enable
stats uri /admin
server xvadm01.ncli 10.101.27.49:80 cookie admin_portal_1 check inter 1000 rise 2 fall 5
server xvadm02.ncli 10.101.26.50:80 cookie admin_portal_2 check inter 1000 rise 2 fall 5
$ /etc/init.d/haproxy start
HAProxy는 네트워크 담당자가 아닌 개발자들에게는 관심 없는 분야의 기술일 수 있다. 그렇지만 모바일 환경이 발달하면서 빠르고 유연한 확장성은 필수 요소로 생각해야 한다. 최초 서비스 구축 시 확장성을 고려해서 L4/L7 스위치 분산까지는 고려할 수 있겠지만 지역간 분산(GSLB 구성)을 고려해서 설계하는 것은 일부 업체를 제외하고는 비용 및 경험 부재로 쉽지 않은 것이 사실이다. 하지만 'DNS + HAProxy + 클라우드 서비스'로 조합하면 적은 비용으로도 동일한 수준으로 구축할수 있다. 그래서 HAProxy의 개념과 서비스 구축 방안 정도는 미리미리 습득하기를 권장한다.
eclipse 실행 시 시스템 jdk 버전과 다르게 사용하고 싶은 경우나, jdk 경로를 찾지 못하는 경우
아래와 같이 설정.
eclipse.ini에 다음을 추가한다.
-vm
C:\java\jdk1.7.0_21\bin\javaw.exe
-startup
plugins/org.eclipse.equinox.launcher_1.3.100.v20150511-1540.jar
--launcher.library
plugins/org.eclipse.equinox.launcher.win32.win32.x86_64_1.1.300.v20150602-1417
-product
org.eclipse.epp.package.jee.product
--launcher.defaultAction
openFile
--launcher.XXMaxPermSize
256M
-showsplash
org.eclipse.platform
--launcher.XXMaxPermSize
256m
--launcher.defaultAction
openFile
--launcher.appendVmargs
-vm
C:\Program Files\Java\jdk1.7.0_79\bin\javaw.exe
-vmargs
-Dosgi.requiredJavaVersion=1.7
-Xms256m
-Xmx1024m