DB/몽고DB 완벽 가이드 3판

[14장] 샤딩 소개

꾸준함. 2025. 5. 16. 00:40

1. 샤딩이란

  • 샤딩은 여러 장비에 걸쳐 데이터를 분할하는 과정을 일컬으며, 때때로 파티셔닝이라는 용어로도 불림
    • 각 장비에 데이터의 서브셋을 넣음으로써, 수직 확장 없이도 더 많은 수의 덜 강력한 장비 (수평 확장)로 더 많은 데이터를 저장하고 보다 많은 부하를 처리할 수 있음
    • 더 자주 접근하는 데이터를 성능이 더 좋은 하드웨어에 배치하거나, 지역에 따라 데이터셋을 분할해 주로 접근하는 애플리케이션 서버와 가까운 컬렉션에서 도큐먼트의 서브셋을 조회할 수 있음

 

  • 수동 샤딩은 어떤 데이터베이스 소프트웨어를 사용하든 대부분 수행 가능
    • 수동 샤딩을 사용하면 애플리케이션이 여러 데이터베이스 서버와 연결을 유지하며, 각 서버는 완전히 독립적
    • 애플리케이션은 각기 다른 데이터를 다른 서버에 저장하고, 데이터를 조회하기 위해 적절한 서버에 쿼리 하는 과정을 관리함
    • 해당 방식은 클러스터에 노드를 추가하거나 삭제할 때 혹은 데이터 분산이나 부하 패턴이 변화할 때는 유지하기 어려운 단점이 있음

 

  • 몽고DB는 애플리케이션에서 구조를 추상화하고 시스템 관리를 간단하게 하는 자동 샤딩을 지원
    • 운영 측면에서는, 몽고DB가 샤드에 걸쳐 데이터 분산을 자동화하므로 용량을 추가하거나 제거하기 쉬움

 

1.1 클러스터 구성 요소 이해하기

  • 몽고DB 샤딩을 통해, 많은 샤드의 클러스터를 생성하고, 각 샤드에 데이터 서브셋을 넣음으로써 컬렉션을 쪼갤 수 있기 때문에 애플리케이션이 독립 실행형 서버나 복제 셋의 리소스 한계에 구애되지 않음
  • 샤딩의 한 가지 목적은 N개의 샤드 클러스터가 하나의 장비처럼 보이게 하는 것
    • 이러한 세부 사항을 애플리케이션으로부터 숨기기 위해, 샤드 앞단에 있는 mongos라는 라우팅 프로세스를 실행
    • mongos에는 어떤 샤드가 어떤 데이터를 포함하는 알려주는 `컨텐츠 목차`가 있으며 애플리케이션은 라우터에 연결해 정상적으로 요청을 발행할 수 있음
    • 라우터는 어떤 데이터가 어떤 샤드에 위치한지 알기 때문에 요청을 적절한 샤드들로 전달 가능
    • 요청에 대한 응답이 있으면 라우터는 응답을 수집하고 통합해 애플리케이션으로 되돌려 보냄

 

https://coding-start.tistory.com/275

 

2. 단일 장비 클러스터에서의 샤딩

  • 단일 장비에 클러스터를 설정하기 위해서는 먼저 --nodb 및 --norc 옵션을 사용해 mongo 셸을 시작해야 함

 

$ mongo --nodb --norc

 

  • 클러스터를 생성하려면 ShardingTest 클래스를 사용하며 직전에 시작한 mongo 셸에서 다음을 실행
    • ShardingTest는 몽고DB 엔지니어링 내부용으로 설계된 클래스이므로 외부적으로 문서화되지 않았지만 몽고DB 서버와 함께 제공되므로 샤드 클러스터를 실험하는 가장 간단한 수단
    • ShardingTest는 서버 테스트 셋을 지원하도록 설계됨

 

 

 

  • 명령을 실행하면 ShardingTest가 자동으로 많은 작업을 수행
    • 두 개의 샤드가 있는 새 클러스터를 생성하며, 각 샤드는 복제 셋
    • 복제 프로토콜을 설정하는 데 필요한 옵션으로 복제 셋을 구성하고 각 노드를 시작함
    • mongos를 시작해 전체 샤드의 요청을 관리하기 때문에 클라이언트는 독립형 mongod와 통신하듯 클러스터와 상호작용 가능
    • 마지막으로 구성 서버에 대한 추가 복제 셋을 시작하는데, 해당 서버는 쿼리를 올바른 샤드로 전달하는 데 필요한 라우팅 테이블 정보를 유지

 

  • ShardingTest가 클러스터 설정을 마치면 연결 가능한 실행 중인 프로세스는 10개
    • 노드 3개로 구성된 복제 셋 2개
    • 노드 3개로 구성된 구성 서버 복제 셋 1개
    • mongos 1개

 

  • 다음으로 mongos에 연결해야 하며 전체 클러스터가 현재 셸에 로그를 떠넘기므로 두 번째 터미널 창을 열어 다른 mongo 셸을 시작

 

