서비스 오픈전에 J곡선 그래프를 타면서 성장하길 바라는 마음은 모두 같을 것이다.
그런 중요한 순간에 서버가 바틀넥이 되어 발목을 잡으면 안된다. 그래서 예측 가능한 서버 확장 방안에 대해서 사전에 준비를 해둬야 한다.
DB 샤딩은 데이터가 급격히 증가하게 되거나 트래픽이 특정 DB로 몰리는 상황을 대비해서 빠르고 유연하고 안전하게 DB를 증설할 수 있게 한다. 샤딩에 대해 알아보자.
샤딩
샤딩(Sharding)은 DB 트래픽을 분산할 수 있는 중요한 수단이다. 추가적으로 특정 DB의 장애가 전면 장애로 이어지지 않게 하는 역할도 한다.
샤딩은 각 DB 서버에서 데이터를 분할하여 저장하는 방식이다. 해당 데이터에 접근할 때는 샤딩키를 사용하여 동적으로 DB 서버를 매핑하는 과정이 필요하다.
샤딩과 수평적 파티셔닝과 차이점은 수평적 파티셔닝은 동일한 DB 서버 내에서 테이블을 분할하는 것이고 샤딩은 DB 서버를 분할한다는 것이다. 즉, DB 서버의 부하를 분산할 수 있다.
요구사항
샤딩을 하기 위해서는 아래의 공통된 요구사항이 필요하다.
- 라우팅을 위해 구분할 수 있는 유일한 키값이 있어야 한다.
- 설정으로 쉽게 증설이 가능해야 한다.
모듈러 샤딩
모듈러 샤딩(Modular Sharding)은 PK를 모듈러 연산한 결과로 DB를 라우팅하는 방식이다.
해당 방식은 아래의 특징을 가진다.
- 레인지 샤딩에 비해 데이터가 균일하게 분산된다.
- DB를 추가 증설하는 과정에서 이미지 적재된 데이터의 재정렬이 필요하다.
데이터가 늘어남에 따라 샤딩을 추가적으로 해야하는 상황이 자주 생기면 큰 부하가 발생한다. 그렇기 때문에 모듈러 샤딩은 데이터량이 일정 수준에서 유지될 것으로 예상되는 데이터 성격을 가진 곳에 적용할 때 어울린다.
데이터가 균일하게 분산된다는 점은 트래픽을 안정적으로 소화하면서도 DB 리소스를 최대한 활용할 수 있다는 것을 의미한다.
레인지 샤딩
레인지 샤딩(Range Sharding)은 PK의 범위를 기준으로 DB를 특정하는 방식입니다.
해당 방식은 아래의 특징을 가진다.
- 모듈러 샤딩에 비해 기본적으로 증설에 재정렬 비용이 들지 않는다.
- 일부 DB에 데이터가 몰릴 수 있다.
레인지 샤딩의 가장 큰 장점은 증설 작업에 드는 큰 비용이 들지 않는다는 점이다. 데이터가 급격히 증가할 여지가 있다면 레인지 방식은 좋은 선택이 될 것이다.
다만 활성 유저가 몰린 DB로 트래픽이나 데이터량이 몰릴 수 있다. 그러면 또 몰리는 DB는 분산시키고 트래픽이 저조한 DB는 통합시키는 과정이 필요하다. 따라서 적절한 Range 기준을 잡는 것이 중요하다.
디렉토리 샤딩
디렉토리 샤딩(Directory Based Sharding)은 별도의 조회 테이블을 사용해서 샤딩을 하는 경우다.
해당 방식은 아래의 특징을 가진다.
- 샤딩에 사용되는 시스템이나 알고리즘을 사용할 수 있다.
- 샤드를 동적으로 추가하는 것도 비교적 쉽다.
- 모든 읽기 및 쓰기 쿼리 전에 조회 테이블을 참조해야 하므로 오버헤드가 발생한다.
구현
샤딩은 일반적으로 DBMS가 지원하는 기능이 아니다. 그래서 ORM을 사용하거나 DB에 접근하는 서버에서 구현해주는 작업이 필요하다.
자바의 경우 AbstractRoutingDataSource를 구현함으로써 풀어낼 수 있다.
필요하다면 아래 우아한형제들 기술 블로그를 참고하자. Spring AOP를 활용해서 샤딩 기능을 독립적인 관점으로 구현하였다.
- https://techblog.woowahan.com/2687
정리
샤딩을 사용하면 DB의 트래픽을 분산시킬 수 있게 큰 역할을 한다. 추가적으로 DB의 테이블 크기를 줄이게 되고 DB의 장애를 국소화시키는 부수적인 역할도 한다.
하지만 샤딩은 파티셔닝(Partitioning)이나 복제(Replication)보다 신중하게 결정해야 한다. 샤딩은 실제 구현이 복잡하다. 잘못 수행하면 데이터가 손실되거나 테이블이 손상되거나 부하의 불균형 등이 발생할 수 있다. 이를 샤딩 전 원래 DB 구조로 되돌리는 작업은 매우 복잡하고 어렵다.
조회할 레코드를 줄이기 위해서는 일반적으로 파티셔닝을 적용할 수 있다. 장애를 방지하고 DB 부하를 분산시키기 위한 목적으로는 복제를 사용할 수 있다. DB서버에도 MSA를 적용하고 분산 트랜잭션으로 잘 풀어나가는 방법도 있다.
하지만 정말 그렇게 해도 안될 경우가 있다. 가령, 전 세계적으로 데이터를 관리하는 경우 당연히 서버가 지역별로 많이 분포되어 있을 수록 좋다. 이때는 샤딩을 사용할 수 있다. 미친듯이 사용자가 많고 레코드 수가 많아서 MasterDB 하나로 도저히 받지 못할 때도 샤딩을 사용할 수 있다.
DB 서버 뿐만 아니라 어떠한 서버에도 Scale-In은 한계가 있다. DB 서버에서의 Scale-out은 동기화라는 제약이 따르게 되는데 전 세계에 뿔뿔이 흩어진 수 천, 수 만개의 DB를 동기화 하는 과정은 결코 쉽지 않다. 그래서 DB 서버의 샤딩은 대규모 시스템 설계와 확장성 확보에 필수 불가결인 요소가 된다.
Reference
- https://techblog.woowahan.com/2687
- https://sophia2730.tistory.com/entry/Databases-Database-Sharding%EC%83%A4%EB%94%A9
- https://nesoy.github.io/articles/2018-05/Database-Shard
- https://levelup.gitconnected.com/what-is-database-sharding-and-how-is-it-done-f36b9cb653e8
'Database > Server' 카테고리의 다른 글
Database의 책임 - DB는 어디까지 해줘야 하는가? (+ 데이터 가공, 비즈니스 로직, 계산 등) (0) | 2022.05.06 |
---|---|
Master-Slave를 사용하는 이유 (Replication 장단점) (0) | 2022.02.25 |