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


Archive»


 
 

대용량 시스템을 위한 데이타베이스 아키텍쳐
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의 복잡도가 올라가고, 데이타 편중 방지등 여러가지 요소를 고려한후에 설계, 반영해야 한다..

MS SQL Replication 아키텍쳐

엔터프라이즈 솔루션/MS-SQL | 2010.04.28 17:44 | Posted by 조대협



MS SQL 데이타 베이스간의 실시간 데이타 복제를 위해서 "Replication"이라는 기능을 제공한다.

보면, Oracle Golden Gate, IBM Info sphere, Quest Shareflex,MySQL geo replication 비슷한 CDC 기능이다.

Replication 방식은 크게 두가지로 나뉘어 지는데, Snapshot replication TransactionalReplication이다.

 

  1. Snapshot Replication

복제 방식은 간단하게 생각하면 Source 데이타 베이스의 내용을 Export해서 Target Import하는 개념으로 생각하면 된다. 데이타 베이스에 대한 복제를 시작하기 전에 초기 데이타를 적재 하거나, 또는 업무가 없을때 데이타를 적재하거나 주기로 변경이 되는 곳에 사용할 있다.

Snapshot Agent 의해서 주기적 또는 스케쥴에 따라서 데이타를 Export하면여 파일로 저장되고 파일은 Distributor 서버로 FTP,윈도우 파일공유,HTTP등을이용하여 전송된다. Distributor 1 이상의 수신 데이타베이스에 데이타를 전송하여 데이타를 반영한다.

 

  1. Transactional Replication

이게 전통적인 CDC 방식이다. Transaction Log Log Reader 캡춰해서 Distributor 통해서 타겟으로 보내는것인데. 재미있는 것중에 하나가 Capture 최소 단위가 하나의 트렌젝션 이하라는 것이다. 최소 단위가 트렌젝션 하나하나를 잡는게 아니라 트렌젝션이 경우 하나의 트렌젝션을 잘라서도 Capture 가능하다.

 

오라클 연동

 

그외에 흥미로운것중 하나가, 송수신 DB 모두 오라클을 지원한다. TransactionalReplication 경우 오라클의 redo 로그를 잡는 것이 아니라 테이블에 트리거를 걸어서 데이타 변경 사항을 Interface table 넣은후, interface 테이블을 읽어서 반영하는 방식이고, 오라클과의 연결은 ADO.NET,OLEDB,ODBC 이용한다

'엔터프라이즈 솔루션 > MS-SQL' 카테고리의 다른 글

MS SQL Replication 아키텍쳐  (0) 2010.04.28
MS SQL 2008 Tutorial  (1) 2010.04.27
물리적으로 분리된 위치에서 데이타 SYNC에 대한 솔루션을 research 하던중에 mysql에 대한 이야기가 많이 나온다. Facebook도 master 와 slave center (미국 서부와 동부)의 데이타를 mysql georeplication 을 이용해서 구현한것으로 보인다.


MySQL georeplication의 원리는 위의 그림과 같다. Master node의 변경 사항을 BinLog라는 형태로 저장하여 복제 대상에 전송한후 replay를 하는 방식이다. record & replay 방식인데, binlog는 오라클의 redo 로그와 유사하다. 데이타베이스의 redo 로그 자체를 레코딩해서 전송하는 방식이기 때문에 데이타 복제만이 가능하고 ETL과 같은 변환은 불가능하며, 변경된 부분만 전송하기 때문에, 성능이 빠르다. 그리고 XA(분산 트렌젝션)처리 등이 필요하지 않다.
사실 이 개념은 DR센터(재해복구를 위한 백업센터)로 데이타를 복제하는 아키텍쳐에 많이 사용되어 왔고, IBM의 CDC나 오라클의 Golden Gate가 매우 유사한 아키텍쳐를 사용한다.
그나저나 MySQL사용해본지가 몇년전인데, 정말 좋아졌다.