- 샤딩을 왜 할까?
- 샤딩은 단일 논리적 데이터 셋을 다수의 데이터 베이스에 쪼개고 나누는 방법이다.
- 레플리카란 뭔가?
- 이중화를 의미하며, 미러링, 백업 디비 등의 용어로도 통용되는데 다양한 방식으로 구현되는 복제를 지칭한다.
샤딩의 목적은 데이터를 분산 저장함으로써, 트래픽 분산에 목적이 있다. 샤딩도 디테일에서 여러방식으로 갈리는데, 샤딩된 노드끼리 통신해야 할 경우에는 트래픽이 다시 몰리는 경우가 있다. (여러 노드의 데이터를 조합해서 결과를 내야 하기 때문)
샤딩은 분산된 데이터 그 자체로 의미가 있을 때는 샤딩 그 자체가 트래픽 분산이 깔끔하게 이루어진다. 실질적으로 이 경우는 샤딩이라 부르기보단 DB 분산 (또는 파티셔닝. 게임의 경우 월드 단위 DB를 따로 쓰는 등의)이라고 부르는 경우도 많은 것이 그 이유다.
필요할 경우 샤딩된 각 디비에서 데이터를 꺼내와서 원하는 결과를 보여주거나, 원하는 처리를 해야 할 때가 있는데, 이 코스트가 꽤나 큰편이다. 어디에 샤딩되어있으며, 샤딩된 결과를 다시 배포해줄 때의 동기화 이슈나 충돌 이슈 등에 대한 문제가 커, 트래픽 분산이 목적이었는데 적지 않은 트래픽과 운용 이슈를 만들기도 한다. 여러 개 샤드에서 데이터를 꺼내와서 그 결과를 다시 분산 처리하고 이 과정에서의 무결성을 유지하는 것은 꽤나 어려운 문제다.
이는 샤딩의 장점보다 단점이 크게 사용되는 사례이지만, 이처럼 샤딩은 성능 문제를 위한 솔루션일 뿐 이외의 장점은 없다고 봐도 무방하다.
샤딩과 레플리카의 본질적 목적과 효과가 다르다.
레플리카는 fail-over나 read/write 경합 감소(또는 제거), read 코스트 분산 등에 치중되어있다.
fail-over시에는 복제 디비를 둠으로써, 메인 디비가 장애가 생겨도 복제 디비에서 정상적인 서비스를 빠르게 구성할 수 있게 구성하는 것이 목적이다.
read/write node를 분리함으로써 성능 분산도 처리할 수 있다. (특히 경합이 이루어질 경우 성능 저하도 우회할 수 있다.)
디비에서의 또다른 전략으로는 파티셔닝이 있는데 주로 사용되는 파티셔닝은 다음과 같다. 이 역시 개념적인 것에 명칭을 붙인것이므로, 더 다양한 방법의 파티셔닝이 존재한다.
- 수직 파티셔닝
- 컬럼들 중 특정 컬럼을 나누어 파티셔닝 하는 것.
- 수평 파티셔닝
- 값을 기준으로 파티셔닝 하는 것.
- Key or hash 기반 파티셔닝이라고도 불림.
- 샤딩도 수평 파티셔닝으로 구현되는 경우 많아 동의어로 사용되기도 함.
- 값을 기준으로 파티셔닝 하는 것.
- 범위 기반 파티셔닝
- 기능 별로 파티셔닝 하는 것.
조금 길게 왔는데 요약하자면 아래와 같은 개념이라고 요약할 수 있다.
- 샤딩, 파티셔닝
- 데이터 분산 저장
- 데이터가 한 곳에 저장되지 않으므로, 분리되어 있는 데이터들을 합쳐서 연산하기 위해선 어플리케이션 레이어나, 플러그인, 서드파티 솔루션 등으로 극복해야하나 많은 기술적 제약이나, 리스크를 가진다.
- 데이터 분산 저장
- 레플리카
- 데이터 복제 저장
- 일정 수준 이상의 지연은 생길 수밖에 없지만 이를 감안하고 지연 복제하는 경우가 일반적.
- 데이터 복제 저장
주의할 점은 분산된 결과를 복제하는 과정 (샤딩+레플리카)이나, 레플리카 구성시 마스터 슬레이브 개념이 없을 시 동기화 이슈가 크게 발생하곤 한다. 양방향 동기화는 오류의 여지가 커지기 때문에 그렇다.
또한 샤딩 사용시 노드를 추가할 경우 리밸런싱은 일반적으로 지원되지 않는다. 이를 위한 작업은 많은 양의 데이터를 재배치하고, 이에 대한 해싱 키등을 재조정하는 큰 작업이므로 점검을 통해 진행되곤 한다. 그래서 운용에 무리가 없을 만큼의 샤드 노드를 확보하거나, 적절한 시점 오토 스케일링, 백그라운드 리밸런싱 등을 고려해야 운영 포인트를 크게 감소 시킬 수 있다.
개념적으론 둘다 쓰면 좋은거 아닌가 싶겠지만, 복잡한 구성을 하면 할 수록, 고민할 여지나 운용 이슈가 발생할 부분이 있다. 특히 내가 설명한 개념과 다르게 구현된 DBMS도 여럿 있을 것이기에 이를 감안한 리서치와 검토, 검증이 필요하다.