블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


 
 

대용량 시스템 아키텍쳐 설계에 대한 강의를 진행합니다.


조대협입니다.

잠깐의 휴식 시간에 짬을 내서, 패스트 캠퍼스에서 대용량 시스템 아키텍쳐 설계에 대한 강의를 합니다.

4/9~4/10일 양일간입니다.



패스트 캠퍼스를 통해서 아키텍쳐 설계 강의를 하게되었습니다
이번에는 실습을 통해 저와 같이 설계를 하는 과정도 같이 들어갑니다.

강의를 개설하게 된 이유는 종종 아키텍쳐에 대한 컨설팅이나 도움을 요청하시는 분들이 있어서 시스템들을 살펴보면, 기술적인 부분에 체계가 안잡혀 있는 것도 문제지만 아키텍쳐를 정의하고 설계하는 흐름에 대해서 이해가 부족한 경우를 많이 봐왔습니다. 짧은 시간이지만 많은 도움이 되려고 합니다.


홍보 때문에 인터뷰도 했어요. http://www.fastcampus.co.kr/dev_workshop_architect_blog_instructor_1/


모처럼 많은 신청 부탁합니다.


신청은

http://www.fastcampus.co.kr/dev_workshop_architect/



아키텍쳐 문서화는 어떤 도구를 사용하는게 좋을까?

