반응형

대용량 분산 아키텍쳐

http://www.slideshare.net/Byungwook/1-34910291


대용량 아키텍처와 성능 튜닝

https://code.google.com/archive/p/architect/wikis/bigArchitecture.wiki


네이버 개발자 센터
http://d2.naver.com/home


반응형
LIST
반응형

In memory dictionary Redis 소개

클라우드 컴퓨팅 & NoSQL/Redis | 2014.01.24 00:44 | Posted by 조대협

redis Introduction


Intro
Redis는 "REmote DIctionary System"의 약자로 메모리 기반의 Key/Value Store 이다.
Cassandra나 HBase와 같이 NoSQL DBMS로 분류되기도 하고, memcached와 같은 In memory 솔루션으로 분리되기도 한다.
성능은 memcached에 버금가면서 다양한 데이타 구조체를 지원함으로써 Message Queue, Shared memory, Remote Dictionary 용도로도 사용될 수 있으며, 이런 이유로 인스탄트그램, 네이버 재팬의 LINE 메신져 서비스, StackOverflow,Blizzard,digg 등 여러 소셜 서비스에 널리 사용되고 있다.
BSD 라이센스 기반의 오픈 소스이며 최근 VMWare에 인수되어 계속해서 업그레이드가 되고 있다.
16,000 라인정도의 C 코드로 작성되었으며, 클라이언트 SDK로는
Action Script,C,C#,C++,Clojure,Erlang,Java,Node.js,Objective-C,Perl,PHP,Python,Smalltalk,Tcl등 대부분의 언어를 지원한다. (참고 : http://www.redis.io/clients )

이번 글에서는 Redis란 무엇인지, 그리고 대략적인 내부 구조에 대해서 살펴보도록 한다.

1. Key/Value Store
Redis는 기본적으로 Key/Value Store이다. 특정 키 값에 값을 저장하는 구조로 되어 있고 기본적인 PUT/GET Operation을 지원한다.

단, 이 모든 데이타는 메모리에 저장되고, 이로 인하여 매우 빠른 write/read 속도를 보장한다. 그래서 전체 저장 가능한 데이타 용량은 물리적인 메모리 크기를 넘어설 수 있다. (물론 OS의 disk swapping 영역등을 사용하여 확장은 가능하겠지만 성능이 급격하게 떨어지기 때문에 의미가 없다.)
데이타 억세스는 메모리에서 일어나지만 server restart 와 같이 서버가 내려갔다가 올라오는 상황에 데이타를 저장을 보장하기 위해서 Disk를 persistence store로 사용한다.

2. 다양한 데이타 타입
단순한 메모리 기반의 Key/Value Store라면 이미 memcached가 있지 않은가? 그렇다면 어떤 차이가 있길래 redis가 유행하는 것일까?
redis가 Key/Value Store이기는 하지만 저장되는 Value가 단순한 Object가 아니라 자료구조를 갖기 때문에 큰 차이를 보인다.
redis가 지원하는 데이타 형은 크게 아래와 같이 5가지가 있다.

1) String
일반적인 문자열로 최대 512mbyte 길이 까지 지원한다.
Text 문자열 뿐만 아니라 Integer와 같은 숫자나 JPEG같은 Binary File까지 저장할 수 있다.

2) Set
set은 string의 집합이다. 여러개의 값을 하나의 Value 내에 넣을 수 있다고 생각하면 되며 블로그 포스트의 태깅(Tag)등에 사용될 수 있다.
재미있는 점은 set간의 연산을 지원하는데, 집합인 만큼 교집합, 합집합, 차이(Differences)를 매우 빠른 시간내에 추출할 수 있다.

3) Sorted Set
set 에 "score" 라는 필드가 추가된 데이타 형으로 score는 일종의 "가중치" 정도로 생각하면 된다.
sorted set에서 데이타는 오름 차순으로 내부 정렬되며, 정렬이 되어 있는 만큼 score 값 범위에 따른 쿼리(range query), top rank에 따른 query 등이 가능하다.


