본문 바로가기

database

[DB] 샤딩(Sharding)이란?

샤딩

샤딩은 분산 시스템에서 데이터를 수평적으로 분할하는 기술이다. 수평적 파티셔닝(horizontal partitioning)의 일종으로 볼 수도 있지만, 분산 시스템에서 서로 다른 시스템 자원을 이용하여 데이터베이스의 부하를 분산시키고 성능을 최적화하는 데 초점이 있다.

아래 그림처럼 단일 서버에서 데이터를 read & write 하는 것이 아니라, 여러 대의 서버로 나누어 저장하고 조회도 각각의 데이터베이스에서 처리함으로써 부하를 분산시킬 수 있다.

출처: oracle docs

 

언제 필요할까?

파티셔닝과 비교해보자. 10개의 파티션을 만들어 주로 적은 수의 파티션에서 read & write 작업이 일어난다면 파티셔닝이 성능 향상에 도움이 될 수도 있다. 하지만 10개의 각 파티션을 균일하게 사용하게 된다면 오히려 오버헤드가 커지는 결과를 초래할 수도 있다.

대용량 테이블에서 이를 sharding 하여 10대의 서버에 분산시키고 각 read & write 작업이 10%씩 균등하게 분산될 수 있다면 각 데이터베이스 서버의 부하도 1/10로 감소할 수 있을 것이다.

 

샤딩을 어떻게 적용할까?

1. key based sharding(hash based sharding)

아래 그림처럼 특정 컬럼의 값을 shard key로 하여 hash function을 통해 산출된 hash value를 기준으로 각 노드에 분산하여 write & read 할 수 있다. 또는 4대의 node가 있다면 id % 4 등으로 저장 노드의 위치를 나누어 저장할 수도 있다.

하지만 이 방법은 db 서버를 scale-out 할 때 hash 함수를 재사용하기 어렵다. 노드가 추가된다면 해당 노드들에 적절히 분산시킬 수 있는 hash 함수를 다시 만들어 데이터들을 rebalancing 해주어야 한다. key 값의 나머지로 노드의 위치를 결정하는 방식도 노드의 수가 늘어나면 다시 재구성해야 하는 단점이 있다.

출처: https://www.digitalocean.com

 

2. range base sharding

특정 컬럼의 범위를 기준으로 각기 다른 노드에 분산하는 방식이다. 아래 그림처럼 price의 범위를 지정하여 해당 범위에 속하는 값을 가진 데이터셋을 같은 노드에 저장할 수 있다.

다만 특정 컬럼의 해당 범위의 데이터가 집중될 때는 샤딩의 효과를 보기가 어렵다.

출처: https://www.digitalocean.com

 

3. directory based sharding

directory based는 중간에 lookup table을 둔다. 이를 통해 어떤 샤드에 어떤 데이터가 존재하는지를 추적할 수 있고, 각 데이터셋을 균일하게 여러 샤딩 테이블로 분산하여 write & read 할 수 있다. 다만 이 방식은 shard key가 되는 컬럼의 cardinality가 낮을 때 적합하다.

출처: https://www.digitalocean.com

 

샤딩을 하는 것이 항상 좋을까?

샤딩은 잘못 적용될 경우 데이터가 손실되거나 정합성이 맞지 않게 되는 경우가 발생할 수 있다. 또 이를 복구하는 것도 까다롭다. 또한 저장되는 데이터를 균등하게 분산시키지 못하거나, 일부 db 서버의 데이터만 자주 호출되어 일부 서버에만 부하가 발생하는 hotspot이 발생할 수도 있다.

따라서 데이터의 양이 단일 서버의 스토리지 용량을 초과했을 때, 단일 서버 또는 read replication 서버가 read or write 시 부하를 처리하지 못해 느려졌을 때 등 scale up 만으로 성능 향상 효과를 보지 못할 때 고려하는 것이 적합하다.

샤딩은 구성이 복잡하고 유지보수 비용이 증가하므로 caching, read replica, scale up 등 여러 해결책을 먼저 고려해본 뒤 필요 시에 도입해야 한다.

 

[참고자료]

oracle docs

digitalocean blog