조대협(http://bcho.tistory.com)


제 현재 본업은 아키텍트 입니다. 주로 시스템을 설계하는 역할을 하는데, 이 아키텍쳐 문서를 주로 PPT를 사용합니다. 문서는 워드로 만드는게 좋을 수 도 있고, EA나 StarUML등등 많은 툴이 있는데,  굳이 PPT를 사용하는 이유를 적어놓고자 합니다.

사실 예전에는 MS WORD로 설계문서를 만들었습니다. 만들어 놓으면 멋도 있고, 자세한 내용 표현이 가능해서 탐독하면서 이해하기도 좋습니다. 

그런데, 고객사의 요구 때문에, PPT로 바꾼후, 거의 습관처럼 PPT로 아키텍쳐 문서를 만들다 보니, 몇가지 장점이 있습니다.





1. PPT 는 표현에 제약이 없다.

아키텍쳐 디자인은 특성상 많은 다이어그램과 노트등을 달아야 하는데, WORD로 작성할 경우, 다른 툴에서 다이어그램을 그린 후 가져다 붙여야 합니다. 문서 만드는데 여간 노력이 많이 들어가고, 또한 UML 도구 같은 것을 사용하면 그 도구에서만 제공하는 다이어그래밍이 가능하지 다양하고 쉬운 다이어그래밍이 어렵습니다. 그냥 그리고 싶은 데로 표현하고 싶은데로 자유롭게 하면 되니 일단 문서 작성이 쉽습니다.


2. PPT는 발표용이지 문서용이 아니다

SI때나, 예전 전통적인 개발 방법론에서는 아키텍쳐 설계서 산출물이 나오면 이걸 받아서 개발자들이 잘 읽고 개발을 시작하는 프로세스였다면 근래의 개발 프로세스는 아키텍트가 설계를 하고,이 내용을 개발자들에게 설명을 합니다.

그냥 문서 하나 휙던지고 마는게 아니라는 겁니다. 예전 포스팅에서도 몇번 언급했지만, 문서화는 커뮤니케이션을 원할하게 하기 위한 하나의 도구이지, 산출물이 목적이 아닙니다.

그런점에서 PPT는 발표를 위한 도구인점에서 메리트가 많습니다. 보고용 자료가 아니라 발표/토론용 자료를 만드는 게 아키텍쳐 문서화의 목적이면 거기에 맞는 툴을 쓰는게 맞기 때문입니다.



대용량 시스템을 위한 데이타베이스 아키텍쳐
Sharding & Query Off Loading

RDBMS는 크게 request를 바로 처리하는 트렌젝션 처리용의 OLTP(On-Line Transaction Processing)성과, 데이타를 모아서 분석하고 리포팅하는 OLAP(On-Line Analytical Processing) 두가지로 분리된다. 여기서 설명하는 RDBMS OLTP성의 데이타 베이스 이다.

RDBMS 2차원 테이블 구조의 데이타를 KEY 값을 중심으로 여러개의 컬럼으로 저장되며, 저장된 각각의 로우()은 다른 테이블의 로우와 관계를 가질 수 있다.

RDBMS를 이용한 설계를 하는데, 고려할만한 아키텍쳐는 성능 향상을 위한 Query Off Loading, Sharding이라는 기법이 있다.


Query Off Loading

 Query Off Loading DB의 성능 향상을 위한 기법이다. (정확하게 이야기 하면, 처리량을 증가 시키기 위한 설계 기법이다.) DB 트렌젝션의 70~90%는 대부분 READ 성이 많다. 나머지 10~30% Create/Delete/Update와 같은 트렌젝션인데, Update 성 트렌젝션과 Read 트렌젝션을 분리하는 기법이다.



먼저 Master DB에는 쓰기(Update)만을 허용하고, Master DB의 내용을 중간의 Staging DB라는 곳으로 복사한다. Staging DB는 복제된 내용은 N개의 Slave DB로 복제한다.

애플리케이션은 Master DB에만 쓰기를 하고, 읽기는 Slave DB에서만 수행한다. 이를 위해서 Application DB에 대한 쓰기 로직과 읽기 로직을 분리해서 구현해야 하며, 이 분리된 로직은 쓰기 DB로 접근하기 위한 DB Connection과 읽기 DB로 접근하기 위한 DB Connection을 이용해서 접근한다. 일반적으로 application server에서는 이러한 Connection Connection Pool 을 이용해서 관리 하는데, 읽기 DB의 경우에는 N개의 Slave DB로 부터 읽기 때문에, Application이 이 N개의 Slave DB에 대한 요청을 Load Balacing을 해야 한다. 또한 특정 Slave DB 장애시 다른 Slave DB 인스턴스에 접근을 할 수 있도록 HA (High Availability) 기능을 제공해야 하는데 Connection Pool 자체에 Load Balancing HA 기능을 가지고 있는 Connection Pool을 이용하거나 또는 JDBC Driver와 같이 DBMS Driver 자체에 Load Balancing HA 기능을 사용한다.

Master DB Slave DB는 각각 쓰기와 읽기를 위해서 접근된다고 하지만 그렇다면 중간에 Staging DB의 역할은 무엇일까? Staging DB Slave DB로 복제하기 위한 중간 경유지 역할을 한다. 다수의 Slave DB로 복제를 해야 하기 때문에, 이에 대한 부하가 크다. 만약 Master DB에서 Slave DB로 바로 복제를 하게 되면, Master DB가 쓰기 트렌젝션 이외에 복제에 대한 부분을 처리해야 하기 때문에 성능 저하를 유발할 수 있다. 이를 방지 하기 위해서 중간에 Staging DB를 넣는 것이다.

그렇다면 Master à Staging à Slave DB로의 복제는 어떤 기술을 이용할까?

CDC (Change Data Capture)라는 기술을 이용한다. DBMS들은 공통적으로 Create/Update/Delete와 같은 쓰기 관련 작업을 수행할때, 데이타를 실제로 저장하기 전에 먼저 해당 작업에 대한 request BackLog라는 곳에 저장한다. (BackLog는 일반적으로 Local 파일이다.) 이는 실제로 데이타를 쓰기전에 장애가 났을때, restart하면서 이 BackLog를 읽어서 복구를 위한 용도로 사용이 된다. CDC는 이 Back Log를 이용해서 데이타를 복제하는데, Source DB로 부터 이 Back Log를 읽어서, 복제를 하고자하는 Target DB replay 하는 형식이다.

Source DB에서, insert A,B,C를 하면 이는 모두 Back Log에 기록되고, 이를 읽어서 Target DB에서 다시 replay – insert A,B,C를 순차적으로 수행하는 것이다.

대표적인 CDC 제품으로는 Oracle Golden Gate, Quest Share Flex가 있고, 오픈소스 제품으로는 Galera[1]라는 제품이 있다.


Sharding

Sharding은 데이타베이스의 용량 한계를 극복하기 위한 기술이다. 클러스터링 기술을 사용하더라도 데이타 베이스는 물리적인 용량 한계를 갖는 경우가 많다. 수년 전에만 해도, 하나의 서비스에 수천만명이 사용하는 서비스는 없었다. 인터넷의 발전등에 따라서 사용자가 급격하게 늘어나고 저장해야 하는 데이타의 양도 급격하게 늘어났다. 데이타 베이스 시스템은 이러한 용량 증가를 따라가지 못했다. 그래서 Sharding이라는 아키텍쳐가 유행하기 시작했는데, Sharding은 쉽게 말해서 데이타를 여러개의 데이타 베이스에 나눠 담는 방법이다.

하나의 데이타 베이스가 10억개의 레코드만 저장할 수 있다면, 100억개의 데이타를 저장하려면 10개의 데이타 베이스를 사용하여 분산 저장하는 방법이다. 이 각 10개의 데이타 베이스를 Shard라고 한다.

Sharding은 데이타를 분산 하는 방식에 따라서 Vertical(수직적) Sharding Horizontal(수평적) Sharding으로 나뉘어 진다.

Vertical Sharding은 연속된 데이타에 대해서 범위별로 데이타를 나누는 방법이다. 아래 예는 연령대 별로, 데이타를 나누는 예이다.



Figure 1 Vertical Sharding


다음으로는 Horizontal Sharding이 있는데, 이는 연속된 키가 아니라 “Category”와 같은 종류에 따라서 데이타를 수평적으로 분리하는 방법이다.



Figure 2 Horizontal Sharding


데이타를 분산 저장할때 위와 같이 meaningful한 데이타를 사용할 수 있는데, 이 경우에는 데이타의 몰림 현상이라는 것이 발생할 수 있다. 위의 Vertical Sharding을 예를 들어보면, 해당 서비스를 사용하는 연령층이 20대와 30대에 편중되어 있다면, 20,30 Shard에는 데이타가 몰리게 되고, 부하도 더 많이 받게 될 것이다. 그래서 이렇게 meaningful한 데이타를 KEY로 사용할 경우에는 데이타 몰림현상을 고려하여 각 Shard 서버의 성능을 비 대칭적으로 설계할 수 있다. 20,30대의 Shard에는 더 좋은 CPU와 메모리를 갖는 서버를 배치하는 방법이 대안이 된다.

만약에 데이타 편중 현상에 대한 예측이 어려운 경우에는, meaningful 하지 않은 KEY를 사용해서 Sharding을 할 수 있다. 10개의 Shard를 갖는 데이타 베이스에서, 사용자 레코드를 등록할때, KEY Sequence를 이용해서 순차적으로 부여한다. 첫번째 사용자는 1, 두번째는 2, 다음은 3,4,5,6.. 등으로.. 그리고 이 ID 10으로 나눈 나머지 값을 가지고 Shard를 결정하면, 데이타를 모든 Shard에 걸쳐서 골고루 분산 시켜 배치 할 수 있다. (Hash 방식)

Sharding을 구현하는 방법은 DBMS 단에서 Sharding을 지원 하는 방법과, OR Mapper와 같은 DB 접근용 프레임웍에서 Sharding을 제공하는 방법 그리고, Application Code 자체에서 지원하는 방법 세가지가 있다.

DBMS 단에서 제공하는 방법으로는 Microsoft SQL Server Azure federation model[2]이나 RDBMS는 아니지만 NoSQL MogoDB의 경우 1.6부터 Sharding DB단에서 지원한다.

프레임웍단에서는 자바의 Hibernate의 경우 Hibernate Shard[3]라는 기능을 통해서 Sharding을 지원한다프로그래밍 언어인 Grail의 경우에도 자체 프레임웍에서 “Grails Sharding Plug in”을 통한 Sharding 을 지원한다.

직접 Application에서 구현할 경우 Key에 따라서 DB Instance를 선택적으로 고를 수 있는 구조를 가져야 하며, 특히 다른 Shard간의 데이타 Join등은 불가능하기 때문에, 구현상에 이에 대한 고려가 필요하다.

Sharding 이라는 것이 데이타를 분산 저장함으로써 시스템의 전체 용량을 늘릴 수 는 있지만 Application의 복잡도가 올라가고, 데이타 편중 방지등 여러가지 요소를 고려한후에 설계, 반영해야 한다..

대용량 시스템 레퍼런스 디자인


SSAG - Face book Server Side Architecture Group

http://www.facebook.com/groups/serverside

조대협 (bwcho75 골뱅이 지메일닷컴)


I. 배경

웹로직,JBOSS 가 유행이던, J2EE 시대만 하더라도, 웹서버+WAS+RDBMS면 대부분의 업무 시스템을 구현할 수 있었다. 오픈소스가 유행하면서 부터는 프레임웍 수는 다소 많기는 했지만 Spring,IBatis or Hibernate,Struts 정도면 대부분 구현이 가능했다.

그러나 근래 수년 동안 벤더 중심에서 오픈소스 중심에서 기술의 중심이 구글,페이스북이 주도하는 B2C 기반의 서비스의 유행과 더불어 대규모 분산 시스템을 위한 대용량 아키텍쳐가 유행하게 되었는데, 이 아키텍쳐의 특징이 오픈소스 중심에 상당히 다양한 수의 솔루션이 사용 되었다.


II. 내용

이 글에서는 일반적인 대용량 시스템을 구축하기 위한 레퍼런스 아키텍쳐를 소개한다.

일반적인 웹이나 서버 플랫폼을 개발할 수 있는 레퍼런스 아키텍쳐이며, 자주 사용되는 오픈 소스 솔루션을 조합하였다.


또한 이 아키텍쳐는 데이타 분석등의 용도가(OLAP)이 아니라 온라인 트렌젝션 처리 (OLTP)성 업무를 위해서 디자인된 아키텍쳐이다.


III. 레퍼런스 아키텍쳐



1. Reverse Proxy Layer - Routing & Load Balacing

첫번째 계층은 Reverse Proxy 계층으로, 첫번째에 들어오는 HTTP Request에 대한 관문 역할을 한다.

이 Reverse Proxy에서는 초기 Request에 대한 Logging, 필요하다면, Authentication & Authorization 처리를 수행하고, 뒷쪽에 Request를 보낼때, 뒷단의 Node로 Routing 또는 Load Balancing을 한다.

뒷단에 클러스터가 업무에 따라서 여러 클러스터로 나뉠 수 있기 때문에 이에 대한 라우팅을 수행하거나, 같은 업무에 대해서는 단일 클러스터에 대해서 여러 서버에 대한 로드 밸런싱을 수행한다.


뒤에 살아 있는 서버에 대한 리스트나 클러스터에 대한 정보는 ZooKeeper에 저장하며, Scale In/Out시 또는 장애시에는 이 정보를 ZooKeeper에 업데이트 하여, ZooKeeper에 저장된 클러스터 정보를 기준으로 라우팅을 한다.


사용할만한 솔루션으로는 Apache,NginX,HA Proxy등이 있다.

성능 상으로는 NginX가 가능 높다. 그러나 NginX는 대용량 HTTP Request에 대해서 아직 제대로 지원하지 않는 부분이 있다. 파일 업다운 로드의 경우 성능이 급격하게 떨어지는 부분이 있다. 위에서 설명한 ZooKeeper연동이나 Routing 기능들은 module을 구현하여 plug in해야 한다.


2. [Optional] Enterprise Service Bus (ESB) Layer - Cross Cutting Concern, Mash up,Routing,MEP (Message Exchange Pattern Converting),Integration, SLA management,Protocol Converting

이 계층은 필요에 따라 넣거나 뺄 수 있는 Optional 한 부분이다. Enterprise Service Bus는 시스템으로 들어오는 메세지에 대해서 좀 더 확장된(진보된) 기능을 제공하는 계층으로, SOA (Service Oriented Architecture)에서 따온 계층이다. 키 포인트는 성능이다. BY PASS의 경우 10~50ms 이내에 통과(IN/OUT 포함), 몬가 작업을 할 경우에는 100ms 이하에 통과되어야 한다.

ESB 계층에서 다루어야 하는 일들은 다음과 같다.

  • Cross Cutting Concern 처리 : Cross Cutting Concern는 횡종단 처리라고 하는데, 모든 메세지에 대해서 뒷단의 비지니스 로직이 공통적으로 처리해야 하는 부분을 이야기 한다. 대표적인 예로, Logging, Authentication & Authorization 등이 있다. 
  • Routing 처리 : Reverse Proxy 보다 향상된 Routing 기능을 제공할 수 있다. 보통 Reverse Proxy에서는 HTTP Header나 URI등의 최소한의 정보를 바탕으로 라우팅을 하는데 반해서, ESB 계층에서는 Message 본문의 Header나 Message 자체의 내용을 가지고 라우팅을 할 수 있다. 예를 들어 VIP 회원에 대해서는 Dedicated 된 서버로 라우팅을 하는지 등의 처리가 가능하다.
  • Protocol Converting : ESB 계층에서는 또한 Protocol 변환을 할 수 있다. 예를 들어 뒷단의 비지니스 컴포넌트가 XML/REST를 지원하는데, 전체 표준을 JSON/REST를 사용한다면, ESB 계층에 프로토콜 변환 기능을 넣어서 JSON to XML 변환을 수행할 수 도 있고, 또 다른 예로는 통신사의 경우 종종 HTTP 메세지를 손을 대는 경우가 있다. Header에 통신사 고유의 헤더를 삽입하는 등의 일이 있는데, 이런 경우 범용으로 디자인 된 시스템은 
  • Mash Up : Mash Up은 뒤의 비지니스 로직 여러개를 합쳐서 하나의 비지니스 로직을 만들어 내는 것을 이야기 한다. 쉬운 예로 기존 서비스가 "구매" 라는 Function이 있었는데, "포인트 적립" 이라는 기능이 새롭게 추가 되었을때, 비지니스 로직 자체를 변경하는 것이 아니라 기존 "구매" 라는 기능에 +"포인트 적립" 이라는 기능을 Mash up으로 더해서 기능을 변경하는 것이다. 이렇게 하면 비지니스 로직 변화 없이 새로운 기능을 구현할 수 가 있다.
  • MEP Converting : MEP란 Message Exchange Pattern의 약자로 메세지의 호출 방식을 이야기 한다. 쉽게 말하면 Sync,Async 와 같은 호출 방식을 정의하는데, 비지니스 로직이 Long Running 하는 Sync 형식의 서비스 였을 때, ESB를 이용하여, Sync 호출을 Async 형태로 변경할 수 있다. (ESB에서 응답을 먼저 보내고, ESB에서 비지니스 컴포넌트로 ASync로 보내는 형태)
  • Integration : 타 시스템과의 통합을 이야기 한다. 일종의 EAI (Enterprise Application Integration) 기능인데, 앞에서 언급된 Mash up + Protocol Conversion + MEP Converting을 합쳐놓은 기능과도 비슷하다. 크게 대내 시스템간의 통합과 대외 시스템과의 통합등으로 나뉘어지며, 대내 시스템과의 통합은 Legacy (SAP와 같은 ERP, Siebel과 같은 CRM과 같은 패키지 형태의 Application)과 통합 하는 경우가 많으며 이런경우 전용 아답터를 사용하는 경우가 많다. 대외 시스템 통합의 경우 예를 들어 전자 결재나 PUSH 서비스 등과  통합하는 경우이며 이 경우 필요에 따라 프로토콜 변환이나 Authentication & Authorization 처리를 하는 경우가 많으며 특히 과금이 연동되는 경우에는 향후 Audit을 위해서 로그를 기록하고 향후 비교하는 경우가 많다.
  • SLA management : SLA (Service Level Agreement)로, Service의 품질을 보장 하는 기능이다. 정확하게는 SLA를 보장한다기 보다는 SLA에 문제가 생겼을때 이를 빠르게 감지하여 후처리를 할 수 있다. ESB는 시스템으로 들어오는 모든 메세지에 대한 관문 역할을 하기 때문에 응답 시간이나 TPS에 대한 변화가 생겼을때 이를 검출할 수 있는 단일 지점으로, 장애 상황에 대한 검출이 있었을때 이에 대한 후처리를 하도록 관리자에게 통보할 수도 있고, 또는 ZooKeeper를 통해서 성능이 떨어지는 노드들에 대한 Scale Out등을 지시할 수 있다.

ESB는 설계시에 적용을 해놓으면 후에 시스템의 변화가 있을 경우에 도움이 많이 되는 계층이다. 시스템 초기 운영시에는 오히려 큰 이득을 보지 못한다. 왜냐하면 처음에는 모든 비지니스 컴포넌트가 초기 요구 사항에 맞춰서 구현이 되었고, 위의 기능들은 시스템을 운영하면서 요구사항이나 환경적인 변화에 따라 발생하는 요구 사항이기 때문이다. 

앞에서도 언급했으나, ESB는 메세지가 지나가는 중간에 위치 하기 때문에 전체 시스템의 성능에 영향을 주게 되기 때문에 성능에 각별한 신경을 써서 디자인을 해야 하며, 특히 메세지의 파싱하는 과정과 메세지 자체 설계에 신경을 많이 써야 한다. 예를 들어 일반적인 경우 메세지의 BODY 부분을 파싱할 일이 없는데 모든 요청에 따라서 BODY 부분을 파싱하게 한다면 이에 대한 오버로드가 상당히 크게된다.


사용 가능한 솔루션으로는 Apache Mule이나 Oracle사의 Oracle Service Bus등이 있고, 재미있는 장비중의 하나는 Oracle Service Bus 제품중에 XML 기반의 메세징을 파싱하는 부분을 Hardware로 구현해놓은 제품이 있다. Oracle Service Bus도 내부적으로 JAXP 기반의 XML Parser를 이용하는데, 이 구현 부분을 ASIC으로 구현해 놓은 제품이 있는데 이 제품의 경우 메세지 처리 속도를 많이 높일 수 있다.


3. WAS Layer - Business Logic

이 계층은 비지니스 로직을 핸들링 하는 계층이다.

Web Application Server (WAS)로 구현이 가능하며, 고속 멀티플렉싱 기반의 고속 처리가 필요한 경우나 대규모 Stateful Connection이 필요한 경우에는 Netty와 같은 네트워크 서버를 사용한다.

이 계층 구현시 중요한점은 Shared Nothing 아키텍쳐를 적용하는 것을 권장한다.

Shared Nothing이랑 WAS 인스턴스끼리 클러스터링등을 통해서 묶지 않고 각각의 WAS를 독립적으로 돌아가게 설계하는 것이다. (대표적으로 Session Clustering을 사용하지 않는것)

이렇게 하는 이유는 특정 인스턴스가 장애가 났을 때 클러스터를 타고 전파되는 현상을 방지하고 또한 횡적인 확장 (Horizontal Scalability )를 보장하기 위해서이다.

참고 자료 

- WAS 기반의 아키텍쳐 http://bcho.tistory.com/373

- J2EE 그리드 아키텍쳐 http://bcho.tistory.com/330


4. Async message Handling

WAS 계층이 Sync 형태의 동기 (Request/Response) 메세지를 처리한다면, 비동기 메세징 처리나 Publish/Subscribe와 같은 1:N 기반의 비동기 메세지 처리를 하는 계층이 필요하다.

예전에는 MQ나 JMS를 많이 사용했으나, 근래에는 좀더 향상된 프로토콜인 AMQP를 기반으로 한 RabbitMQ가 많이 사용된다.


RabbitMQ의 경우에도 수억명의 사용자를 커버하기에는 클러스터의 확장성이 문제가 있기 때문에 이런 경우에는 MySQL등의 DBMS의 테이블을 큐 처럼 사용하고, 메세지를 읽어가는 부분을 Quartz등을 이용해서 주기적으로 읽어가서 처리하는 구조로 만들게 되면 확장성을 보장할 수 는 있으나, 복잡한 비동기 메세징 (에러처리, Pub/Sub)을 구현하기에는 난이도가 높기 때문에, RabbitMQ를 복수의 클러스터로 묶는 Sharding이나 분산큐(Distributed Queue) 개념을 고려할 필요가 있다.


5. Temporary Storage Layer - Temporary space

다음 계층은 Temporary Storage Layer - 작업 공간이다.

이 작업 공간은 4번의 WAS들이 서로 데이타를 공유할 수 있는 "휘발성", 작업 공간이다. 

필수 조건은 높은 성능을 보장해야 하며, 모든 WAS Node가 접근할 수 있어야 한다. 저장 매체가 Memory냐, Disk냐에 따라서 다음과 같이 나눠볼 수 있다.


1) Data Grid (Memory)

