DBMS/MongoDB

[MongoDB] 샤딩 개념

반응형
MongoDB in Action을 바탕으로 정리한 내용입니다.


샤딩의 배경

최신 애플리케이션의 규모가 커짐에 따라 많은 데이터와 부하를 처리할 만큼 강력한 단일 시스템을 얻는 것이 점점 더 비용이 많이 들고, 일부의 경우 불가능해지고 있다. (컴퓨팅 성능에는 한계가 존재하기 때문)

문제에 대한 한 가지 해결책은 많은 컴퓨팅의 용량을 모으는 것이다.


샤딩이란?

샤딩(Sharding)은 데이터베이스를 작은 조각으로 분할하여 단일 머신이 모든 데이터를 저장하거나 전체 부하를 처리하지 않도록 하기 위해 고안된 것.

  • 데이터의 크기가 커지고 애플리케이션이 더 많은 읽기 쓰기 처리량을 필요로 할 때 단일 서버로는 충분하지 않을 수 있다.
  • 이러한 문제를 해결하기 위해 데이터베이스를 둘 이상의 서버에 분산시켜야 한다. MongoDB에서는 이를 수행하는 방법을 샤딩이라고 한다. (참고로 샤딩은 관리 및 성능 오버헤드가 존재하므로 샤딩을 하)


샤딩을 언제 하는 것이 좋을까?

일반적으로 샤딩은 저장소 분산과 부하 분산이라는 두 가지 주요한 목적을 가지고 있다.

(다만 샤딩이 모든 성능 문제를 해결하는 것은 아니며, 추가적인 관리 복잡성과 성능 오버 헤드를 발생시키므로, 애플리케이션에 필요할 경우인지 확인하는 절차가 필요하다.)

부하 분산

  • 샤딩을 하는 가장 큰 이유 중 하나로 인덱스와 작업 데이터 세트를 RAM에 유지하는 것이 성능상 중요하다.
  • 애플리케이션의 데이터 세트가 무한대로 계속 증가하면 해당 데이터가 더 이상 램에 들어가지 않게 된다.


샤드 클러스터 구성 요소

샤딩이 가능하도록 하기 위해서는 여러 구성 요소가 함께 작동해야 한다.

  • 모든 것이 함께 기능적으로 작동할 때 샤드 클러스터라고 한다.

샤드 클러스터


샤드 (애플리케이션 데이터의 저장소)

  • 애플리케이션 데이터를 저장한다.
  • 샤드 클러스터에서는 오직 mongos 라우터 또는 시스템 관리자만 샤드에 직접 연결해야 한다.


mongos (연산 라우터)

  • 각 샤드에는 클러스터 데이터의 일부만 들어 있으므로 연산을 적절한 샤드로 라우팅해야 한다
  • mongos 프로세스는 모든 읽기, 쓰기 및 명령을 해당 샤드에 보내는 라우터다.
  • 이러한 방식으로 mongos는 클라이언트에게 클러스터와의 단일 접촉 지점을 제공하며, 이는 샤드 클러스터가 비 샤드 클러스터와 동일한 인터페이스를 제공할 수 있게 한다.


설정 서버

  • mongos 프로세스는 지속성이 없으며 이는 클러스터를 적절하게 관리하는 데 필요한 메타 데이터를 영구적으로 저장해야 함을 뜻한다. (이것이 설정 서버의 역할)
  • 메타 데이터에는 글로벌 클러스터의 설정사항과 각 데이터베이스 컬렉션, 각 범위의 데이터의 위치, 샤드 간 데이터 전송 내역을 가지고 있는 변동사항 로그이다.
  • 설정 서버가 가지고 있는 메타 데이터는 클러스터가 제대로 동작하고 유지되기 위해 반드시 필요하다. 예를 들어 mongos 프로세스는 시작할 때마다 설정 서버로부터 메타데이터 복사본을 가지고 온다.
  • mongos 프로세스가 쓰기를 할 때 2단계 커밋을 사용하는데, 이것을 통해 설정 서버들 사이의 일관성이 보장된다.


샤드 된 클러스터에서의 데이터 분산

도큐먼트

  • MongoDB에서 가장 작은 데이터 단위

청크

  • 필드의 값 별로 클러스터 된 도큐먼트 그룹.
  • 샤드 키라는 필드 또는 필드 집합에 대한 값을 기반으로 하는 도큐먼트의 논리적 그룹.

컬렉션

  • 데이터베이스 내에 명명된 그룹화된 도큐먼트

데이터베이스

  • 도큐먼트 모음을 포함하며, 시스템의 최상위 레벨 그룹.


샤드 된 클러스터에 데이터를 분산시킬 수 있는 방법

  • 컬렉션의 파티션 또는 청크 수준에서 컬렉션의 도큐먼트 자체가 분할되어 도큐먼트의 샤드 키라는 필드 또는 필드 집합의 값에 따라 여러 샤드로 분산된다.

MongoDB가 개별 도큐먼트가 아닌 청크 기반으로 분할하는 이유

  • 도큐먼트 수준에서 분할하면 모든 단일 도큐먼트를 독립적으로 추적하여 설정 서버에 메타데이터를 저장해야 하는 문제가 존재.


컬렉션 내에서 샤딩하기

  • 개별 컬렉션의 파티셔닝을 허용하기 위해 MongoDB는 미리 정의된 필드의 값 또는 샤드 키라는 필드 세트를 기반으로 도큐먼트의 논리적 그룹인 청크의 개념을 정의한다.
  • MongoDB는 각 도큐먼트에서 샤드 키 정보를 사용하여 도큐먼트가 어떤 청크에 속하는지 확인한다.
  • 코어에서 MongoDB 샤딩은 범위 기반이다. 즉 각 청크는 샤드의 범위를 나타낸다.