4) Hashes
hash는 value내에 field/string value 쌍으로 이루어진 테이블을 저장하는 데이타 구조체이다.
RDBMS에서 PK 1개와 string 필드 하나로 이루어진 테이블이라고 이해하면 된다.


5) List
list는 string들의 집합으로 저장되는 데이타 형태는 set과 유사하지만, 일종의 양방향 Linked List라고 생각하면 된다. List 앞과 뒤에서 PUSH/POP 연산을 이용해서 데이타를 넣거나 뺄 수 있고, 지정된 INDEX 값을 이용하여 지정된 위치에 데이타를 넣거나 뺄 수 있다. 


6) 데이타 구조체 정리
지금까지 간략하게 redis가 지원하는 데이타 구조체들에 대해서 살펴보았다.
redis의 데이타 구조체의 특징을 다시 요약하자면
  • Value가 일반적인 string 뿐만 아니라, set,list,hash와 같은 집합형 데이타 구조를 지원한다.
  • 저장된 데이타에 대한 연산이나 추가 작업 가능하다. (합집합,교집합,RANGE QUERY 등)
  • set은 일종의 집합, sorted set은 오름차순으로 정렬된 집합, hash는 키 기반의 테이블, list는 일종의 링크드 리스트 와 같은 특성을 지니고 있다.
이러한 집합형 데이타 구조 (set,list,hash)등은 redis에서 하나의 키당 총 2^32개의 데이타를 이론적으로 저장할 수 있으나, 최적의 성능을 낼 수 있는 것은 일반적으로 1,000~5,000개 사이로 알려져 있다.

데이타 구조에 따른 저장 구조를 정리해서 하나의 그림에 도식화해보면 다음과 같다.



3. Persistence
앞서도 언급하였듯이, redis는 데이타를 disk에 저장할 수 있다. memcached의 경우 메모리에만 데이타를 저장하기 때문에 서버가 shutdown 된후에 데이타가 유실 되지만, redis는 서버가 shutdown된 후 restart되더라도, disk에 저장해놓은 데이타를 다시 읽어서 메모리에 Loading하기 때문에 데이타 유실되지 않는다.
redis에서는 데이타를 저장하는 방법이 snapshotting 방식과 AOF (Append on file) 두가지가 있다.

1) snapshotting (RDB) 방식
순간적으로 메모리에 있는 내용을 DISK에 전체를 옮겨 담는 방식이다.
SAVE와 BGSAVE 두가지 방식이 있는데,
SAVE는 blocking 방식으로 순간적으로 redis의 모든 동작을 정지시키고, 그때의 snapshot을 disk에 저장한다.
BGSAVE는 non-blocking 방식으로 별도의 process를 띄운후, 명령어 수행 당시의 메모리 snaopshot을 disk에 저장하며, 저장 순간에 redis는 동작을 멈추지 않고 정상적으로 동작한다.
  • 장점 : 메모리의 snapshot을 그대로 뜬 것이기 때문에, 서버 restart시 snapshot만 load하면 되므로 restart 시간이 빠르다.
  • 단점 : snapshot을 추출하는데 시간이 오래 걸리며, snapshot 추출된후 서버가 down되면 snapshot 추출 이후 데이타는 유실된다.
    (백업 시점의 데이타만 유지된다는 이야기)
2) AOF 방식
AOF(Append On File) 방식은 redis의 모든 write/update 연산 자체를 모두 log 파일에 기록하는 형태이다. 서버가 재 시작될때 기록된  write/update operation을 순차적으로 재 실행하여 데이타를 복구한다. operation 이 발생할때 마다 매번 기록하기 때문에, RDB 방식과는 달리 특정 시점이 아니라 항상 현재 시점까지의 로그를 기록할 수 있으며, 기본적으로 non-blocking call이다.
  • 장점 : Log file에 대해서 append만 하기 때문에, log write 속도가 빠르며, 어느 시점에 server가 down되더라도 데이타 유실이 발생하지 않는다.
  • 단점 : 모든 write/update operation에 대해서 log를 남기기 때문에 로그 데이타 양이 RDB 방식에 비해서 과대하게 크며, 복구시 저장된 write/update operation을 다시 replay 하기 때문에 restart속도가 느리다.
