데이터베이스의 볼륨이 커질수록 성능은 감소하게 된다. 이를 해결하기 위한 대표적인 방법으로 파티셔닝과 샤딩이 있다. 이 글은 MySQL 8.0 버전의 InnoDB를 기준으로 작성되었다.
파티셔닝과 샤딩에는 두가지 방법이 있다.
레코드별로 분리하는 수평 분할을 뜻한다. 스키마 복제 후 사용자가 지정한 기준으로 분리한다.
스키마(컬럼)를 나누고 데이터가 따라 분산되는 것을 뜻한다. 도메인의 영향을 많이 받고, 분할이 쉽지만, 변경이 일어나는 경우 추가 정렬이 필요할 수 있다.
하나의 테이블을 여러개의 테이블로 물리적으로 분할 저장하는 방법.
사용자는 논리적으로 하나의 테이블을 사용하는 것과 같이 사용 가능하다.
지정된 값을 범위별로 분리한다.
지정된 값은 연속적이며 겹치지 않아야 한다. (보통 날짜별로 파티셔닝한다.)
PARTITION BY RANGE (원하는 컬럼) (
PARTITION p0 VALUES LESS THAN (값1), -- MIN_VALUE ~ 값1
PARTITION p1 VALUES LESS THAN (값2), -- 값1 ~ 값2
PARTITION p2 VALUES LESS THAN (값3), -- 값2 ~ 값3
PARTITION p3 VALUES LESS THAN (값4) -- 값3 ~ 값4
);
--보통 마지막 줄에 VALUES LESS THAN (MAX_VALUE)를 사용하기도 한다.
Range 파티셔닝과 유사하다.
다른점은 연속적인 범위가 아니라 컬럼값을 기반으로 분리한다. (보통 지역별로 나누기도 한다.)
PARTITION BY LIST(원하는 컬럼) (
PARTITION pNorth VALUES IN (3,5,6,9,17), -- 컬럼 값 3,5,6,9,17에 해당하는 레코드만 분리
PARTITION pEast VALUES IN (1,2,10,11,19,20), -- 위와 같음
PARTITION pWest VALUES IN (4,12,13,14,18),
PARTITION pCentral VALUES IN (7,8,15,16)
);
Hash 함수를 사용해 데이터를 균등하게 분할한다.
PARTITION BY HASH(원하는 컬럼)
PARTITIONS 4;
-- 컬럼 자리에 YEAR(원하는 컬럼)을 사용하면 년도별로 나뉜다.
Hash 파티셔닝과 유사하다. 테이블의 Key를 해시함수에 사용해 분할한다.
여기서 사용되는 Key는 NOT NULL이어야 한다.
PARTITION BY KEY() --LINEAR KEY 키워드 사용 가능(선형 해시)
PARTITIONS 10;
-- 비어있으면 기본키 사용, 컬럼 지정 가능
Composite 파티셔닝이라고 하기도 하며, 분할된 파티션을 한번 더 파티셔닝 하는 것이다.
PARTITION BY RANGE( YEAR(날짜 컬럼) )
SUBPARTITION BY HASH( TO_DAYS(날짜 컬럼) ) -- 여기서 2개로 나뉜다.
SUBPARTITIONS 2 ( -- 여기서 3개로 나뉜다.
PARTITION p0 VALUES LESS THAN (1990),
PARTITION p1 VALUES LESS THAN (2000),
PARTITION p2 VALUES LESS THAN MAXVALUE
);
-- 2개 x 3개 = 총 6개의 파티션
큰 테이블을 동일한 스키마를 가진 여러 데이터베이스 서버에 shard 단위로 분산 저장하는 방법. 수평파티셔닝과 비슷하다 생각이 들지만, 파티셔닝은 하나의 서버, 샤딩은 여러 서버에 분산한다는 차이점이 있다.
물리적으로 다른 서버에 저장하기 때문에 트래픽이 분산되고, 가용성이 늘어난다.
샤딩은 애플리케이션(서버)에서 구현하는 것이 일반적이나 플랫폼(DB)에서 제공하기도 한다.
반면에 샤딩은 데이터를 물리적으로 다른 서버로 분산시키기 때문에 여러 샤드에 있는 데이터를 조인하는데 어려움이 있다. 또한 반대로 한 샤딩에 데이터가 몰리는 경우 성능 저하가 발생한다.
컬럼값으로 샤드를 지정하는 방식이다. Hash Shard 대비 증설작업에 리소스 소요가 적다. 따라서 데이터가 **급격히 증가하는 경우 사용하면 좋다. 하지만, 특정 데이터베이스에 부하**가 몰리는 경우가 생긴다.
Hash 함수를 통해 반환되는 값으로 샤드를 결정하는 방법이다. 일반적으로 나머지값인 Modular를 사용한다. 샤드(분산 DB)수가 정해진 경우 사용하기 좋다. DB 수가 변경되면 재정렬이 필요하다.
Locator Service를 통해 shard를 나눈다. DB수가 변경되어도 Locator Service에 샤드키만 추가하면 되기때문에 확장에 유연하다.
데이터의 지리적 위치에 따라 가까운 서버에 분할한다. 한국이면 한국 샤드에, 미국이면 미국 샤드에 저장.