샤딩 클러스터 질의 및 인덱싱

애플리케이션 관점에서 보면 샤드 클러스터에 질의하는 것과 단일 mongod에 질의하는 것 사이에 차이가 없다.

  • 두 경우 모두 질의 인터페이스와 결과 집합을 반복하는 과정은 같다.
  • 하지만 이면에는 여러 가지 다른 점들이 있고 정확히 어떤 일들이 일어나고 있는지 이해하는 것이 중요하다.


쿼리 라우팅

샤드 클러스터에 질의한다고 할 때 질의에 대한 결과를 반환하기 위해 mongos는 얼마나 많은 샤드에 연결해야 할까?

  • 샤드 키가 쿼리 실렉터에 있는지 여부에 달렸음을 을 수 있다.
  • 설정 서버는 키의 범위를 샤드에 대해 매핑한 것을 갖고 있다.
  • 샤드 키가 쿼리에 포함되어 있으면 mongos는 신속하게 청크 데이터를 참고해서 질의의 결괏값이 정확히 어느 샤드에 포함되어 있는지 결정한다. (타깃 쿼리라고 한다)
  • 하지만 만일 샤드 키가 쿼리에 들어 있지 않다면, 쿼리 플래너는 질의를 완전히 수행하기 위해 모든 샤드를 다 방문해야 한다. (글로벌 쿼리 or 스캐터/개더 쿼리라고 한다)


샤드 클러스터에서 인덱싱 하기

  • 쿼리가 얼마나 잘 타기팅이 되든 관계없이 결국 하나 이상의 샤드에서 실행해야 한다.
  • 즉 샤드가 쿼리에 응답하는 속도가 느리면 클러스터도 느려질 것이다.

비 샤드 배포처럼 인덱싱은 성능을 최적화하는 중요한 부분이다.

  • 각 샤드는 자신만의 인덱스를 가진다.
  • 각 샤드에 대한 샤드 컬렉션은 같은 인덱스가 있어야 한다
  • 샤드 컬렉션은 _id 필드와 샤드 키에 대해서만 고유 인덱스를 허용한다.
    • 다른 필드에 대한 고유 인덱스는 금지되는데, 이것을 허용할 경우 샤드 간 통신이 필요하고 이는 MongoDB의 샤딩 기본 설계에 위배되는 것이기 때문이다.


샤드 키 선택

잘못 선택된 샤드 키로 인해 애플리케이션에서 샤드 클러스터가 제공하는 많은 장점들을 이용할 수 없게 된다.

  • 극단적인 경우 삽입과 질의 성능까지도 심각하게 영향받을 수 있다.
  • 샤드 키를 일단 선택하고 나면 변경할 수 없으므로 매우 신중하게 선택해야 한다.


핫스팟

  • 일부 샤드 키는 모든 읽기 또는 쓰기가 단일 샤드에 있는 단일 청크에 향하는 상황을 만든다.
  • 이로 인해 하나의 샤드는 완전히 주체할 수 없는 상황이 되고, 나머지는 유휴 상태가 된다.
    • 대표 적으로 _id 필드를 샤드 키로 사용하는 경우, 해당 값이 엄격한 오름차순이다. (모든 새 도큐먼트에는 컬렉션의 다른 도큐먼트보다 큰 샤드 키가 있다.)
    • 이로 인해 새로 생성된 모든 데이터가 동일한 청크에 속하게 될 수 있다. (100개의 샤드가 있더라도 나머지가 유휴 상태로 유지되는 동안 모든 기록은 하나의 샤드로 보내진다)


분할할 수 없는 청크 (낮은 수준의 타기팅)

  • username 필드를 샤드 키로 사용하는 경우, 상대적으로 균형 잡힌 삽입을 이끌어 낸다.
  • 하지만 세분화 수준이 너무 낮아서 하나의 청크가 경계 없이 자라는 상황에 처하게 될 수 있다. (예를 들어서 will이라는 이름을 가진 유저가 많이 있어 청크의 최대 크기인 64MB를 넘는 경우)


부족한 타깃팅

  • 샤드 키가 포함된 쿼리만 올바른 샤드로 라우팅 될 수 있다.


이상적인 샤드 키

샤드 키를 선택할 때 고려할 사항

  • 읽는 방법
  • 쓰기가 얼마나 잘 분산되는지
  • MongoDB가 컬렉션에서 청크를 얼마나 효율적으로 분할하고 마이그레이션 할 수 있는지

{username: 1, _id: 1}로 샤드 키를 잡는 경우 username 필드가 읽기에 종종 표시되고, username이 알파벳 전체에 고르게 분포되어 있어서 쓰기 밸런싱이 좋으며, 유일성을 가진 id 필드를 포함하고 있어 MongoDB가 청크를 분할할 만큼 충분히 세밀하므로 좋은 타깃팅이다.

 

Reference

http://www.yes24.com/Product/Goods/60659843

반응형

'DBMS > MongoDB' 카테고리의 다른 글

[MongoDB] MongoDB ReplicaSet 설정 방법 (샤딩 X )  (0) 2022.07.20
[MongoDB] MongoDB 배포 형태  (0) 2022.03.18
[MongoDB] MongoDB - 복제 (1)  (0) 2022.02.09