데이타 그리드는 쉽게 생각하면 자바의 HashTable 같은 Key/Value Store 기반의 메모리 Store이다. 단.. 이 그리드는 클러스터 구성을 통해서 용량 확장이 가능하고, 별도의 서버 클러스터로 구성되어 여러개의 WAS 노드들이 접근할 수 있다. 일종의 WAS간의 공유 메모리라고 생각하면 된다.

솔루션으로는 Oracle Coherence (예산만 넉넉하다면 이걸 쓰는게 맘편하다), Redis, memecahed, Terracota 등이 있다.

참고 자료 

- Redis 소개 - http://bcho.tistory.com/654

- Coherence를 활용한 아키텍쳐 설계 - http://bcho.tistory.com/327


2) Working Space (DISK)

트렌젝션을 처리하다 보면, 종종 임시적인 작업 공간이 필요할때가 있다. 예를 들어 드롭 박스와 같은 파일 서비스를 이야기 해보자, 드롭박스는 이미지 파일을 하나 올리면, 모바일 디바이스의 화면 해상도에 맞게 5개의 썸네일 이미지를 재 생산한다. 이런 작업을 하기 위해서는 이미지 파일을 저장하기 위해서 임시로 저장해놨다가 썸네일을 추출하는 공간이 필요한데 이를 임시 작업 공간이라고 한다.

