서비스를 운영할 때 단일 서버로 구성된 애플리케이션이 속도는 가장 빠르다. 하지만 여러 가지 애로사항이 존재한다. 물리적인 한계에 도달했을 때 확장이 불가능하다.


가장 단순한 방법은 서버 부품(Cpu, Memory, Disk)를 더 빠른 부품으로 교체한다. 기존 업무프로세스에 변동이 없는 대신 큰 비용을 사용해야 한다. 대기업에서 주로 사용하는 방법이며, 수직 확장 Scale up이다.


소규모 기업은 보통 비용 사용에 부담을 느끼기 때문에 다른 방법을 모색하는데, 서버를 같은 구성으로 추가하는 모습을 띠게 된다. 여기서 한가지 짚고 넘어가야 할 부분이 있다. 진입점이 여러 개가 되는데 한곳으로 만들어줘야만 클라이언트가 손쉽게 이용할 수 있다. 그렇지 않다면 직접 판단해서 접근해야 한다. 수평 확장 Scale out이다.


하나의 진입점에서 여러 개의 서버로 분배해주는 것을 Load Balancing 이라고하며 OSI 7 Layer 중 L4 Layer 이상이 되어야 tcp, udp등 프로토콜을 구분할 수 있다. 추가로 L7 Layer 애플리케이션 간의 프로토콜을 확인할 수 있으며 보통 http, https, smtp등 을 사용한다. 훨씬 많은 정보를 얻기 때문에 체계적인 Load Balancing이 가능하다.


HAProxy는 Scale out으로 확장할 때 진입점을 관리해주는 L4/L7 로드밸런서이며 tcp, http, https를 지원한다.



무료로 사용할 수 있는 HAProxy Community Edition이 있으며, 기업을 대상으로는 로드밸런서 HAProxy Enterprise Edition를 제공한다. 추가로 ALOHA Load Balancer는 하드웨어 장비에 HAProxy를 결합해서 판매하는 상품이다.


마이크로서비스로 아키텍처를 사용할수록 진입점이 많아지게 되는데, 이 부분을 HAProxy를 사용하면 효과적으로 관리할 수 있다.

GitHub, Instagram, Stackoverflow, Tumblr, Amazon web service, Openstack등 글로벌 기업들도 많이 사용하고 있다.


HAProxy Community Edition을 설치해보도록 하겠다. 사용하려면 아래 모듈이 설치되어 있어야 한다.


yum install gcc gcc-c++ pcre-devel openssl-devel


준비가 완료되면 아래 명령어를 이용하여 설치한다. Https 사용이 필요하다면 USE_OPENSSL 옵션을 활성화하도록 한다.


wget http://www.haproxy.org/download/1.8/src/haproxy-1.8.3.tar.gz
tar zxvf haproxy-1.8.3.tar.gz
make TARGET=linux2628 USE_PCRE=1 USE_OPENSSL=1 USE_ZLIB=1 
make PREFIX=/usr/local/haproxy DESTDIR= install


설정은 global, defaults, frontend, backend, listen 총 5가지 그룹으로 관리된다.



global은 프로세스 전체에 적용된다. 모든 영역에 적용하려는 값만 선언해야 한다.

defaults는 frontend, backend, listen 3가지를 선언했을 때 기본적으로 적용되는 옵션이다. 진입점을 1개만 선언해서 사용할 때에는 기본값에 명시해도 되지만, 진입점이 여러 개인 경우 각각 선언하는 편이 좋다.


frontend는 진입점을 선언하는 곳이며, 조건이 일치하는 경우 backend로 연결해주는 역할을 한다.

backend는 frontend가 실질적으로 연결할 server들을 선언하여 관리한다.


listen은 frontend, backend를 합쳐서 선언할 수 있다.


실제로 설정을 frontend, backend 2가지를 나눠서 하는 편이좀 더 명확한 것 같다. 


설치가 완료되면 /etc/haproxy.cfg을 생성하고 아래 샘플을 참고하여 작성하자.

실제 테스트 하면서 작성했던 설정 값이며, 필요한 옵션만 간략하게 정리하였다.


