대규모 데이터베이스를 수평 분할하여 파편화된 형태로 관리하는 기법을 샤딩이라고 한다. 대량의 정보를 저장하고 접근할 때의 확장성에 도움을 준다.
하나의 서버만을 사용해 데이터를 저장하는 경우는 아래의 문제점과 한계를 가질 수 있다.
- 저장 공간: 서버에서 제공할 수 있는 용량을 초과해서 저장해야 할 경우, 서버의 디스크 크기를 키우거나(scale-up) 새 디스크를 추가(scale-out)해야 한다. 서버 한 대로 관리하는 것이 점차 까다로워지기 때문에 서버를 분산해서 사용해야 할 필요성이 증가한다.
- 처리 속도: 한 대의 서버에서 제공할 수 있는 컴퓨팅 속도 또한 저장 공간과 같이 제한되어 있다. 더 좋은 프로세서를 사용하거나 프로세서의 수를 늘려도 그 한계에 도달하게 된다. 처리 속도가 느리면 사용자가 느끼는 응답 시간은 길어지고, 결국 더 많은 서버 컴퓨터가 필요해지는 시점이 온다.
- 네트워크 대역폭: 한 대의 서버가 처리할 수 있는 네트워크 대역폭 또한 한정적이다. 트래픽을 초과하는 요청이 들어오면 실패하기 때문에, 더 많은 서버를 사용해야 하는 경우가 생긴다.
- 지리적 특성: 데이터의 종류와 서비스의 특징에 따라 데이터를 다른 지역에 분산 배치해야 하는 경우가 있다. 국내의 경우 지도 정보나 의료 정보는 국외로 반출할 수 없어, 서버를 국내에 두어야 한다. 스트리밍 서비스의 경우 서비스 지역에 서버를 배치하는 것이 속도 면에서 더욱 유리하다. Scale-up 방식의 업그레이드를 통해 이런 문제점들을 일부 해결할 수 있지만, 한계가 명확한 일시적인 대처다. 그렇기 때문에 scale-out을 효과적으로 지원할 수 있어야한다.
데이터를 샤드라는 조각으로 수평 분할해 보관한다. 각 샤드는 동일한 스키마를 갖지만, 전체 데이터의 일부를 담고 있다. 샤딩을 통해서 아래와 같은 이점을 얻을 수 있다.
- Scale-out 형식으로 서버를 추가하고, 각 서버에 샤드를 배치할 수 있다.
- 샤드간 워크로드 밸런싱을 통해 성능을 향상시키고 병목 현상을 해결할 수 있다.
- 필요에 따라 샤드를 물리적으로 가까운 곳에 배치시켜 운용할 수 있다.
샤딩을 위해 데이터를 수평 분할해서 보관해야 한다. 일반적으로, 특정 속성을 기준으로 구간을 나눠 각 샤드로 나누게 된다. 이때 지정된 속성을 샤드 키(shard key, partition key)라고 한다. 샤딩을 통해 물리적으로 데이터를 나눠서 보관하고 정리할 수 있다. 샤드 키는 불변하는 속성으로 지정해야 한다. 샤드 키를 통해 데이터가 위치할 샤드를 찾아야 하기 때문에, 샤드 키가 변하면 구조가 망가진다.
샤딩 패턴이 적용된 애플리케이션은 정보를 저장하거나 불러올 때, 브로커를 통해 적절한 샤드를 찾는다. 브로커는 샤드 키에 해당하는 정보를 받아, 샤딩 로직에 맞춰 애플리케이션이 필요한 샤드를 찾을 수 있도록 해준다. 애플리케이션은 추상화된 데이터베이스에 접근하고, 브로커는 적절한 샤드를 찾을 수 있도록 해준다.
데이터를 적절히 나누기 위해 다양한 전략이 존재한다. 대표적으로 3가지 샤딩 전략이 있다.
- Lookup Strategy: 샤드 키를 받으면, 데이터가 위치한 샤드로 안내할 수 있도록 매핑하는 전략이다. 샤드 키를 통해 가상의 샤드를 찾고, 시스템에서 가상의 샤드를 물리적인 디스크로 안내하게 할 수 있다.
- Range Strategy: 샤드 키를 구간으로 나눠 샤드에 저장하는 전략이다. 데이터를 순차적으로 저장해야 하는 경우 자주 적용된다. 예시로, 시간 순으로 정보를 받아와야 하는 애플리케이션의 경우, 동일한 샤드에 정보가 연속적으로 위치한게 성능 면에서 유리하기 때문이다.
- Hash Strategy: 샤드 키를 해싱을 통해 나눠 샤드에 저장하는 전략이다. 이 방식의 핵심은 특정 샤드에 트래픽이 몰리지 않도록 하는 것이다.
성능과 확장성을 위해 데이터를 적절히 나눠주는것이 중요하다. 그리고 애플리케이션의 특징과 부합하는 샤딩 전략을 선택하는 것이 중요하다.
10,000명의 회원에 대해 1 ~ 10,000의 회원ID를 샤드 키로 갖는 애플리케이션을 예시로 들자면, 회원ID를 2,000개 단위로 5개의 샤드로 나눠 관리한다고 가정하자. 초기 회원인 회원ID 1 ~ 2,000에 해당하는 유저의 경우 지속적으로 애플리케이션을 사용해 샤드에 저장할 정보가 많고, 신규 회원인 회원 ID 8,001 ~ 10,000에 해당하는 사용자는 활발하게 활동하며 트랜젝션이 빈번하게 일어나는 상황이라면 2가지 문제가 발생한다. 초기 회원 정보를 보유한 샤드의 경우 데이터양이 집중되어 다른 샤드와 균형을 이루지 못한다. 그리고 신규 회원의 정보를 보유한 샤드의 경우 트랜젝션이 몰려 다른 샤드와 균형을 이루지 못하는 문제가 발생한다.
위 예시에서 Range Strategy를 적용했지만, Hash Strategy를 적용했다면 샤드 간 균형을 맞출 수 있을 것이다.