데이타 그리드와 마찬가지로, 여러 노드들이 해당 공간을 공유할 수 있어야 한다. 그래서 NFS (Network File System)이 많이 사용되며, Gluster와 같은 소프트웨어 기반의 NFS나 NetApp社의 NFS appliance server (하드웨어) 등이 있다.

참고 자료

- Amazon에서 Gluster 성능 비교 자료 - http://bcho.tistory.com/645


6. Persistence Layer

다음은 영구 저장 공간이다. 영구 저장 공간은 우리가 일반적으로 생각하는 데이타가 저장되는 공간이라고 보면된다.  쉽게 예를 들 수 있는 공간으로는 데이타 베이스와 파일 시스템을 들 수 있다. 이러한 영구 저장소는 대용량 B2C 시스템의 유행과 함께 새로운 DBMS들이 등장하였는데, DBMS 측면에서는 Key Value Store 기반의 NoSQL이나, 대용량 파일을 저장할 수 있는 Object Store등을 그 예로 들 수 있다.


1) Relational Data

개체간의 관계가 있는 경우에 대한 데이타를 관계형 데이타라고 하고, 이를 핸들링 하기 위해서는 관계형 데이타 베이스 RDBMS를 사용한다. 우리가 지금까지 일반적으로 사용해왔던 데이타 베이스가 이 RDBMS이다. RDBMS는 대용량 서비스를 위해서는 태생적인 한계를 가지고 있는데, 예를 들어 MySQL의 경우 하나의 데이타베이스에서 저장할 수 있는 레코드의 수가 10억개 정도가 최적이다. 