global
        daemon # 백그라운드에서 동작
 
        user    haproxy 
        group   haproxy
        log     127.0.0.1   local0
        log     127.0.0.1   local1 notice
        maxconn 4096 # 프로세스 별 최대 connection 갯수
 
        ssl-default-bind-options no-sslv3 # Bind SSL 프로토콜 정의
        ssl-default-bind-ciphers ECDHE-RSA-AES128-GCM-SHA256:... # Bind SSL 사용 알고리즘 목록 정의
 
        ssl-default-server-options no-sslv3 # Server SSL 프로토콜 정의
        ssl-default-server-ciphers ECDHE-RSA-AES128-GCM-SHA256:... # Server SSL 사용 알고리즘 목록 정의
 
        tune.ssl.cachesize 100000 # SSL Session Cache 크기 설정
        tune.ssl.lifetime 600 # SSL Session 유효시간 설정
        tune.ssl.default-dh-param 2048 # Diffie-Hellman 키 교환 시 최대 크기 설정
 
defaults
        maxconn 4096 # 프로세스 별 최대 connection 갯수
 
frontend https-in
        mode    http
        log     global
        option  httplog
        option  dontlognull
 
        bind *:80 # listening 되어야하는 ip, port 설정
        bind *:443 ssl crt ./key.pem ca-file ./key.ca verify optional alpn h2,http/1.1 # (listening 되어야하는 ip, port + ssl + http/1.1, http/2) 설정
 
        timeout client  30s # client에서 haproxy 접속 시 timeout 설정
        timeout http-keep-alive 5s # 새로운 http 요청이 들어오기까지의 대기시간
 
        # host 지정 모든문자열이 일치 할 경우
        acl stats hdr(host) -i test.haproxy.com 
        acl host_api_cluster hdr(host) -i test.server.com
 
        # host가 일치할 때 지정 된 backend로 진행
        use_backend haproxy_stats if host_haproxy_stats 
        use_backend test_server if host_api_cluster
 
backend stats
        mode    http
        log     global
        option  httplog
        option http-server-close # 응답이 완료되면 server 측에서 연결을 종료함
 
        stats enable # 모니터링 활성화
        stats auth id:password # 모니터링 인증 활성화 basic auth 아이디, 비밀번호 설정
        stats uri /stats # 모니터링 페이지 url 설정
        stats hide-version # 버전 숨김
 
backend test_server
        mode    http
        log     global
        option  httplog
 
        balance leastconn # 요청 분배 알고리즘 설정
 
        timeout connect 10s # haproxy에서 server 접속 시 timeout 설정
        timeout check   5s # haproxy에서 check 목적으로 접속 시 timeout 설정
        timeout server  30s # haproxy에서 server 접속 시 timeout 설정
        timeout http-keep-alive 5s # 새로운 http 요청이 들어오기까지의 대기시간
 
        acl valid_method method GET POST PUT DELETE # 허용할 메소드 설정
        http-request deny if ! valid_method # 메소스 조건 확인
 
        http-request replace-value Host (.*):.* 1 # server에 client에서 요청한 Host 전달
        http-request set-header x-forwarded-for %ci # server에 remoteAddress 전달
 
        option httpchk GET /status # server에 지정된 상태 체크 url로 요청하여 확인
        http-check expect status 200 string OK # 응답 시 상태코드 200 + 문자열 OK 확인
 
        default-server inter 100 rise 2 fall 5 # 검사 조건 (확인 주기 100/ms, 2번이상 성공시 정상 확인, 5번이상 실패 시 제외)
        server server-001 192.168.0.1:8080 check # 서버 alias, ip:port, 검사 여부
        server server-002 192.168.0.2:8080 check 
        server server-003 192.168.0.3:8080 check


작성이 완료되었다면 /usr/local/haproxy/sbin/haproxy -f /etc/haproxy.cfg 명령어를 입력하여 시작하자.

자세한 내용은 http://cbonte.github.io/haproxy-dconv/ HAProxy 1.8 Documentation를 참고 하도록한다.


참고 사이트

  • http://www.haproxy.org/
  • http://www.haproxy.com/
  • http://cbonte.github.io/haproxy-dconv/
  • https://networkel.com/osi-model-7-layer-network-communication/
  • http://d2.naver.com/helloworld/284659
  • https://www.haproxy.com/documentation/aloha/7-0/traffic-management/lb-layer7/health-checks/
  • https://www.haproxy.com/blog/ssl-client-certificate-management-at-application-level/
  • https://www.haproxy.com/documentation/aloha/6-5/haproxy/tls/
  • http://inor.tistory.com/35
  • https://www.haproxy.com/blog/haproxy-amazon-aws-best-practices-part-1/


프로젝트가 운영단계로 접어들게 되면, 안정성과 신뢰성이 중요하게 작용한다. 장애, 재해 등 발생했을 때 데이터 복구 작업이 필요한데 준비되어 있지 않아, 데이터가 유실되거나, 초기화되는 경우 신뢰성은 추락하게 된다.


