Distributed Relational Database(분산 관계형 데이터베이스)
•
분산 관계형 데이터베이스
•
Distributed Database가 중점
참고 시나리오
•
초기에는 단일 테이터베이스 사용
•
간단한 구조의 Article Table 만든다. Client는 단일한 DB에서 데이터를 생성/조회/수정/삭제한다.
•
서비스가 활성화되면 단일한 DB로 처리하기엔 큰 부담이 생기게 된다. 저장해야 할 데이터와 트래픽이 많아졌다면 어떻게 해야할까?
•
가장 간단한 방법으로 Scale-Up을 고려해볼 수 있다. DB 장비의 성능을 업그레이드 한다.
•
만약에 저장해야 할 데이터와 트래픽이 계속 많아진다면 다시 한 번 Scale-Up을 고려해볼 수 있으나 장비를 무한정 Scale-Up 하는 것은 한계가 있다.
•
이제 2대의 DB가 운용되며 Client의 요청은 각 DB로 분산될 수 있다.
•
데이터베이스에 대한 하나의 분산 시스템이 구성된 것이다.
•
그렇다면, 데이터는 각 DB에 어떻게 분산될 수 있을까?
•
샤딩을 이용하여 데이터를 여러 DB에 분산할 수 있다.
◦
샤딩된 각각의 데이터 단위를 샤드라고 부른다.
◦
샤딩(Sharding) : 데이터를 여러 데이터베이스에 분산하여 저장하는 기술
◦
샤드(Shard) : 샤딩된 각각의 데이터 단위
◦
샤딩에는 수직 샤딩(Vertical Sharding)과 수평 샤딩(Horizontal Sharding)이 있다.
•
수직 샤딩(Vertical Sharding) : 데이터를 수직으로 분할하는 방식(컬럼 단위)
◦
article_id 식별자를 이용하여 좌측 샤드 title/content, 우측 샤드 board_id/created_at 을 분산 저장
•
각 샤드가 적은 수의 컬럼을 저장하므로, 성능 및 공간에 대한 이점이 생긴다.
•
하지만, 데이터의 분리로 인해 조인 또는 트랜잭션 관리가 복잡해질 수 있다. 수직으로 분할되므로 수평적 확장에 제한이 있다. 수평으로 분할되므로 수평적 확장에 용이하다.
•
수평 샤딩(Horizontal Sharding) : 데이터를 수평으로 분할하는 방식(행 단위)
◦
좌측 샤드 article_id=1~5000
◦
우측 샤드 article_id=5001~10000으로 분산 저장
•
각 샤드에 데이터가 분산 저장되므로 성능 및 공간에 대한 이점이 생긴다.
•
하지만, 데이터의 분리로 인해 조인 또는 트랜잭션 관리가 복잡해질 수 있다.
수직 샤딩, 수평 사딩
수직 샤딩 | 수평 샤딩 | |
샤딩 | 수직으로 분할(컬럼 단위) | 수평으로 분할(행 단위) |
확장성 | 제한 | 용이 |
장점 | 각 샤드로 데이터 분산되므로, 성능 및 공간에 대한 이점 | 각 샤드로 데이터 분산되므로, 성능 및 공간에 대한 이점 |
단점 | 조인 또는 트랜잭션 관리 등의 어려움 | 조인 또는 트랜잭션 관리 등의 어려움 |
Range-based Sharding(범위 기반 샤딩)
•
데이터를 특정 값(Shard Key)의 특정 범위에 따라 분할하는 기법
◦
좌측 샤드 article_id = 1 ~ 5000
◦
우측 샤드 article_id = 5001 ~ 10000
•
범위 데이터 조회에 유리
◦
article_id=100 부터 30개 조회한다면 좌측 샤드에서 모든 데이터를 찾을 수 있음
•
데이터 쏠림 현상 발생 가능
◦
데이터가 6,000개만 있다면, 우측 샤드에는 1,000개만 저장
Hash-based Sharding(해시 기반 샤딩)
•
데이터를 특정 값(Shard Key)의 해시 함수에 따라 분할하는 기법
◦
hash_function = article_id → article_id % 2 라고 한다면?
◦
좌측 샤드 article_id = 1, 3, 5, …
◦
우측 샤드 article_id = 2, 4, 6, …
•
균등한 분산을 위한 Shard Key와 해시 함수가 필요
•
균등하게 분산되지 않으면, 데이터 쏠림 현상 발생 가능
•
만약, board_id가 Shard Key라고 한다면?
◦
인기 많은 게시판에 데이터가 몰릴 수 있음
•
범위 데이터 조회에 불리할 수 있음
◦
shard_key = article_id 인 상황에 게시판의 게시글 목록을 조회하려면?
▪
article_id 기준으로 데이터가 분산되었기 때문에 모든 샤드에 요청해야 할 수도 있음
◦
시스템 특성에 따라서 적절한 Shard Key와 해시 함수를 선정해야 함
Directory-based Sharding
•
디렉토리를 이용하여 데이터가 저장된 샤드를 관리하는 기법
•
매핑 테이블을 이용하여 각 데이터가 저장된 샤드를 관리
◦
좌측 샤드 article_id = 1, 4
◦
우측 샤드 article_id = 2, 3
•
디렉토리 관리 비용 있으나, 데이터 규모에 따라 유연한 관리 가능
물리적 샤드와 논리적 샤드
— 물리적 샤드 —
•
위 그림에서는 DB가 2대로 물리적으로 분리되었다. 2개의 물리적 샤드(Physical Shard)를 가지는 것이다.
•
물리적 샤드가 2개인 위 상황에서 Hash-based Sharding을 적용한다. 2개의 샤드에 균등한 분산을 위해 아래와 같은 해시 함수를 적용한다.
◦
hash_function = article_id → article_id % 2
•
8개의 데이터는 2개의 샤드에 4개씩 균등하게 분산되었다.
•
늘어난 4개의 샤드에 균등한 분산을 위해 아래와 같은 해시 함수를 적용한다.
◦
hash_function = article_id → article_id % 4
◦
article_id = 3, 7, 4, 8은 데이터 재배치가 필요하다.
•
8개의 데이터 중 4개의 데이터가 새로운 샤드로 균등하게 재배치되었다.
•
Client는 이제 4개의 Shard로 요청해야 하므로, 애플리케이션 코드를 수정하는 등 새로운 Shard의 정보를 알아야 한다.
•
데이터베이스의 확장(변경)으로 인해 Client의 수정도 필요했는데 Client와 데이터베이스는 독립적으로 구성 및 운영될 수 있는 시스템이다.
•
혹시 Client의 수정 없이 DB만 유연하게 확장하는 방법은 없을까? → 논리적 샤드 활용
— 논리적 샤드 —
•
다시 처음으로 돌아가보면 물리적 샤드는 여전히 2개다.
•
이번에는 실제 물리적인 샤드의 개수와 관계없이, 개념적으로 데이터를 분할하는 가상의 샤드가 4개 있다고 가정한다. 물리적 샤드는 2개 뿐이지만, Client는 4개의 샤드가 있다고 가정하여 분리하는 것이다.
•
이러한 가상의 샤드를 논리적 샤드라고 한다.
•
물리적으로 2개의 샤드로 분산되지만, Client는 4개의 샤드로 분산된 것으로 인지한다.
•
Client는 논리적 샤드의 접근 방법으로만 DB에 연결하는 것이다.
•
hash_function = article_id → article_id % 4
•
그렇다면, Client가 요청한 논리적 샤드가 어떤 물리적 샤드에 속해있는지를 알아야 한다. 그래야 직접적으로 데이터에 접근할 수 있기 때문이다. 이러한 라우팅을 위한 라우터는 DB 시스템 내부 또는 DB와 Client를 연결해주는 중간에 독립적으로 만들어질 수 있다.
•
여기서 이러한 Router가 DB 시스템 내부에 포함된다고 가정한다. DB 시스템 내부에 존재하는 논리적 샤드의 실제 물리적 샤드로 라우팅해주는, Shard Router를 만들어본다.
•
Client는 논리적 샤드를 기반으로 Router에 요청하면, DB 시스템 내부의 Router는 물리적 샤드로 라우팅해준다.
•
예를 들어, article_id = 5 데이터를 요청하려면?
◦
Client 입장에서는 4개의 논리적 샤드가 있으므로 5 % 4 = 1번 샤드로 Router에 요청한다.
◦
Router는 1번 논리적 샤드에 대한 요청을 받아서, 좌측 물리적 샤드로 라우팅한다.
•
데이터베이스 확장이 필요한 상황이 와서 물리적 샤드를 4개로 늘린다고 가정해보자. 논리적으로 4개의 샤드로 분산되어 있지만, 물리적 샤드가 늘어남에 따라 데이터를 물리적으로 다시 재배치할 수 있다.
•
4개의 물리적 샤드로 데이터가 재배치되었다.
•
Router가 물리적으로 늘어난 새로운 샤드 정보를 알도록 한다. 이번에 Client는 어떠한 수정도 필요 없었다. 새로운 물리적 샤드를 알 책임이 있는 Router는 DB 시스템 내부에 있었기 때문이다.
•
논리적 샤드 개념을 이용하여, 물리적 샤드를 확장하더라도 Client의 어떠한 변경도 없이 DB를 유연하게 확장할 수 있었던 것이다.
물리적 샤드 | 논리적 샤드 | |
정의 | 데이터를 물리적으로 분산한 실제 단위 | 데이터를 논리적으로 분산한 가상의 단위 |
필요성 | 대규모 데이터 분산 저장 및 성능 향상 | 물리적 확장 시, Client 변경 없이 유연한 매핑 |
데이터 복제 - 고가용성, 안정성, 성능
•
좌측 샤드에 장애가 발생했다. 시스템 오류 또는 네트워크 순단에 의한 일시적인 현상일 수도 있고, 자연 재해에 의한 영구적인 데이터 손실일 수도 있다.
•
그럼 좌측 샤드의 데이터는 복구 전까지 또는 영구적으로 사용할 수 없는 것일까?
•
이러한 문제를 해결하기 위해 데이터 복제본을 관리할 수 있다. Primary(주 데이터베이스)에 데이터를 쓰고, Replica(복제본)에 데이터를 복제한다. Primary/Replica, Leader/Follower, Master/Slave, Main/Standby 등 유사한 개념이지만, 시스템이나 목적에 따라 다르게 사용되기도 한다.
•
이러한 복제는 동기적 또는 비동기적으로 처리될 수 있다.
◦
Synchronous(동기적): 데이터 일관성을 보장하나, 쓰기 성능이 저하된다.
◦
Asynchronous(비동기적): 쓰기 성능은 유지되나, 복제본에 최신 데이터가 즉시 반영되지 않을 수 있다.
•
이러한 복제본은 고가용성을 위해 동일한 데이터 센터 내에 관리될 수도 있고, 다른 지역의 데이터 센터에서 관리될 수도 있다. 이러한 데이터의 분산을 통해 데이터는 안전하게 관리된다.
•
이제 좌측 샤드에 장애가 발생하더라도?
•
Replica에서 데이터 조회를 수행할 수도 있고,
•
Replica를 Primary로 재선출하여 쓰기 작업을 이어서 수행할 수도 있다.
•
이러한 시스템을 통해, 고가용성(Primary 재선출을 통한 서비스 지속성), 데이터 유실 방지 및 데이터 백업(Replica 복제본 관리), 부하 분산(Replica 또는 각 샤드로 요청 분산) 등의 다양한 이점을 가질 수 있다.
•
Distributed가 무엇인지 학습했지만..
◦
이러한 환경이 구축되어 있다고 가정만 한다.
▪
안정성, 고성능, 고가용성, 내결함성, 확장성 등이 보장된 환경
▪
우리는 서버 애플리케이션 개발이 주 목적
◦
우리의 개발 환경에서는 단일 MySQL을 사용한다.
▪
Docker로 세팅한다.
▪
Sharded 환경을 어느 정도 고려해서 개발한다.