이상적인 샤드 키 사용하면 MongoDB 클러스터 전체에 문서를 고르게 분산하는 동시에 일반적인 쿼리 패턴을 용이하게 할 수 있습니다. 샤드 키 최적화되지 않으면 고르지 않은 데이터 분산으로 인해 성능 또는 확장 문제를 일으킬 수 있습니다. 컬렉션 의 샤드 키 변경하여 클러스터 전체의 데이터 분포를 변경할 수 있습니다.
MongoDB 8.0부터는 동일한 샤드 키 에서 컬렉션 리샤딩할 수 있으므로 샤드 키 변경하지 않고도 새 샤드를 포함하거나 다른 구역에 데이터를 재배포할 수 있습니다. 동일한 샤드 키 리샤딩하려면 forceRedistribution 을 true로 설정하다 .
MongoDB 8.0.10부터는 time series 컬렉션 리샤딩할 수 있습니다. time series 컬렉션 의 모든 샤드는 리샤딩하려면 버전 8.0.10 이상 실행 해야 합니다.
참고
컬렉션을 리샤딩하기 전에 샤드 키 문제 해결을 읽고 일반적인 성능 및 확장성 문제에 대한 정보와 해결 방법에 대한 조언을 확인하세요.
이 작업에 대하여
한 번에 하나의 컬렉션만 리샤딩할 수 있습니다.
writeConcernMajorityJournalDefault은(는)true이어야 합니다.고유성 제약 조건이 있는 컬렉션을 리샤드하려면 새 샤드 키가 기존의 모든 고유 인덱스에 대한 고유 인덱스 요구 사항을 충족해야 합니다.
리샤딩 작업이 진행 중인 동안 리샤딩되는 컬렉션에서는 다음 명령 및 해당 셸 메서드가 지원되지 않습니다.
다음 작업 중 하나를 실행 하면 작업이 실행되기 전에 리샤딩이 완료될 때까지 대기합니다.
dropDatabase리샤딩 중인 컬렉션 호스팅하는 데이터베이스 에서
리샤딩하려는 컬렉션이 MongoDB Search를 사용하는 경우, 리샤딩 작업이 완료되면 검색 인덱스 사용할 수 없게 됩니다. 리샤딩 작업이 완료되면 검색 인덱스 수동으로 다시 작성해야 합니다.
리샤딩하려는 컬렉션 Atlas Online Archives에 보관되는 경우, 리샤딩 작업이 완료되면 온라인 아카이브 파일이
Orphaned로 표시됩니다.Active상태 의 동일한 조합에 대한 다른 아카이브가 없는 한 고아 아카이브와 동일한 데이터베이스, 컬렉션 및 필드에 대해 다른 온라인 아카이브를 생성할 수 있습니다.
시작하기 전에
컬렉션 리샤딩을 시작하기 전에 다음 요구 사항을 충족하는지 확인하세요.
애플리케이션 은 영향을 받는 컬렉션 이 쓰기를 차단하는 2초의 기간을 허용할 수 있습니다. 쓰기가 차단되는 기간 동안 애플리케이션 의 지연 시간 이 증가합니다.
워크로드가 이러한 요구 사항을 수용할 수 없는 경우에는 대신 샤드 키를 개선하는 것이 좋습니다.
데이터베이스는 다음과 같은 리소스 요구 사항을 충족합니다.
각 수신자 샤드 의 사용 가능한 저장 공간이 리샤딩하려는 컬렉션 의 저장 크기에 총 인덱스 크기를 더한 값을 샤드 수로 나눈 값의 두 배 이상이어야 합니다.
( ( collection_storage_size + index_size ) * 2 ) / shard_count = storage_req 예시 를 들어, 저장 크기가 2 TB 데이터이고 인덱스 400 GB 인 컬렉션 생각해 보겠습니다. 4개의 샤드에 분산하려면 다음이 필요합니다.
( ( 2 TB collection + 0.4 TB index ) * 2 ) / 4 shards = 1.2 TB storage 이 컬렉션 리샤딩하려면 각 샤드 1.2 이(가) 필요합니다. TB의 사용 가능한 저장.
MongoDB Atlas 에서 리샤딩 작업을 위해 다음 저장 계층 으로 업그레이드 해야 할 수도 있습니다. 작업이 완료되면 다운그레이드할 수 있습니다.
I/O 용량 이 50% 미만인지 확인합니다.
CPU 로드가 80% 미만인지 확인합니다.
중요
이러한 요구 사항은 데이터베이스에 의해 적용되지 않습니다. 충분한 리소스를 할당하지 못하면 다음과 같은 결과가 발생할 수 있습니다.
데이터베이스 공간이 부족하여 종료되는 경우
성능 저하
작업이 예상보다 오래 걸리는 경우
애플리케이션 에 트래픽이 적은 기간이 있는 경우 가능하면 해당 기간 동안 컬렉션 에 대해 이 작업을 수행합니다.
리샤딩하기 전에 새 샤드 키 에 인덱스 생성할 필요가 없습니다. 리샤딩 작업은 인덱스 단계에서 필요한 인덱스를 자동으로 빌드합니다.
진행 중인 인덱스 빌드가 없습니다. 실행 인덱스 빌드를 확인하려면
$currentOp을 사용합니다.db.getSiblingDB("admin").aggregate( [ { $currentOp : { idleConnections: true } }, { $match: { $or: [ { "op": "command", "command.createIndexes": { $exists: true } }, { "op": "none", "msg": /^Index Build/ } ] } } ] ) 결과 문서에서
inprog필드 값이 빈 배열이면 진행 중인 인덱스 빌드는 없습니다.{ inprog: [], ok: 1, '$clusterTime': { ... }, operationTime: <timestamp> }
참고
리샤딩 작업은 증가된 oplog 비율을 생성할 수 있는 쓰기 집약적인 프로세스 입니다. 다음을 수행할 수 있습니다.
고정된 oplog 크기를 설정하여 무한한 oplog 증가를 방지합니다.
하나 이상의 세컨더리 노드가 오래된 상태가 될 가능성을 최소화하기 위해 oplog 크기를 늘립니다.
자세한 내용은 복제본 세트 Oplog 문서를 참조하세요.
2단계 쓰기 프로토콜
쿼리 필터에 전체 샤드 키가 포함되지 않는 쿼리에는 2단계 쓰기 (write) 프로토콜이 필요할 수 있습니다. 이 프로토콜은 쿼리를 여러 샤드에 부로드캐스트하고 성능을 상당히 저하시킬 수 있습니다.
새 샤드 키 대신 이전 샤드 키 제공하는 쿼리는 2단계 쓰기 (write) 프로토콜 사용합니다.
deleteOne()메서드는 쿼리 필터가 전체 샤드 키 또는_id필드를 사용하지 않을 경우 2단계 쓰기 (write) 프로토콜을 사용합니다.replaceOne()및updateOne()메서드:쿼리 전체 샤드 키 제공하는 경우 2단계 프로토콜 사용되지 않습니다.
쿼리에서 전체 샤드 키를 제공하지 않고
_id필드를 제공하는 경우, 2단계 쓰기 (write) 프로토콜의 사용은upsert의 값에 따라 다라집니다.upsert이true으로 설정되면 2상 쓰기 (write) 프로토콜이 사용됩니다.upsert이false인 경우, 2단계 쓰기 (write) 프로토콜은 사용되지 않습니다.쿼리가 전체 샤드 키도
_id필드도 제공하지 않는 경우, 2단계 쓰기 (write) 프로토콜이 항상 사용됩니다.
다음 메서드는 쿼리 필터하다 전체 샤드 키 사용하지 않는 경우 2단계 쓰기 (write) 프로토콜 사용합니다.
최적의 성능을 위해 리샤딩 작업이 완료된 후 이러한 작업에 대한 쿼리 필터에서 새 샤드 키를 사용하도록 애플리케이션을 업데이트하세요.
단계
컬렉션 리샤딩 작업에서 샤드는 다음과 같을 수 있습니다.
기증자는 현재 샤딩된 컬렉션의 청크를 저장합니다.
샤드는 기증자와 수신자가 동시에 될 수 있습니다.
config 서버 프라이머리는 항상 리샤딩 코디네이터이며 리샤딩 작업의 각 단계를 시작합니다.
밸런서 비활성화
컬렉션 리샤딩 프로세스 시작하기 전에 밸런서 꺼야 합니다. 밸런서 비활성화하려면 여기를 참조하세요.
리샤딩 작업을 시작합니다.
mongos에 연결된 동안 리샤딩할 컬렉션과 새 샤드 키를 지정하는 reshardCollection 명령을 실행합니다.
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey> })
MongoDB는 쓰기를 차단하는 최대 시간(초)을 2초로 설정하고 리샤딩 작업을 시작합니다.
동일한 샤드 키 리샤딩하려면 forceRedistribution 을 true로 설정하다 .
db.adminCommand({ reshardCollection: "<database>.<collection>", key: <shardkey>, forceRedistribution: true })
sh.reshardCollection() 를 사용하여 동일한 키로 컬렉션 리샤딩할 수도 있습니다. 예시는 새 샤드에 데이터 재배포를 참조하세요.
리샤딩 작업을 모니터링합니다.
리샤딩 작업을 모니터링하려면 $currentOp 파이프라인 단계를 사용할 수 있습니다.
db.getSiblingDB("admin").aggregate([ { $currentOp: { allUsers: true, localOps: false } }, { $match: { type: "op", "originatingCommand.reshardCollection": "<database>.<collection>" } } ])
참고
업데이트된 값을 확인하려면 이전 파이프라인을 계속 실행해야 합니다.
$currentOp 파이프라인은 다음을 출력합니다.
totalOperationTimeElapsedSecs: 경과된 작업 시간(초)remainingOperationTimeEstimatedSecs: 현재 리샤딩 작업에 남은 예상 시간(초)입니다. 새로운 리샤딩 작업이 시작되면-1(으)로 반환됩니다.MongoDB 7.0부터 리샤딩 작업 중에 코디네이터에서
remainingOperationTimeEstimatedSecs를 사용할 수도 있습니다.remainingOperationTimeEstimatedSecs비관치 추정으로 설정됩니다.따라잡기 단계 시간 추정은 상대적으로 긴 시간인 클론 단계 시간으로 설정됩니다.
실제로 보류 중인 쓰기 작업이 적은 경우 실제 따라잡기 단계 시간은 상대적으로 짧습니다.
[ { shard: '<shard>', type: 'op', desc: 'ReshardingRecipientService | ReshardingDonorService | ReshardingCoordinatorService <reshardingUUID>', op: 'command', ns: '<database>.<collection>', originatingCommand: { reshardCollection: '<database>.<collection>', key: <shardkey>, unique: <boolean>, collation: { locale: 'simple' } }, totalOperationTimeElapsedSecs: <number>, remainingOperationTimeEstimatedSecs: <number>, ... }, ... ]
행동
리샤딩 작업의 최소 지속 시간
리샤딩 작업의 최소 기간은 항상 5분입니다.
재시도 가능한 쓰기
리샤딩 이전이나 도중에 시작된 재시도 가능 쓰기는 컬렉션이 리샤딩되는 동안과 이후에 최대 5분 동안 재시도될 수 있습니다. 5분 후에 쓰기의 최종 결과를 찾지 못할 수 있으며 이후 쓰기 재시도가 IncompleteTransactionHistory 오류와 함께 실패할 수 있습니다.
리샤드 제한
컬렉션 Atlas Search 사용하는 경우 작업이 완료된 후 검색 인덱스 사용할 수 없게 됩니다. 복원 하려면 검색 인덱스 수동으로 다시 작성합니다.
Queryable Encryption 사용하는 컬렉션은 지원되지 않습니다.
오류 사례
Duplicate _id Values
컬렉션 데이터 손상을 방지하기 위해 _id 값이 전체적으로 고유하지 않으면 리샤딩 작업이 실패합니다. 중복 _id 값은 성공적인 청크 마이그레이션을 방해할 수도 있습니다. 중복 _id 값이 있는 문서가 있는 경우 각 문서의 데이터를 새 문서로 복사한 다음 중복 문서를 삭제하십시오.