이런 문제를 해결하기 위해서는 대용량 시스템에서 몇가지 기법을 추가로 사용하는데 "Sharding" 과 "Query Off Loading"이다.


Sharding이란, 데이타의 저장용량의 한계를 극복하기 위한 방안으로

데이타를 저장할때 데이타를 여러 데이타 베이스에 걸쳐서 나눠 저장하는 방법이다. 예를 들어 "서울","대구","대전"등 지역별로 데이타베이스를 나눠서 저장하거나(이를 횡분할 Sharding) 또는 10대,20대,30대 식으로 데이타를 나눠서 저장하는 방식(이를 수직분할 Sharding)을 사용한다. 이러한 Sharding은 데이타베이스 계층에서 직접적으로 지원하기가 어렵기 때문에, 애플리케이션 레벨에서 구현해야 한다.


다음으로 Query Off Loading이라는 기법으로, 이 기법은 성능의 한계를 높이기 위한 기법이다. 

"Master DB → Staging DB → Slave DB 1,Slave DB 2,....N"

    1. Create/Update/Write/Delete는 Master DB에서 수행하고
    2. Master DB의 데이타를 Staging DB로 고속 복사한후
    3. Staging DB에서 N개의 Slave DB로 데이타를 복사한다.
    4. Read는 Slave DB에서 수행한다.