$ mongo --nodb

 

  • 해당 셸을 사용해 클러스터의 mongos에 연결하며 mongos는 포트 20009에서 실행함

 

> db = (new Mongo("localhost:20009")).getDB("accounts")

 

  • mongo 셸의 프롬프트는 mongos에 연결됨을 반영하도록 변경돼야 함
    • 셸은 클라이언트이고 mongos에 연결됨
    • 이제 mongos에 요청을 전달할 수 있으며, mongos는 요청을 샤드로 라우팅
    • 샤드의 정보는 전혀 몰라도 되며 샤드가 있는 한 요청을 mongos에 보내서 적절하게 전달하도록 허용할 수 있음

 

  • sb.status()를 실행해 클러스터를 전체적으로 볼 수 있으며 샤드, 데이터베이스, 컬렉션에 대한 요약을 제공함

 

 

 

  • accounts 데이터베이스에는 위에 표시된 것과 다른 프라이머리 샤드가 있을 수 있음
    • 프라이머리 샤드는 `홈 베이스` 샤드이며, 각 데이터베이스마다 무작위로 선택되며 모든 데이터는 프라이머리 샤드에 있음
    • 몽고DB는 데이터를 분산할 방법을 모르기 때문에 아직 데이터를 자동으로 분산할 수 없으므로 컬렉션마다 데이터를 어떻게 분산할지 알려야 함

 

  • 특정 컬렉션을 샤딩하려면 먼저 컬렉션의 데이터베이스에서 샤딩을 활성화해야 하며 이를 위해 enableSharding 명령을 실행
    • 이제 accoutns 데이터베이스에서 샤딩이 활성화돼 데이터베이스 내에서 컬렉션을 샤딩할 수 있음

 

> sh.enableSharding("accounts")

 

  • 컬렉션을 샤딩할 때 샤드 키를 선택하는데, 이는 몽고DB가 데이터를 분할하는 데 사용하는 필드
    • i.g. "username"에서 샤딩하도록 선택하면 몽고DB는 데이터를 사용자명 범위로 나눌 수 있음; "a1-steak-sauce" ~ "defcon"까지, "defcon1" ~ "howie1998"까지로 나눌 수 있음
    • 샤드 키를 선택하는 것은 컬렉션 내 데이터 순서를 선택하는 것으로 생각할 수 있는데 이는 인덱싱과 유사한 개념이며, 컬렉션이 커질수록 샤드 키가 컬렉션에서 가장 중요한 인덱스가 됨
    • 샤드 키를 생성하려면 필드에 인덱스를 생성해야 함

 

> db.users.createIndex({"username": 1})

 

  • 이제 "username"으로 컬렉션을 샤딩할 수 있음
    • 여기서는 별 다른 고민 없이 샤드 키를 선택했지만 실제 시스템에서는 키를 선택할 때 신중하게 고려해야 함

 

> sh.shardCollection("accounts.users", {"username": 1})

 

  • 몇 분 기다렸다가 sh.status()를 다시 실행해 보면 이전보다 훨씬 많은 정보가 표시됨
    • 컬렉션은 13개의 청크로 분할됐고, 각 청크는 데이터의 서브셋
    • 청크는 샤드 키 범위에 따라 나열됨
    • {"username": minValue} -->> {"username": maxValue}는 각 청크의 범위를 나타내며 샤드 키 값은 항상 $minKey와 $maxKey 사이에 있음
    • 출력의 "on": shard 부분을 보면 청크가 샤드 간에 균등하게 분산됨을 알 수 있음

 

 

 

  • "username"이 샤드 키이기 때문에 특정 사용자 이름에 쿼리를 호출하면 mongos가 쿼리를 올바른 샤드로 직접 라우팅 할 수 있음
    • 샤드 키를 포함하여 단일 샤드나 샤드 서브셋으로 보낼 수 있는 쿼리를 타겟 쿼리라고 지칭

 

 

 

  • 모든 데이터를 찾는 쿼리를 호출하면 두 샤드를 모두 방문하는 것을 확인 가능
    • 일반적으로 쿼리에서 샤드 키를 사용하지 않으면 mongos는 모든 샤드에 쿼리를 보냄
    • 모든 샤드로 보내야 하는 쿼리는 분산-수집 쿼리라고 지칭
    • mongos는 쿼리를 모든 샤드로 분산한 다음 결과를 수집

 

 

 

  • 셋을 종료하기 위해서는 원래 셸로 다시 전환한 뒤 엔터 키를 몇 번 눌러 명령행으로 돌아간 다음 st.stop()을 실행해 모든 서버를 완전히 종료하면 됨

 

> st.stop()

 

참고

몽고DB 완벽 가이드 3판 - 한빛미디어

반응형

'DB > 몽고DB 완벽 가이드 3판' 카테고리의 다른 글

[16장] 샤드 키 선정  (0) 2025.05.16
[15장] 샤딩 구성  (0) 2025.05.16
[13장] 복제 셋 관리  (0) 2025.04.26
[12장] 애플리케이션에서 복제 셋 연결  (0) 2025.04.25
[11장] 복제 셋 구성 요소  (0) 2025.04.24