3) 권장 사항
RDB와 AOF 방식의 장단점을 상쇠하기 위해서 두가지 방식을 혼용해서 사용하는 것이 바람직한데
주기적으로 snapshot으로 백업하고, 다음 snapshot까지의 저장을 AOF 방식으로 수행한다.
이렇게 하면 서버가 restart될 때 백업된 snapshot을 reload하고, 소량의 AOF 로그만 replay하면 되기 때문에, restart 시간을 절약하고 데이타의 유실을 방지할 수 있다.


4. Pub/Sub Model
redis는 JMS나 IBM MQ 같은 메세징에 활용할 수 있는데, 1:1 형태의 Queue 뿐만 아니라 1:N 형태의 Publish/Subscribe 메세징도 지원한다.(Publish/Subscribe 구조에서 사용되는 Queue를 일반적으로 Topic이라고 한다.)
하나의 Client가 메세지를 Publish하면, 이 Topic에 연결되어 있는 다수의 클라이언트가 메세지를 받을 수 있는 구조이다. (※ Publish/Subscribe 형태의 messaging 에 대해서는 http://en.wikipedia.org/wiki/Pub/sub  를 참고하기 바란다.)


재미있는 것중에 하나는 일반적인 Pub/Sub 시스템의 경우 Subscribe 하는 하나의 Topic에서만 Subscribe하는데 반해서, redis에서는 pattern matching을 통해서 다수의 Topic에서 message 를 subscribe할 수 있다.
예를 들어 topic 이름이 music.pop music,classic 이라는 두개의 Topic이 있을때, "PSUBSCRIBE music.*"라고 하면 두개의 Topic에서 동시에 message를 subscribe할 수 있다.

5. Replication Topology
redis는 NoSQL 계열의 Key/Store Storage인데 반해서 횡적 확장성을 지원하지 않는다.
쉽게 말해서 2.4.15 현재 버전 기준으로는 클러스터링 기능이 없다. (향후 지원 예정)
그래서 확장성(scalability)과 성능에 제약사항이 있는데, 다행이도 Master/Slave 구조의 Replication(복제)를 지원하기 때문에 성능 부분에 있어서는 어느정도 커버가 가능하다.

Master/Slave replication
Master/Slave Replication이란, redis의 master node에 write된 내용을 복제를 통해서 slave node에 복제 하는 것을 정의한다.
1개의 master node는 n개의 slave node를 가질 수 있으며, 각 slave node도 그에 대한 slave node를 또 가질 수 있다.


이 master/slave 간의 복제는 Non-blocking 상태로 이루어진다. 즉 master node에서 write나 query 연산을 하고 있을 때도 background로 slave node에 데이타를 복사하고 있다는 이야기고, 이는 master/slave node간의 데이타 불일치성을 유발할 수 있다는 이야기이기도 하다.
master node에 write한 데이타가 slave node에 복제중이라면 slave node에서 데이타를 조회할 경우 이전의 데이타가 조회될 수 있다.

Query Off Loading을 통한 성능 향상
그러면 이 master/slave replication을 통해서 무엇을 할 수 있냐? 성능을 높일 수 있다. 동시접속자수나 처리 속도를 늘릴 수 있다. (데이타 저장 용량은 늘릴 수 없다.) 이를 위해서 Query Off Loading이라는 기법을 사용하는데
Query Off Loading은 master node는 write only, slave node는 read only 로 사용하는 방법이다.
단지 redis에서만 사용하는 기법이 아니라, Oracle,MySQL과 같은 RDBMS에서도 많이 사용하는 아키텍쳐 패턴이다.
대부분의 DB 트렌젝션은 웹시스템의 경우 write가 10~20%, read가 70~90% 선이기 때문에, read 트렌젝션을 분산 시킨다면, 처리 시간과 속도를 비약적으로 증가 시킬 수 있다. 특히 redis의 경우 value에 대한 여러가지 연산(합집합,교집합,Range Query)등을 수행하기 때문에, 단순 PUT/GET만 하는 NoSQL이나 memcached에 비해서 read에 사용되는 resource의 양이 상대적으로 높기 때문에 redis의 성능을 높이기 위해서 효과적인 방법이다.

Sharding 을 통한 용량 확장
redis가 클러스터링을 통한 확장성을 제공하지 않는다면, 데이타의 용량이 늘어나면 어떤 방법으로 redis를 확장해야 할까?
일반적으로 Sharding이라는 아키텍쳐를 이용한다. Sharding은 Query Off loading과 마친가지로, redis 뿐만 아니라 일반적인 RDBMS나 다른 NoSQL에서도 많이 사용하는 아키텍쳐로 내용 자체는 간단하다.
여러개의 redis 서버를 구성한 후에, 데이타를 일정 구역별로 나눠서 저장하는 것이다. 예를 들어 숫자를 key로 하는 데이타가 있을때 아래와 그림과 같이 redis 서버별로 저장하는 key 대역폭을 정해놓은 후에, 나눠서 저장한다.
데이타 분산에 대한 통제권은 client가 가지며 client에서 애플리케이션 로직으로 처리한다.

현재 버전 2.4.15에서는 Clustering을 지원하지 않아서 Sharding을 사용할 수 밖에 없지만 2012년 내에 Clustering기능이 포함된다고 하니, 확장성에 대해서 기대해볼만하다. redis가 지원할 clustering 아키텍쳐는 ( http://redis.io/presentation/Redis_Cluster.pdf ) 를 참고하기 바란다.

6. Expriation
redis는 데이타에 대해서 생명주기를 정해서 일정 시간이 지나면 자동으로 삭제되게 할 수 있다.
redis가 expire된 데이타를 삭제 하는 정책은 내부적으로 Active와 Passive 두 가지 방법을 사용한다.
Active 방식은 Client가 expired된 데이타에 접근하려고 했을 때, 그때 체크해서 지우는 방법이 있고
Passive 방식은 주기적으로 key들을 random으로 100개만 (전부가 아니라) 스캔해서 지우는 방식이 이다.
expired time이 지난 후 클라이언트에 의해서 접근 되지 않은 데이타는 Active 방식으로 인해서 지워지지 않고 Passive 방식으로 지워져야 하는데, 이 경우 Passive 방식의 경우 전체 데이타를 scan하는 것이 아니기 때문에, redis에는 항상 expired 되었으나 지워지지 않는 garbage 데이타가 존재할 수 있는 원인이 된다.

7. Redis 설치(윈도우즈)
https://github.com/rgl/redis/downloads 에서 최신 버전 다운로드 받은후
redis-server.exe를 실행

클라이언트는 redis-cli.exe를 실행
아래는 테스트 스크립트
    % cd src
    % ./redis-cli
    redis> ping
    PONG
    redis> set foo bar
    OK
    redis> get foo
    "bar"
    redis> incr mycounter
    (integer) 1
    redis> incr mycounter
    (integer) 2
    redis> 


참고 자료


반응형
LIST
반응형

L4/L7 스위치의 대안, 오픈 소스 로드 밸런서 HAProxy

Ncloud에서 하드웨어로 구성된 기존의 로드 밸런서(load balancer)를 대체할 수 있는 솔루션을 찾던 중 소프트웨어 로드 밸런서인 HAProxy를 검토하게 됐습니다. HAProxy를 검토하면서 정리한 자료와 사내 개발용 Ncloud(ncloud.nhncorp.com) 서비스에 HAProxy를 적용한 사례를 공유하려 합니다.

HAProxy를 이해하기 위해서 우선 로드 밸런서의 기본 개념을 이해하고 HAProxy의 동작 방식을 알아보겠습니다. 그리고 HAProxy로 설계 가능한 구조를 알아보겠습니다.

오픈 소스 로드 밸런서 HAProxy

HAProxy는 기존의 하드웨어 스위치를 대체하는 소프트웨어 로드 밸런서로, 네트워크 스위치에서 제공하는 L4, L7 기능 및 로드 밸런서 기능을 제공한다. HAProxy는 설치가 쉽고 또한 환경 설정도 어렵지 않으므로 서비스 이중화를 빠르게 구성하고 싶다면 HAProxy를 추천한다.

로드 밸런싱이란?

로드 밸런싱이란 부하 분산을 위해서 가상(virtual) IP를 통해 여러 서버에 접속하도록 분배하는 기능을 말한다. 로드 밸런싱에서 사용하는 주요 기술은 다음과 같다.

  • NAT(Network Address Translation): 사설 IP 주소를 공인 IP 주소로 바꾸는 데 사용하는 통신망의 주소 변조기이다.
  • DSR(Dynamic Source Routing protocol): 로드 밸런서 사용 시 서버에서 클라이언트로 되돌아가는 경우 목적지 주소를 스위치의 IP 주소가 아닌 클라이언트의 IP 주소로 전달해서 네트워크 스위치를 거치지 않고 바로 클라이언트를 찾아가는 개념이다.
  • Tunneling: 인터넷상에서 눈에 보이지 않는 통로를 만들어 통신할 수 있게 하는 개념으로, 데이터를 캡슐화해서 연결된 상호 간에만 캡슐화된 패킷을 구별해 캡슐화를 해제할 수 있다.

로드 밸런서 동작 방식

이제 일반적인 로드 밸런서의 동작 방식을 설명하고 HAProxy를 설명하겠다.

로드 밸런서의 동작을 간단하게 설명하면, 네트워크에서 IP 주소와 MAC 주소를 이용해 목적지(destination) IP 주소를 찾아가고 출발지로 되돌아오는 구조이다. 이 글에서는 4가지의 로드 밸런서 동작 방식을 설명하겠다. 일반적인 로드 밸런서의 동작을 참조하기 위한 것이므로 정확하게 이해하지 못해도 상관없다.

Bridge/Transparent Mode

사용자가 서비스를 요청하면 L4로 전달된 목적지 IP 주소를 real server IP 주소로 변조하고 MAC 주소를 변조해서 목적지를 찾아가는 방식이다.

  1. 요청 전달 시 변조 
    - 사용자 > L4 > NAT(IP/MAC 주소 변조) > real server - 사용자가 L4를 호출하면 중간에 NAT가 목적지 IP 주소를 real server IP 주소로 변조하고 MAC 주소도 변조한다.
  2. 응답 전달 시 변조 
    - real server > NAT > L4 > 사용자 - real server에서 L4를 거치면서 출발지(source) IP 주소를 L4 가상 IP 주소로 변조한다. 동일 네트워크 대역이므로 MAC 주소는 변조하지 않는다.

Router Mode

Bridge/Transparent Mode와 유사하지만 출발지(source) MAC 주소도 변조된다.

One Arm Mode

사용자가 real server에 접근할 때 목적지 IP는 L4 스위치 IP를 바라본다. L4에 도달하면 L4가 클라이언트에게 받은 목적지 IP 주소를 L4 IP 주소에서 real server IP와 real server MAC 주소로 변조한다. 되돌아가는 IP는 L4의 IP pool의 IP 주소로 변조한다.

DSR (Direct Server Return) Mode

사용자가 real server에 접근할 때 출발지와 목적지의 IP 주소를 변조하지 않고, L4에서 관리하는 real server의 MAC 주소 테이블을 확인해서 MAC 주소만 변조한다.

HAProxy 동작 방식

HAProxy는 기본적으로 reverse proxy 형태로 동작한다. 우리가 브라우저에서 사용하는 proxy는 클라이언트 앞에서 처리하는 기능으로, forward proxy라 한다. reverse proxy의 역할을 간단히 설명하면, 실제 서버 요청에 대해서 서버 앞 단에 존재하면서, 서버로 들어오는 요청을 대신 받아서 서버에 전달하고 요청한 곳에 그 결과를 다시 전달하는 것이다.

HAProxy의 동작 방식을 알아보고 HAProxy를 이용해서 어떤 구조로 확장할 수 있는지 알아보겠다.

HAProxy의 동작 흐름은 다음과 같다.

  1. 최초 접근 시 서버에 요청 전달
  2. 응답 시 쿠키(cookie)에 서버 정보 추가 후 반환
  3. 재요청 시 proxy에서 쿠키 정보 확인 > 최초 요청 서버로 전달
  4. 다시 접근 시 쿠키 추가 없이 전달 > 클라이언트에 쿠키 정보가 계속 존재함(쿠키 재사용)

haproxy1

그림 1 HAProxy 동작 방식

HAProxy HA(High availability) 구성

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초 정도의 순단 현상은 발생할 수 있다.

haproxy2

그림 2 HAProxy 무정지 구성

HA로 설정된 HAProxy의 동작 흐름이 단일 HAProxy와 다른 점은 최초 접근 시 쿠키에 바로 서버 정보를 입력하지 않고 서버에서 jsessionid가 전달될 때 서버 정보를 합쳐서 전달한다는 것이다.

  1. 쿠키에 정보 추가 없고 X-Forwarded-For에 정보 추가
  2. 쿠키에 추가 없음
  3. Jsessionid 추가
  4. 서버 정보 + jsessionid를 쿠키에 추가
  5. 쿠키에서 서버 판별 후 jsessionid만 전달

haproxy3

그림 3 HA 구성 시 동작 방식

L4 + HAProxy HA 구성 및 Global 환경에서 구성

HAProxy와 기존 하드웨어 스위치를 이용해서 더 확장된 형태의 고가용성 구조를 설계할 수가 있다. 다음과 같은 형태의 구성도 가능하다.

하드웨어 L4 + HAProxy

클라이언트에서 연결되는 부분은 가상 IP 주소 + L4의 구성으로 하드웨어 이중화를 구축하고, L4에서 서버 앞 단에 HAProxy를 구축해서 HAProxy를 더 확장할 수 있는 구조로 설계할 수 있다.

haproxy4

그림 4 L4 + HAProxy 구성

GSLB(Global Service Load Balancing) + HAProxy

global 서비스가 증가되면서 IDC 간 이중화 및 global 환경에서의 무정지 서비스를 위한 DR(Disaster Recovery, 재해 복구) 시스템 구축이 필수 요구사항이 되었다. GSLB + HAProxy를 이용하면 global한 무정지 서비스 구축이 가능하다.

GSLB 구축에 L4 스위치를 사용할 수도 있지만 GSLB 구성용 L4는 고가의 장비이다. 따라서 L4를 이용한 GSLB 대신 DNS(BIND)를 이용한 구축 형태는 다음과 같다.

  1. 클라이언트에서 DNS로 도메인 조회
  2. 근거리 IDC 정보 전달

haproxy5

그림 5 Global 환경에서 GSLB+HAProxy 구성

이상 로드 밸런서의 동작 원리와 HAProxy를 이용한 다양한 구축 방법에 대해서 알아보았다. 이제 실제 HAProxy를 설치하기 위한 옵션 및 설치 방법에 대해서 알아보겠다.

HAProxy Ncloud 적용 사례

사내 개발자용 Ncloud 시스템은 DNS에서 RR(Round Robin) 기능을 통해 이중화된 서비스로 운영하고 있었다. 그런데 DNS의 경우 팀에서 관리하는 시스템도 아니고 서버 증설 또는 제거를 위해서 매번 관리 시스템을 통해서 작업하는 것이 번거로웠다. 또한 HAProxy의 실제 적용을 테스트하기 위해서 우리가 관리하는 시스템에 적용했는데, 이 적용 및 운영 사례를 살펴보겠다.

사내 Ncloud 시스템의 DNS RR을 HAProxy로 교체

사내 Ncloud 시스템의 DNS RR을 HAProxy로 교체하여 <그림 6>과 같이 앞에서 설명한 HA 구성과 동일한 형태로 구성했다. 그 결과 기존 DNS로 구성할 때보다 서버 증설 및 삭제에 있어 유연성이 증가했으며 HA 구성으로 서비스 안정성도 높아졌다.

그런데 서버 반영 후 애플리케이션 서버에서 클라이언트 IP 주소를 찾아서 처리하는 로직에 문제가 발생했다. 확인 결과 사용자의 요청이 HAProxy를 거치면서 클라이언트 IP 주소 정보가 HAProxy의 정보로 변조되어 보이는 상황이었다.

이 문제가 발생하지 않도록 하기 위해서 HAProxy에서 제공하는 X-Forwarded-For 옵션을 적용하고 Apache 서에는 mod_rpaf 모듈을 설치해서 애플리케이션 서버가 HTTP 헤더에서 클라이언트 IP 주소를 조회하면 실제 클라이언트 IP 주소가 반환되도록 보완했다.

haproxy6

그림 6 HAProxy 적용 구조

실제 적용 후 서버 L7 check가 잘 되고 있는지 HAProxy가 제공하는 어드민 페이지에서 확인했고, 클라이언트 IP 주소 문제 외에 별다른 이슈는 발생하지 않았다.

haproxy7

그림 7 HAProxy 어드민 페이지

HAProxy 성능

Ncloud는 동시 접속자가 많은 시스템이 아니라 성능에 대해 크게 문제될 부분이 없었지만 HAProxy가 설치되는 서버의 사양에 따라 어느 정도 성능이 제공되는지 확인하기 위해 성능을 측정했다. 여기에서는 nGrinder(http://www.nhnopensource.org/ngrinder/) 테스트 결과와 해외 사례를 공유한다.

1. 해외 운영 사례

  • 서버 사양(저사양): Dell PowerEdge 2850, Intel PCI3 4x Gigabit Fiber card (CPU 1.6GHz dual core x 1)
  • 제공 서비스: 영화 다운로드 서비스
  • 결과: 일별 2.47TB 전송 + 81일 동안 운영

2. nGrinder 테스트

  • 환경: HAProxy (1core), apache 서버 2대
  • 결과: 6,603 TPS

haproxy8

그림 8 nGrinder 테스트 결과

3. 해외 성능 사례

  • 듀얼 CPU 환경에서 초당 2만 세션까지 연결 가능 -> CPU 성능이 높아지면 연결 가능 세션 수 증가
  • 초당 1만 건 세션 연결 시 응답에 100밀리초(ms) 소요 -> 최대 연결 개수는 하드웨어의 RAM과 file descriptor에 의해 결정됨 -> 세션당 16KB 사용 시 6만 세션당 1G RAM 필요

haproxy9

그림 9 해외 성능 테스트 사례(이미지 출처: http://haproxy.1wt.eu/#perf)

HAProxy 설치 및 옵션

HAProxy의 중요 옵션과 단점에 대해서 간단하게 알아보겠다. 자세한 설치 방법 및 서비스에 사용되는 설정은 마지막에 설명해 놓았으니 실제 설치가 필요한 경우에 참고하기 바란다.

HAProxy 운영 시 필요한 옵션

HAProxy의 경우 튜닝 옵션을 비롯하여 매우 많은 옵션을 지원하므로 여기에서는 실제 구축 시 필요한 옵션만 간략하게 알아보겠다.

옵션을 변경하려면 haproxy.cfg 파일을 수정한다. 실제 수정 방법은 설치 방법에서 설명한다. 더 자세한 설명이 필요하면 다음 웹 페이지에서 확인하기 바란다.

HAProxy 옵션

다음은 전역 옵션(global) 섹션과 기본 옵션(defaults) 섹션, 프록시 옵션 섹션(listen)의 주요 옵션에 관한 설명이다.

  • global # 전역 옵션 섹션
    • daemon: 백그라운드 모드(background mode)로 실행
    • log: syslog 설정
    • log-send-hostname: hostname 설정
    • uid: 프로세스의 userid를 number로 변경
    • user: 프로세스의 userid를 name으로 변경
    • node: 두 개 이상의 프로세스나 서버가 같은 IP 주소를 공유할 때 name 설정(HA 설정)
    • maxconn: 프로세스당 최대 연결 개수
  • Defaults # 기본 옵션 섹션
    • log: syslog 설정
    • maxconn: 프로세스당 최대 연결 개수
  • listen webfarm 10.101.22.76:80 : haproxy name ip:port
    • mode http: 연결 프로토콜
    • option httpchk: health check
    • option log-health-checks: health 로그 남김 여부
    • option forwardfor: 클라이언트 정보 전달
    • option httpclose: keep-alive 문제 발생 시 off 옵션
    • cookie SERVERID rewrite: 쿠키로 서버 구별 시 사용 여부
    • cookie JSESSIONID prefix: HA 구성 시 prefix 이후에 서버 정보 주입 여부
    • balance roundrobin: 순환 분배 방식
    • stats enable: 서버 상태 보기 가능 여부
    • stats uri /admin: 서버 상태 보기 uri
    • server xvadm01.ncli 10.101.22.18:80 cookie admin_portal_1 check inter 1000 rise 2 fall 5: real server 정보(server [host명] [ip]:[port] cookie [서버쿠키명] check inter [주기(m/s)] rise [서버구동여부점검횟수], fall [서비스중단여부점검횟수])

balance 옵션

로드 밸런싱의 경우 round robin 방식을 일반적으로 사용하지만 다른 여러 방식이 있다. 옵션에 적용할 수 있는 로드 밸런싱 알고리즘은 다음과 같다.

  • roundrobin: 순차적으로 분배(최대 연결 가능 서버 4128개)
  • static-rr: 서버에 부여된 가중치에 따라서 분배
  • leastconn: 접속 수가 가장 적은 서버로 분배
  • source: 운영 중인 서버의 가중치를 나눠서 접속자 IP를 해싱(hashing)해서 분배
  • uri: 접속하는 URI를 해싱해서 운영 중인 서버의 가중치를 나눠서 분배(URI의 길이 또는 depth로 해싱)
  • url_param: HTTP GET 요청에 대해서 특정 패턴이 있는지 여부 확인 후 조건에 맞는 서버로 분배(조건 없는 경우 round robin으로 처리)
  • hdr: HTTP 헤더 에서 hdr(<name>)으로 지정된 조건이 있는 경우에 대해서만 분배(조건 없는 경우 round robin으로 처리)
  • rdp-cookie: TCP 요청에 대한 RDP 쿠키에 따른 분배

HAProxy 1.4.22 단점 - SSL 미지원

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 설치 및 config 수정

HAProxy 설치를 위한 소스 파일 다운로드와 설치 절차는 다음과 같다.

예제 1 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 파일은 다음 설정 예제를 참고해서 수정하면 된다.

예제 2 HAProxy 환경 설정 예제

#서버 정보
#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의 개념과 서비스 구축 방안 정도는 미리미리 습득하기를 권장한다.

참고 자료


반응형
LIST
반응형

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  

참고> https://wiki.eclipse.org/Eclipse.ini

반응형
LIST

+ Recent posts