일반적인 DBMS 트렌젝션은 10~20% 정도가 Update성이고, 나머지 80~90%가 Read성이기 때문에, Read Node를 분산함으로써, 단일 DBMS 클러스터의 임계 처리 성능을 높일 수 있다.


이때 Master/Staging/Slave DB로 데이타를 복제하는 방식이 매우 중요한데, 여기서 일반적으로 사용하는 방식을 CDC (Change Data Capture)라고 한다.

RDBMS는 데이타 베이스 장애에 대한 복구등을 위해서 모든 트렌젝션을 파일 기반의 로그로 남기는 데 이를 Change Log라고 한다. CDC는 이 Change Log를 타겟 DB에 고속으로 복사해서 다시 수행(Replay)하는 형태로 데이타를 복제한다.


MySQL의 경우 Clustering에서 이 CDC 기능을 기본적으로 제공하고 있고, Oracle의 경우 Oracle Golden Gate라는 솔루션을 이용한다. (비싸다..) 중가격의 제품으로는 Quest의 ShareFlex들을 많이 사용한다.


2) Key/Value Data

다음으로 근래에 들어서 "NoSQL"이라는 간판을 달고 가장 유행하는 기술중의 하나가 Key/Value Store이다.

데이타 구조는 간단하게 Key에 대한 데이타(Value)를 가지고 있는 형태이다. RDBMS와 같이 개체간의 관계를 가지지 않는다.

