효율적인 샤딩 및 MongoDB 클러스터 스케일링을 위한 모범 사례
더 나은 MongoDB 샤드 키를 선택하고, 밸런싱을 모니터링하며, 불필요한 스캐터-게더 작업을 피하는 쿼리를 설계하세요.
MongoDB 클러스터의 효율적인 샤딩 및 확장을 위한 모범 사례
MongoDB 샤딩은 컬렉션을 여러 샤드에 분산시켜 하나의 복제 세트가 모든 데이터나 트래픽을 감당하지 않도록 합니다. 이는 실제 확장 문제를 해결할 수 있지만, 잘못된 샤드 키는 핫 샤드, 느린 스캐터-게더 쿼리, 그리고 되돌리기 어려운 운영 작업을 초래할 수 있습니다.
인덱스, 스키마 설계, 하드웨어 크기 조정, 쿼리 튜닝과 같은 기본 사항을 이미 처리한 후에 단일 복제 세트가 데이터 크기, 쓰기 처리량 또는 읽기 작업 부하를 더 이상 처리할 수 없을 때 샤딩을 사용하세요.
샤드 클러스터의 핵심 구성 요소 이해
기능적인 샤드 클러스터는 여러 상호 연결된 구성 요소가 함께 작동해야 합니다:
- 샤드 (샤드 복제 세트): 각 샤드는 일반적으로 전체 데이터 세트의 하위 집합을 보유하는 복제 세트입니다. 데이터는 이러한 샤드에 걸쳐 분할됩니다.
- 쿼리 라우터 (Mongos 프로세스): 이 프로세스는 클라이언트 요청을 수신하고, 필요한 데이터가 있는 샤드를 결정하며(메타데이터 기반), 쿼리를 라우팅하고, 결과를 집계하여 클라이언트에 반환합니다. 상태 비저장이며 확장성이 뛰어납니다.
- 구성 서버 (Config 서버): 이 전용 복제 세트는 특정 데이터 청크가 어디에 있는지
mongos프로세스에 알려주는 메타데이터(클러스터 맵)를 저장합니다. 클러스터 운영에 중요하며 항상 고가용성을 유지해야 합니다.
주요 전략 1: 최적의 샤드 키 선택
샤드 키는 샤딩에서 가장 중요한 결정입니다. 이는 데이터가 샤드 간에 어떻게 분할되는지를 결정합니다. 잘 선택된 샤드 키는 균일한 데이터 분포와 효율적인 쿼리 라우팅을 이끌어내는 반면, 잘못된 키는 핫스팟과 불균형한 클러스터를 초래합니다.
효과적인 샤드 키의 특성
이상적인 샤드 키는 세 가지 주요 특성을 가져야 합니다:
- 높은 카디널리티: 키는 세분화된 파티셔닝을 허용하기 위해 많은 고유 값을 가져야 합니다. 낮은 카디널리티는 전체적으로 더 적은 청크를 초래합니다.
- 높은 쓰기 빈도/균일한 분포: 쓰기는 단일 샤드가 과부하되는 것(핫스팟)을 방지하기 위해 모든 샤드 키 값에 걸쳐 균등하게 분산되어야 합니다.
- 쿼리 패턴: 쿼리는 이상적으로 샤드 키를 대상으로 하여 타겟팅된 쿼리(특정 샤드로 라우팅)를 가능하게 해야 합니다. 모든 샤드를 스캔해야 하는 쿼리(스캐터-게더 쿼리)는 훨씬 느립니다.
샤딩 방법 및 그 영향
MongoDB는 두 가지 주요 샤딩 방법을 지원합니다:
- 해시 샤딩: 샤드 키 값에 해시 함수를 사용합니다. 이는 순차적인 키에도 모든 사용 가능한 샤드에 쓰기를 분산시켜 우수한 데이터 분포를 보장합니다. 쿼리 지역성이 덜 중요한 높은 쓰기 처리량에 가장 적합합니다.
- 범위 기반 샤딩: 샤드 키의 범위를 기준으로 데이터를 분할합니다(예: ID가 1-1000인 모든 사용자는 샤드 A로 이동). 쿼리 패턴이 범위 조회(예: 날짜 범위 또는 알파벳순 ID 범위로 쿼리)와 일치할 때 가장 적합합니다.
⚠️ 범위 기반 샤딩에 대한 경고: 데이터 삽입 패턴이 엄격하게 증가하는 순서(타임스탬프나 자동 증가 ID와 같은)를 따르는 경우, 범위 기반 샤딩은 모든 쓰기가 가장 최신 청크에 집중되어 마지막 샤드에 심각한 핫스팟이 발생합니다.
예시: 해시 샤딩 적용
userId와 같은 필드를 선택하고 쿼리가 자주 이 필드로 필터링하는 경우, 해싱하면 쓰기가 균등하게 분산됩니다:
// 데이터베이스 및 컬렉션 선택
use myAppDB
// 샤딩을 위해 userId 필드 해싱
sh.shardCollection("myAppDB.users", { "userId": "hashed" })
주요 전략 2: 데이터 분포 및 밸런싱 관리
완벽한 샤드 키를 사용하더라도, 진화하는 쿼리 패턴이나 초기 로드 불균형으로 인해 데이터 청크(샤드에 저장된 데이터의 물리적 단위)의 크기나 분포가 고르지 않을 수 있습니다. 밸런서 프로세스는 이러한 청크의 마이그레이션을 처리합니다.
밸런서 모니터링
클러스터의 균형 메트릭을 모니터링하는 것이 중요합니다. 불균형한 청크는 일부 샤드에서 리소스가 과소 활용되고 다른 샤드는 과부하되는 결과를 초래합니다.
쉘 내에서 sh.status() 명령을 사용하여 마이그레이션 중인 청크를 포함한 전체 상태를 확인하세요.
밸런서 제어
밸런서는 자동으로 실행되지만, 리소스 소비를 제어하기 위해 유지 관리 시간이나 대규모 배치 가져오기 중에 일시적으로 비활성화할 수 있습니다:
// 현재 상태 확인
sh.getBalancerState()
// 밸런싱 일시 중지
sh.stopBalancer()
// ... 유지 관리 또는 대규모 가져오기 수행 ...
// 완료되면 밸런싱 재시작
sh.startBalancer()
모범 사례: 밸런서를 영구적으로 비활성화하지 마세요. 비활성화하는 경우, 애플리케이션이 성장함에 따라 데이터가 균등하게 분포되도록 정기적인 검토를 예약하세요.
청크 크기 고려 사항
청크가 너무 작으면 과도한 메타데이터 오버헤드가 발생하고 밸런서 속도가 느려집니다. 반대로 청크가 너무 크면 마이그레이션이 느리고 로드 밸런싱 기회가 줄어듭니다.
- 기본 청크 크기: MongoDB의 기본 청크 크기는 일반적으로 많은 클러스터에 적합합니다. 변경하기 전에 MongoDB 버전의 문서를 확인하세요.
- 청크 크기 조정: 마이그레이션이 너무 오래 걸리거나 메타데이터 오버헤드가 과도해지는 등 명확한 운영상의 이유가 있을 때만 청크 크기를 변경하세요. 지원되는 방법은 MongoDB 릴리스에 따라 변경되었으므로, 적용하기 전에 현재 버전의 명령을 확인하세요.
주요 전략 3: 읽기 및 쓰기 성능 최적화
샤딩은 읽기와 쓰기가 라우팅되는 방식을 변경하므로 특정 성능 튜닝이 필요합니다.
타겟팅된 쿼리 vs. 스캐터-게더 쿼리
- 타겟팅된 쿼리: 샤드 키(또는 범위 샤딩을 사용하는 경우 샤드 키의 접두사)를 포함하는 쿼리는
mongos라우터가 요청을 하나 또는 몇 개의 샤드로 직접 보낼 수 있습니다. 이러한 쿼리는 빠릅니다. - 스캐터-게더 쿼리: 샤드 키를 사용하지 않는 쿼리는 모든 샤드로 전송되어 네트워크 지연 시간과 처리 오버헤드가 증가합니다.
실행 가능한 팁: 가능할 때마다 샤드 키를 활용하도록 애플리케이션 쿼리를 설계하세요. 광범위하게 스캔해야 하는 쿼리의 경우, 프라이머리 멤버로부터 부하를 분리하기 위해 복제 세트의 세컨더리 멤버를 선호하는 읽기 설정을 사용하는 것을 고려하세요.
샤드 클러스터에서의 읽기 설정
샤드 클러스터는 클라이언트 수준에서 읽기 설정을 처리합니다. 작업의 중요성에 따라 애플리케이션 코드가 올바르게 읽기 설정을 지정하는지 확인하세요:
primary(기본값): 각 샤드 복제 세트의 프라이머리로 읽기가 전송됩니다.nearest: 지리적 또는 네트워크상 애플리케이션에 가장 가까운 복제 세트 멤버로 읽기가 전송됩니다.secondaryPreferred: 세컨더리를 사용할 수 없는 경우가 아니면 읽기가 세컨더리로 전송되며, 이는 프라이머리에서 보고 또는 분석 쿼리를 오프로드하는 데 유용합니다.
인덱싱 함정 피하기
쿼리 필터나 정렬 작업에 자주 사용되는 필드, 특히 샤드 키와 샤드 키의 접두사 필드에 인덱스가 존재하는지 확인하세요. 샤드 간 인덱스가 일관되지 않으면 한 샤드가 인덱스를 사용할 수 없어 예상치 못한 스캐터-게더 쿼리가 발생할 수 있습니다.
안정성을 위한 운영 모범 사례
안정적이고 고성능의 샤드 클러스터를 유지하려면 지속적인 운영 경계가 필요합니다.
1. 샤드 키 변경
샤드 키는 변경하는 데 비용이 많이 들 것처럼 선택하세요. 일반적으로 그렇기 때문입니다. 최신 MongoDB 버전은 이전 버전보다 더 많은 샤드 키 개선 및 일부 샤드 키 값 업데이트를 지원하지만, 규칙은 버전, 키 패턴 및 트랜잭션 요구 사항에 따라 다릅니다. 프로덕션 트래픽이 시작된 후 쉬운 재작성을 기대하지 마세요.
2. 구성 서버 복원력
구성 서버는 클러스터의 두뇌입니다. 사용할 수 없게 되면 클라이언트는 데이터가 어디에 있는지 확인할 수 없어 운영이 사실상 중단됩니다.
- 항상 구성 서버를 복제 세트(최소 3개 멤버)로 배포하세요.
- 구성 서버에 빠른 스토리지를 사용하고 애플리케이션 작업 부하를 부담하지 않도록 하세요.
3. 용량 계획
개별 샤드 멤버의 CPU, 메모리, 디스크 I/O, 스토리지 증가, 복제 지연 및 청크 분포를 모니터링하여 성장을 계획하세요. 하나의 고정된 사용률 백분율에 의존하기보다는 하나의 샤드가 병목 현상이 되기 전에 용량을 추가하세요.
핵심 요점
MongoDB의 샤딩은 데이터 모델링을 우회하는 지름길이 아닌 확장 도구입니다. 쓰기를 분산시키고 가장 중요한 쿼리와 일치하는 샤드 키를 선택하고, 출시 후 밸런싱을 모니터링하며, 가능할 때마다 애플리케이션 쿼리를 타겟팅된 상태로 유지하세요.