Search

샤딩

샤딩

큰 데이터를 여러 서브셋으로 나누어 여러 인스턴스에 저장하는 방법이다. 이때 각 서브셋을 샤드(shard)라고 한다.
파티셔닝은 하나의 인스턴스에서 테이블을 분리하여 사용한다.
데이터를 여러 인스턴스로 분산해 쿼리할 데이터의 양이 줄어듦에 따라 쿼리 성능을 향상시킬 수 있다.
단점
1.
재샤딩에 비용이 많이 든다 : 추후, 수요가 증가/감소해 서버를 추가/제거하는 경우 데이터를 재샤딩하는 것이 복잡하다. 데이터를 샤딩하기 위해 주어진 조건에 따라 데이터를 다시 정렬해야 하므로, 비용이 많이 든다.
2.
샤드는 불균형이 될 수 있다 : 샤드를 나누는 방식에 따라 데이터 불균형이 발생할 수 있다.
3.
샤드 병합이 복잡하다
4.
Join 비용이 증가한다 : 데이터가 여러 서버에 분산되어 있는 경우 모든 서버에서 조인 작업을 수행해야 하므로 매우 복잡하다.

샤딩 종류

1. Hash Sharding

열, 또는 열 조합을 선택하고 해시 함수 결과값을 통해 샤드를 결정하는 방식이다.
아래 그림은 그 중 하나인 Modular Sharding 방식으로 PK값의 모듈러 연산 결과를 통해 샤드를 결정하는 방식이다.
PK값을 샤드의 개수로 모듈러 연산해 해시값을 얻으므로, 총 샤드 수가 정해져있을 때 유용하다.
단점 : 샤드 추가/감소 시 해시 함수 변경이 필요하고, 이에 따라 데이터를 재정렬 해야한다. (재샤딩)

2. Range Based Sharding

범위(날짜 범위, 기본 키 등)를 기반으로 샤드를 만드는 방식이다.
아래와 같이 PK가 0-9인 데이터는 0번 샤드에, 10-19인 데이터는 1번 샤드에 저장할 수 있다.
샤드 추가/감소 비용이 Hash Sharing 방식보다는 낮다.
단점: 샤드의 불균형이 발생할 수 있다. 즉, 특정 샤드에만 부하가 집중될 수 있다.

3. Directory Based Sharding

각 샤드에 대한 카테고리(shard key)를 설정해 데이터의 종류에 따라 동일한 샤드로 그룹화하는 방식이다.
이러한 카테고리는 지역, 성별등이 될 수 있다. (카디널리티가 낮은)
lookup table에 shard key를 추가하면 되므로, 샤드 추가/감소에 비교적 유연하다.
단점: 반드시 샤드와 데이터를 매핑하는 lookup table을 만들고 유지해야 한다.
단점: 쿼리를 수행하기 전 반드시 lookup table을 거쳐야하므로 성능이 낮아질 수 있다. lookup table이 단일 장애 지점이 될 수 있다.

4. Entity Group Based Sharding

관련된 데이터를 기반으로 데이터를 분할하는 방식이다.
관계형 데이터를 다른 샤드에 보관하면 조인 작업을 수행하는 것이 복잡해지므로, 관련된 데이터는 같은 샤드에 저장하는 방식이다.
아래와 같이 Users 데이터를 기반으로 샤드를 결정하고, 해당 User와 관련된 모든 데이터를 동일한 샤드에 보관한다.
Join 비용을 줄여 쿼리 성능 최적화 가능
단점: 관계형 데이터베이스에 적합하다.

샤딩 해야하나?

이런 상황에서 유용하다
애플리케이션 데이터 양이 단일 데이터베이스 서버의 스토리지 한계를 초과했을 때
Write & Read 양이 단일 데이터베이스 서버나 read replica가 핸들링할 수 있는 수준을 넘어서서 반응이 느려졌을 때
단일 데이터베이스 서버 또는 read replica에 가능한 네트워크 대역폭을 초과해 반응 속도가 느려졌을 때
샤딩은 복잡도가 높아지므로, 최적화할 수 있는 모든 다른 옵션들을 검토해야 한다
캐시(Cache): 읽기 성능이 문제라면, 캐시를 통해 이미 요청된 데이터들을 일시적으로 메모리에 저장해 읽기 성능 향상 가능.
복제(Replication): read replica를 추가해 읽기 성능 향상 가능

결론

sharding은 데이터베이스 수평 확장을 고려할 때 좋은 해결책이 될 수 있다. 하지만 복잡성과 잠재적 실패 지점을 만들 수도 있다. 어떤 이에게는 필요할 수도 있지만, 다른 경우 sharding이 주는 이점보다 sharded architecture를 만들고 유지하는데 드는 시간과 비용이 압도적일 수도 있다.

Reference