오로지 대용량,고속 데이타 억세스,데이타에 대한 일관성 에만 초점을 맞춘다. (이중에서 보통 2개에만 집중한다. 이를 CAP 이론 - Consistency, Availability, Performance)


이 기술은 태생 자체가 B2C 서비스를 통해서 탄생하였다.

블로그나 트위터, 페이스북 처럼 데이타의 구조 자체가 복잡하지 않으나 용량이 많고 고성능이 필요한 데이타들이다. 태생 자체가 이렇기 때문에 복잡한 관계(Relationship)을 갖는 복잡한 업무 시스템에는 잘 맞지 않는 경우가 많으며, 트렌젝션 처리나 JOIN, SORTING 등이 어렵기 때문에 애플리케이션의 구현 복잡도가 올라간다.


참고 자료

- 사람들은 왜 NoSQL에 열광하는가? - http://bcho.tistory.com/658

- Amazon Dynamo 계열의 NoSQL 장단점 - http://bcho.tistory.com/622

- NoSQL Riak - http://bcho.tistory.com/621

- NoSQL 계보 정리 - http://bcho.tistory.com/610

- Cassandra 소개 - http://bcho.tistory.com/440


3) Object Data

Object Data는 File과 같이 대용량 데이타 파일 저장을 할 수 있는 Storage이다.

10M,1G와 같은 대용량 파일을 저장할 수 있는 저장소로, Amazon의 S3, Openstack SWIFT등이 대표적인 예이며, 하드웨어 어플라이언스 장비로는 애플의 iCloud로 유명해진 EMC의 isilion등이 있다.

Object Data 저장에 있어서 중요하게 생각하는 부분은 대용량의 데이타를 저장할 수 있는 용량에 대한 확장성과 데이타 저장에 대한 안정성이다. 

이러한 Object Data는 Quorum이라는 개념을 적용하여, 원본을 포함하여 N개의 복사본을  유지한다. 일반적으로는 N+3 (3개의 복사본)을 저장하여 데이타에 대한 안정성을 보장한다. 


4) Document Data

Document Data는 Key/Value Store에서 조금 더 발전한 데이타 저장 방식으로

Key 자체는 동일하나 Value에 해당하는 부분이 Document가 저장된다. Document 는 JSON이나 XML 문서와 같이 구조화된 데이타를 저장한다.

RDBMS가 다양한 select, where, group, sorting,index 등 여러가지 데이타에 대한 기능을 제공한다면, Key/Value Store는 이런 기능은 거의 제공하지 않는다. Document Data를 저장하는 제품들은 RDBMS와 Key/Value Store의 중간정도에서 데이타에 대한 핸들링 기능을 제공한다. (부족한 Indexing 기능, 부족한 Group 기능, 부족한 Sorting 기능등)


대표적은 솔루션으로는 MongoDB,CouchDB, Riak등이 있다.


요즘 들어서 자주 사용되는 대표적인 Persistence Store에 대해서 간단하게나마 집고 넘어갔지만, 사실 이 보다 더 많은 형태의 Persistence Store들과 기능들이 있다.


7. Configuration management & Coordinator

대용량, 분산 시스템으로 발전하면서 풀어야되는 문제중의 하나가 "분산되어 있는 노드들에 대한 설정(Configuration)정보를 어떻게 서로 동기화하고 관리할것인가? (이를 Configuration Management라고 한다.) " 인다. 거기에 더해서 클라우드 인프라를 사용하면서 "전체 클러스터내의 서버들의 상태를 모니터링 해서, 서버의 수를 느리고 줄여야 하며 서버들간의 통신을 중재해야 한다. (이를 Coordination 이라고 한다.)"  


여기에 필요한 기능이 작은 량의 데이타(Configuration Data)를 여러 서버가 공유해서 사용할 수 있어야 하며, 이 데이타의 변화는 양방향으로 클러스터 노드내에 전해져야 한다.

