샤딩된 클러스터에서 롤링 인덱스 빌드
인덱스 빌드는 샤딩된 클러스터 성능에 영향을 줄 수 있습니다. 기본적으로 MongoDB는 모든 데이터가 포함된 복제본 세트 멤버에서 동시에 인덱스를 빌드합니다. 샤딩된 클러스터의 인덱스 빌드는 인덱싱되는 컬렉션의 데이터를 포함하는 샤드에서만 발생합니다. 인덱스 빌드로 인한 성능 저하를 허용할 수 없는 워크로드는 다음 절차를 사용하여 인덱스를 롤링 방식으로 빌드하는 것이 좋습니다.
롤링 인덱스 빌드는 한 번에 하나의 샤드 복제본 세트 멤버만 중단시키며, 세컨더리 멤버부터 시작하여 해당 멤버에서 독립형으로 인덱스를 빌드합니다. 롤링 인덱스 빌드에는 샤드당 하나 이상의 복제본 세트 투표가 필요합니다.
참고
Atlas Atlas 의 인덱스 관리 페이지를 참조하세요.
고려 사항
Unique Indexes
다음 절차를 사용하여 고유 인덱스를 만들려면 이 절차 중에 컬렉션에 대한 모든 쓰기를 중지해야 합니다.
이 절차가 진행되는 동안 컬렉션의 모든 쓰기 작업을 중단할 수 없는 경우, 해당 페이지에 이 절차를 수행하지 않습니다. 대신, 샤딩된 클러스터의 mongos
에서 db.collection.createIndex()
를 실행하여 컬렉션에 고유한 인덱스를 빌드합니다.
Oplog 크기
너무 뒤쳐져 뒤쳐지지 않으면서 인덱싱 또는 재인덱싱 작업을 완료할 수 있을 만큼 Oplog가 충분히 커야 합니다. 자세한 내용은 Oplog 크기 조정 문서를 참조하세요.
전제 조건
- 고유 인덱스 구축용
다음 절차를 사용하여 고유 인덱스를 만들려면 인덱스 빌드 중에 컬렉션에 대한 모든 쓰기를 중지해야 합니다. 그렇지 않으면 복제본 세트 멤버 간에 데이터가 일관되지 않을 수 있습니다. 컬렉션에 대한 모든 쓰기를 중지할 수 없는 경우 다음 절차를 사용하여 고유 인덱스를 생성하지 마세요.
경고
컬렉션에 대한 모든 쓰기를 중지할 수 없는 경우 다음 절차를 사용하여 고유 인덱스를 생성하지 마십시오.
인덱스를 생성하기 전에 컬렉션에 인덱스 제약 조건을 위반하는 문서가 없는지 확인합니다. 만약 컬렉션이 여러 샤드에 분산되어 있고 샤드에 중복 문서가 있는 청크가 포함되어 있는 경우, 중복이 없는 샤드에서는 인덱스 생성 작업이 성공할 수 있지만 중복이 있는 샤드에서는 실패할 수 있습니다. 샤드 간에 일관성 없는 인덱스가 남지 않도록 하려면
mongos
에서db.collection.dropIndex()
실행을 통해 컬렉션에서 인덱스를 제거할 수 있습니다.
절차
중요
순차적으로 인덱스를 빌드하는 다음 절차는 복제본 세트 배포가 아니라 샤딩된 클러스터 배포에 적용됩니다. 복제본 세트 절차에 관한 내용은 대신 복제본 세트에서의 인덱스 빌드 롤링에서 확인하세요.
A. 밸런서 중지
샤딩된 클러스터의 mongosh
(을)를 mongos
인스턴트로 연결하고 sh.stopBalancer()
(을)를 실행해 밸런서 [1](을)를 비활성화합니다.
sh.stopBalancer()
참고
진행 중인 마이그레이션이 있다면, 시스템은 밸런서를 중지하기 전에 진행 중인 마이그레이션을 완료할 것입니다.
밸런서가 비활성화되었는지 확인하려면 sh.getBalancerState()
를 실행하면 밸런서가 비활성화된 경우 false를 반환합니다.
sh.getBalancerState()
[1] | MongoDB에서 시작하기 6.0.3부터 자동 청크 분할이 수행되지 않습니다. 이는 밸런싱 정책 개선 때문입니다. 자동 분할 명령은 여전히 존재하지만 작업을 수행하지 않습니다. MongoDB 6.0.3 이전 버전에서 sh.stopBalancer() 는 샤딩된 클러스터에 대한 자동 분할도 비활성화합니다. |
B. 컬렉션 배포 결정
mongos
에 연결된 mongosh
에서 해당 mongos
의 캐시 라우팅 테이블을 새로 고침하여 컬렉션에 대한 오래된 분산 정보 반환을 방지합니다. 새로 고침이 완료되면 인덱스를 빌드하려는 컬렉션에 대해 db.collection.getShardDistribution()
을 실행합니다.
예를 들어, test
데이터베이스의 records
컬렉션에 대한 오름차순 인덱스를 생성하려는 경우 다음과 같습니다.
db.adminCommand( { flushRouterConfig: "test.records" } ); db.records.getShardDistribution();
이 메서드는 샤드 분포를 출력합니다. 예를 들어 3개의 샤드 shardA
, shardB
, shardC
가 있는 샤딩된 클러스터가 있고 db.collection.getShardDistribution()
이 다음을 반환한다고 가정해 보겠습니다.
Shard shardA at shardA/s1-mongo1.example.net:27018,s1-mongo2.example.net:27018,s1-mongo3.example.net:27018 data : 1KiB docs : 50 chunks : 1 estimated data per chunk : 1KiB estimated docs per chunk : 50 Shard shardC at shardC/s3-mongo1.example.net:27018,s3-mongo2.example.net:27018,s3-mongo3.example.net:27018 data : 1KiB docs : 50 chunks : 1 estimated data per chunk : 1KiB estimated docs per chunk : 50 Totals data : 3KiB docs : 100 chunks : 2 Shard shardA contains 50% data, 50% docs in cluster, avg obj size on shard : 40B Shard shardC contains 50% data, 50% docs in cluster, avg obj size on shard : 40B
출력에서는 shardA
및 shardC
에 test.records
에 대한 인덱스만 빌드합니다.
C. 컬렉션 청크가 포함된 샤드에 인덱스 빌드
컬렉션을 위해 청크가 포함된 각 샤드의 경우, 샤드에 인덱스를 빌드하는 절차를 따라야 합니다.
C1. 세컨더리 장치 하나를 중지하고 독립형으로 재시작
영향을 받는 샤드의 경우, 세컨더리 중 하나와 관련된 mongod
프로세스를 중지합니다. 다음 구성을 업데이트한 후 다시 시작합니다.
구성 파일을 사용하는 경우 다음 구성 업데이트를 수행합니다.
replication.replSetName
옵션을 코멘트합니다.sharding.clusterRole
옵션을 코멘트합니다.setParameter
섹션에서 매개변수skipShardingConfigurationChecks
을(를)true
(으)로 설정합니다.setParameter
섹션에서 파라미터disableLogicalSessionCacheRefresh
를true
로 설정합니다.
예를 들어, 샤드 복제본 세트 노드의 경우 업데이트된 구성 파일에는 다음 예와 같은 콘텐츠가 포함됩니다.
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27218 # port: 27018 #replication: # replSetName: shardA #sharding: # clusterRole: shardsvr setParameter: skipShardingConfigurationChecks: true disableLogicalSessionCacheRefresh: true
그리고 다시 시작합니다:
mongod --config <path/To/ConfigFile>
기타 설정 (예: storage.dbPath
등)은 동일하게 유지합니다.
명령줄 옵션을 사용하는 경우 다음과 같이 구성을 업데이트합니다.
샤드 멤버인 경우
--shardsvr
를 제거하고 config 서버 멤버인 경우--configsvr
를 제거합니다.옵션에서 매개 변수
skipShardingConfigurationChecks
를true
--setParameter
로 설정합니다.--setParameter
옵션에서 매개 변수disableLogicalSessionCacheRefresh
를true
로 설정합니다.
예를 들어, --replSet
및 --shardsvr
옵션 없이 샤드 복제본 세트 멤버를 다시 시작합니다. 새 포트 번호를 지정하고 skipShardingConfigurationChecks
및 disableLogicalSessionCacheRefresh
매개변수를 모두 true로 설정합니다.
mongod --port 27218 --setParameter skipShardingConfigurationChecks=true --setParameter disableLogicalSessionCacheRefresh=true
기타 설정 (예: --dbpath
등)은 동일하게 유지합니다.
[2] | (1, 2) 다른 포트에서 mongod 를 실행하면 인덱스를 구축하는 동안 복제본 세트의 다른 구성원과 모든 클라이언트가 해당 구성원과 접촉하지 않도록 합니다. |
C2. 인덱스 빌드
새 포트에서 독립 실행형으로 실행 중인 mongod
인스턴스에 직접 연결하고 이 인스턴스에 대한 새 인덱스를 만듭니다.
예를 들어 mongosh
를 인스턴스에 연결하고, db.collection.createIndex()
메서드를 사용하여 records
컬렉션의 username
필드에 오름차순 인덱스를 생성합니다.
db.records.createIndex( { username: 1 } )
C3.mongod
복제본 세트 멤버로 프로그램 다시 시작
인덱스 빌드가 완료되면 mongod
인스턴스를 종료합니다. 독립형으로 시작할 때의 구성 변경 사항을 실행 취소하여 원래 구성으로 돌아가 다시 시작합니다.
중요
skipShardingConfigurationChecks
매개 변수와 disableLogicalSessionCacheRefresh
매개 변수를 제거해야 합니다.
예를 들어, 복제본 세트 샤드 멤버를 다시 시작하려면 다음을 수행합니다.
구성 파일을 사용하는 경우:
원래 포트 번호로 되돌립니다.
replication.replSetName
코멘트를 삭제합니다.sharding.clusterRole
코멘트를 삭제합니다.setParameter
섹션에서 매개변수skipShardingConfigurationChecks
을(를) 제거합니다.setParameter
섹션에서 매개변수disableLogicalSessionCacheRefresh
를 제거합니다.
net: bindIp: localhost,<hostname(s)|ip address(es)> port: 27018 replication: replSetName: shardA sharding: clusterRole: shardsvr
기타 설정 (예: storage.dbPath
등)은 동일하게 유지합니다.
그리고 다시 시작합니다:
mongod --config <path/To/ConfigFile>
명령줄 옵션을 사용하는 경우:
원래 포트 번호로 되돌립니다.
--replSet
을(를) 포함합니다.샤드 멤버인 경우
--shardsvr
을(를) 포함하고 Config 서버 멤버인 경우--configsvr
을(를) 포함합니다.Remove parameter
skipShardingConfigurationChecks
.Remove parameter
disableLogicalSessionCacheRefresh
.
예를 들면 다음과 같습니다.
mongod --port 27018 --replSet shardA --shardsvr
기타 설정 (예: --dbpath
등)은 동일하게 유지합니다.
복제가 이 멤버를 따라잡을 수 있도록 허용합니다.
C4. 샤드의 나머지 세컨더리에 대한 절차 반복
멤버가 세트의 다른 멤버를 따라잡으면 샤드의 나머지 세컨더리 멤버에 대해 한 번에 한 멤버씩 절차를 반복합니다.
C5. 프라이머리에서 인덱스 빌드
샤드의 모든 세컨더리에 새 인덱스가 있으면 샤드의 프라이머리를 강등하고 위에서 설명한 절차에 따라 독립형으로 다시 시작한 다음 이전 프라이머리에 인덱스를 빌드합니다.
rs.stepDown()
에서mongosh
메서드를 사용하여 기본값을 내릴 수 있습니다. 단계적 하향에 성공하면 현재 프라이머리이 세컨더리가 되고 복제 세트 구성원은 새 프라이머리를 선택합니다.
D. 영향을 받은 다른 샤드에 대해 반복
샤드에 대한 인덱스 빌드를 완료하면 영향을 받는 다른 샤드에 대해 C. 컬렉션 청크가 포함된 샤드에 인덱스 빌드를 반복합니다.
E. 밸런서 재시작
영향을 받는 샤드에 대한 롤링 인덱스 빌드가 완료되면 밸런서를 다시 시작합니다.
mongosh
를 샤딩된 클러스터의 mongos
인스턴스에 연결하고 sh.startBalancer()
: [3]를 실행합니다.
sh.startBalancer()
[3] | MongoDB 6.0.3부터는 밸런싱 정책의 개선으로 인해 자동 청크 분할이 수행되지 않습니다. 자동 분할 명령은 여전히 존재하지만 작업을 수행하지는 않습니다. MongoDB 6.0.3 이전 버전에서 sh.startBalancer() 는 샤딩된 클러스터에 대한 자동 분할도 활성화합니다. |
추가 정보
샤드된 컬렉션이 일관성 없는 인덱스를 가지게 되는 경우는 컬렉션에 대한 청크를 포함하는 각 샤드에 정확히 동일한 인덱스(인덱스 옵션 포함)가 없을 때입니다. 일반 작업 중에는 일관성 없는 인덱스가 발생하지 않아야 하지만,
예를 들어 사용자가
unique
키 제약 조건을 사용하여 인덱스를 생성 중이고 하나의 샤드에 중복 문서가 있는 청크가 포함되어 있는 경우와 같이 일관성 없는 인덱스가 발생할 수 있습니다. 이러한 경우 인덱스 생성 작업은 중복이 없는 샤드에서는 성공할 수 있지만 중복이 있는 샤드에서는 실패할 수 있습니다.사용자가 여러 샤드에 걸쳐 인덱스를 롤링 방식으로 생성하고 있지만 연결된 샤드에 대한 인덱스를 빌드하지 못하거나 다른 사양으로 인덱스를 잘못 빌드하는 경우입니다.
config 서버 프라이머리는 주기적으로 샤딩된 컬렉션의 샤드 간 인덱스 불일치가 있는지 확인합니다. 이러한 주기적 검사를 구성하려면 enableShardedIndexConsistencyCheck
및 shardedIndexConsistencyCheckIntervalMS
를 참조하세요.
serverStatus
명령은 config 서버 프라이머리에서 실행될 때 인덱스 불일치를 보고하기 위해 shardedIndexConsistency
필드를 반환합니다.
샤드 컬렉션에 인덱스가 일관되지 않은지 확인하려면 샤드에서 일관되지 않은 인덱스 찾기를 참조하세요.