대비하려면 반드시 백업/복구에 대해 준비를 해야 한다. MariaDB 백업/복구는 mysqldump, xtrabackup 2가지 방법이 있다.


mysqldump는 설치 시 기본적으로 제공되는데, SQL 기반으로 백업되기 때문에 대응이 xtrabackup 보다는 편리하다.

운영 초기에는 별문제 없이 사용할 수 있는데, 데이터양이 많아졌을 때 한계점에 부딪치게 된다. 

모든 데이터를 메모리에 올려놓고 SQL로 변환하는 만큼 서버에 부담이 많이 가고, 백업도 많은 시간이 소요된다. 마찬가지로 복구도 모든 SQL이 실행되어야 하므로 같은 문제점을 가지고 있다.


xtrabackup은 Mysql, MariaDB 모든 버전을 지원하는 백업 솔루션이다. facebook은 엄청난 양의 데이터를 생성하는데 백업은 xtrabackup를 사용하고 있다.


“Facebook users create a vast amount of data every day. To make sure that data is stored reliably, we back up our databases daily. Facebook was an early adopter of incremental backup in Percona XtraBackup.”


대표적인 기능은 빠르고 안정적으로 백업/복구가 가능하고, 백업 중 중단없이 트랜젝션 처리가 가능하다. 모든 데이터를 가공하는 게 아닌, data 파일을 복제하는 것을 기반으로 하기 때문이다. 추가로 증분 백업을 지원하기 때문에 데이터양이 많아도 시점별로 관리가 가능하다.


사용하려면 별도로 설치해야 한다. linux에서만 지원하기 때문에, windows에서는 사용할 수 없다.

설치 가이드: https://www.percona.com/doc/percona-xtrabackup/LATEST/installation.html


설치가 완료되었다면 innobackupex 명령어를 통해서 전체 백업을 진행해보자.


백업 하기 전 주의사항이 있는데 엔진이 InnoDB인 경우 백업을 완료하는 시점에서 현재 스키마를 저장하기 위해 일시적으로 'Global Lock'을 걸게 되는데, 그 시간 동안 write 작업은 대기 상태가 되고, Lock이 해제되는 순간 진행된다. 데이터 파일이 크다면 길어질 수 있기 때문에 "--no-lock" 옵션을 사용하게 되면 이슈는 사라진다. 처리 시간은 DISK I/O의 영향을 많이 받으며, 가능하다면 별도의 디스크에 백업하는 것을 권장한다. 


전체 백업 시에는 MariaDB 서버의 설정 파일을 "--default-file"에 명시해야 한다. 서버 메모리가 여유가 된다면 "--use-memory"를 늘려서 처리하면 빠르게 진행할 수 있다. 백업이 완료된 후 "/backups"로 이동하여 파일을 확인해보면 data 파일이 이동된 것을 확인할 수 있다.


innobackupex \
        --default-file=my.cnf \
        --backup \
        --host=${backup_host} \
        --port=${backup_port} \
        --user=${backup_user} \
        --password=${backup_password} \
        --parallel=4 \
        --no-lock \
        --use-memory=4gb \
        /backups


데이터 복구를 진행하기 전 반드시 MariaDB 서버를 종료시키고, data 파일은 비워줘야 한다. 복구 시 파일 덮어쓰기는 불가능하다.

"/backups"를 data 파일 경로에 복사하여 복구 하므로 MariaDB 접속은 하지 않아도 된다.


복구 하기 전 "--apply-log" 옵션을 넣어서 준비상태로 만들어야 한다.


innobackupex \
        --use-memory=4gb \
        --apply-log \
/backups


완료되면 "--copy-back" 옵션을 넣고 복구를 진행한다.


innobackupex \
        --default-file=my.cnf \
        --parallel=4 \
        --copy-back \
        --use-memory=4gb \
        /backups


data 경로의 권한을 mysql로 변경해야 시작 시 권한 문제가 발생하지 않는다.


chown -R mysql. /mariadb/data


MariaDB를 시작하면 복구된 데이터를 확인할 수 있다.


만약 시간이 허락한다면, xtrabackup를 도입해서 장기적으로 장애 및 재해에 미리 대비하는 편이 안전하고 신뢰성을 높이는 길이라고 생각된다.


참고 사이트

  • https://www.percona.com/doc/percona-xtrabackup/LATEST/index.html
  • [리얼타임] MariaDB 실전 활용 노하우 (6.1. xtrabackup 참고)


+ Recent posts