즉 Configuration 정보를 각 서버들이 읽어올 수 있어야 하며, 이 Configuration 정보가 바뀌었을 경우 다른 서버들에게 데이타가 변했음을 통지해줄 수 있어야 하며, 중앙 집중화된 Configuration 정보 뿐만 아니라, 서버의 상태가 변했음을 다른 서버들에게 빠르게 알려줄 수 있어야 한다.


이런 역할을 하는 대표적인 솔루션으로는 ZooKeeper 많이 사용된다.


8. Infrastructure

마지막으로 이런 소프트웨어 스택을 구동하기 위한 하드웨어 인프라가 필요한데, 예전에는 일반적인 서버를 Co-Location이나 Hosting 형태로 사용하는 것이 일반적이었으나, 요즘은 가상화 기술을 기반으로 한 클라우드 (Infrastructure as a service)를 사용하는 경우가 많다.

클라우드의 특징은 "Pay-as-you-go" 로 자원을 사용한 만큼에 대해서만 비용을 지불하는 구조이다. CPU를 사용한 만큼, 디스크를 사용한 만큼, 네트워크 대역폭을 사용한 만큼만 비용을 지불한다.


Amazone WebService (AWS), Microsoft Azure, Google App Engine등이 대표적인 예인데, 이러한 클라우드의 장점은 Time To Market (시장 진입 시간)이 매우 짧다는 것이다. 앉아서 신용카드와 PC만 있다면 인터넷에 접속해서 30분내에 서버,디스크,네트워크등을 설정해서 사용할 수 있다.

단 이러한 클라우드 인프라는 Public 한 서비스 형태로 공유되서 서비스 되기 때문에 일반적인 호스팅과는 달리 성능등에 대한 한계를 가지고 있다. 예를 들어 서버와 디스크간의 네트워크 대역폭이 보장되지 않기 때문에 디스크 IO가 많은 애플리케이션 (DBMS와 같은)에 대한 성능을 보장하기가 쉽지 않고, LAN 설정이 자유롭지 않기 때문에 UDP등을 이용해서 클러스터링을 하는 제품의 경우 클러스터링을 사용할 수 없는 경우가 있다.  이런 이유로, 클라우드위에서 구현되는 시스템의 경우에는 해당 클라우드의 기술적인 특징을 제대로 이해하고 구현해야 한다.


또한 클라우드가 "Pay-as-you-go" 형태로 사용한만큼 비용을 지불한다는 것이 어떻게 보면 "싸다"라고 느껴질 수 있지만, 네트워크,IP 등등 모든 자원에 대해서 비용을 지불하기 때문에 실제적으로 계산해보면 싸지 않은 경우도 많고 기술적인 제약 때문에, 초기 시장 진입을 하는 경우에는 클라우드를 사용하는 경우아 많지만 규모가 커진 서비스의 경우에는 다시 자체 데이타 센타를 구축하는 경우가 많다. (예 소셜 게임 서비스인-Zinga, VOD 서비스인-Netflix)


운영 측면에서 인프라에 대한 관리를 클라우드 업체에 대행시킴으로써 얻는 이득도 있지만 불필요한 비용이 낭비되지 않게 클라우드 인프라에 대한 배포 구조를 끊임 없이 최적화 하는 노력도 필요하다.


IV. 결론

지금까지 현재 유행하는 대용량 고성능 시스템에 대한 레퍼런스 아키텍쳐에 대해서 설명하였다. 사실 이 글을 정리한 이유는 글을 쓰는 본인도 기술이 변화함을 느끼고 있었고, 이에 대한 공부와 개념 정리가 필요하다고 느껴서인데, 확실하게 기술 구조는 변했다. 유행하는 기술도 변했다. 대용량 시스템은 이런 구조로 구현하는게 하나의 모범 답안 (정답이 아니라는 이야기)은 될 수 있으나, 대부분의 IT 시스템은 이런 대용량 아키텍쳐 구조 없이도 WAS + RDBMS 구조만으로도 충분히 구현이 가능하다.

그럼에도 불구하고 이러한 레퍼런스 아키텍쳐에 대한 글을 쓴 이유는 레퍼런스 아키텍쳐를 이해하고, 이런 아키텍쳐가 왜 필요한지 어디에 쓰이는지를 이해한 후에 제대로 적용하기를 바라는 마음에서 정리 하였다. 이러한 대용량 기술은 유용한 기술임에는 분명하지만, 닭잡는데 소잡는 칼을 쓸 필요는 없지 않은가?


누락된 부분

※ node.js 를 이용한 Long Running Connection Service : 예-Push 등을 추가 할것.

※ Map & Reduce를 이용한 분산 처리

※ 데이타 분석을 위한 Hadoop 또는 OLAP성의 처리 아키텍쳐


P.S. 요즘 제 포스팅들이 읽이 어려운가요? 내용은 어떤지요? 피드백을 못 받아서 궁금합니다. 요즘 글들이 축약적인 내용이나 추상적인 개념들을 많이 이야기 하는 것 같아서요.