[시스템 설계: 한번에 인터뷰 합격하기] 샤딩(Sharding) & RDB vs NoSQL
Programming

[시스템 설계: 한번에 인터뷰 합격하기] 샤딩(Sharding) & RDB vs NoSQL

1. 알고자 하는 것

  • 샤딩 (Sharding)
  • Sharding: MongoDB, Cassandra
  • RDB vs NoSQL

 

2. 알게 된 것

Sharding

  • 샤딩은 데이터를 여러 DB에 분산하여 저장하는 방식이다.

  • 데이터를 특정 Hash Function을 통해 구분지어 각 샤드에 저장한다.
  • 클라이언트는 각 요청에 대해 Hash Function을 통해 데이터가 있는 샤드에 접근하여 데이터를 조회 및 저장한다.
  • 각 샤드에는 장애 시 메인 샤드 DB로 승격될 수 있는 백업을 가질 수 있다.
  • 이를 통해 새로운 DB를 계속 추가함으로써 무한히 확장 가능하다. (수평 스케일링의 장점)

 

Sharding: MongoDB

  • 몽고DB는 다음과 같은 구조로 샤딩을 구성한다.
  • 최소 3대 이상의 호스트를 구성하여 하나의 호스트에 장애가 발생해도 다른 호스트로 즉시 복구 될 수 있도록 한다. (고가용성)
  • 또한 3대 이상의 RS(Replica Set, = 샤드)을 두어 데이터를 분산저장한다. (해당 예시에서는 userId를 기준으로 분산)
  • 각 RS에는 Secondary DB들을 두어 Primary DB에 장애가 발생해도 Secondary DB를 Primary로 승격시켜 즉시 복구 될 수 있도록 한다. (고가용성)
  • 각 데이터의 분산 정보는 구성서버 (Config Server)에 기록해두어 mongos가 구성서버에서 데이터를 찾아올 위치를 알아와 처리한다.
  • 각 RS는 주기적으로 OPLog(데이터의 변경사항에 대한 쿼리가 저장되는 별도의 저장영역)에서 로그를 폴링하며 데이터를 동기화한다.
  • 이러한 샤딩 방식으로 몽고DB는 고가용성을 보장하고 단일 장애점(SPOF)을 최소화한다.
  • 하지만 장애 대비를 위해 많은 복제셋들이 대기하고 있어 DB 구성 시 비용이 많이 든다.
  • 또한, 많은 복제셋을 관리해야 하는 유지보수 비용 역시 많이 든다.

 

Sharding: Cassandra

 

  • 카산드라는 각 Node(= 샤드)를 링 형식으로 구성한다.
  • Primary, Secondary의 구성 없이 모든 노드가 주 서버가 될 수 있어 단일 장애점이 없다. (고가용성)
  • 이 때, 모든 데이터가 주 서버가 될 수 있으므로 한 노드에 최신 데이터가 쓰여지고 이러한 데이터가 다른 노드에 동기화되어 그 값을 반환하기까지 지연이 생길 수 있다. (데이터 지연)
    • 이를 궁극적 일관성 (Eventual Consistency)라고 한다.
    • 지금 당장은 아니더라도, 결국에는 최신의 데이터를 가지는 것을 의미.

 

RDB vs NoSQL

  • 이러한 샤딩 데이터베이스는 일반적으로 NoSQL (Not Only SQL)DB 이다.
    • RDB의 경우, 스키마가 고정되어 있고 정규화를 통한 join 연산을 통해 연관된 데이터를 가져온다.
    • 물리적으로 분할된 샤드에서의 join 연산은 많은 어려움이 동반되므로 샤딩은 고정되지 않은 스키마와 정규화되지 않은 데이터가 저장되는 NoSQL DB에서 주로 사용한다.
  • 더 많은 샤드가 추가될 때 데이터를 다시 분배하는 방식(Resharding)에 대한 처리가 까다롭다.
  • 특정 데이터에 대한 요청이 몰릴 경우 해당 샤드에 트래픽이 몰리는 HotSpot 문제가 있을 수 있다.
    • 모니터링을 통해 트래픽을 파악하고 샤드를 재분배하는 방식으로 해결해야한다.
  • NoSQL은 비정규화를 통해 다른 테이블에서 데이터를 결합해 가져오는 join 연산 없이 데이터를 key-value 형식 등으로 바로 가져올 수 있고, 샤딩을 통해 데이터를 수평적으로 확장할 수 있다.
  • 그러나 데이터 변경 시 중복된 모든 데이터를 모두 변경해야 하는 단점이 있다.
  • RDB는 정규화를 통해 중복된 데이터를 별도 테이블에 두어 공간을 절약하고, 변경 시 해당 데이터만을 수정하면 되는 용이성이 있다.
  • 그러나 데이터 조회 시 연관된 데이터를 조회하기 위해 join 연산이 필요하다.
  • 데이터의 변경이 잦은지 / 많은 데이터가 저장되어 확장이 고려되는지 / 다른 테이블과 join 연산 시 병목이 치명적인지 등을 고려하여 RDB, NoSQL의 사용을 고려해야한다.

 

3. 정리

  • 데이터베이스를 수평적으로 확장하는 방식에는 데이터를 여러 DB에 분산하여 저장하는 샤딩(Sharding) 방식이 있다.
  • 데이터 조회 및 저장 시 여러 DB가 트래픽을 분산하여 처리하고 장애 발생 시 다른 Secondary DB가 Primary DB로 승격해 처리한다.
    • 트래픽 분산이 용이하고 가용성이 높다.
  • 하지만 그에 따라 동기화의 문제, 많은 DB 구성으로 인한 비용, 유지보수의 어려움이 존재한다.
  • RDB와 NoSQL은 데이터의 변경, 확장성, join 연산 시 병목 등에서 각 차이를 보이므로 이러한 조건을 파악하여 선택하는 것이 중요하다.

 


Reference

강의 - 시스템 설계(System Design): 한번에 인터뷰 합격하기