mongodb "schema" 생산 변화 처리 방법
mongodb + node.js + mongoose.js ORM 백엔드를 사용합니다.
_id 필드가 없는 개체의 중첩 배열이 있다고 가정합니다.
mongoose.Schema({
nested: [{
_id: false, prop: 'string'
}]
})
그런 다음 _id 필드를 모든 중첩된 객체 d에 추가하여 몽구스 스키마가
mongoose.Schema({
nested: [{
prop: 'string'
}]
})
그럼 제가 프로덕션 DB를 수정하기 위해 스크립트를 실행해야 하는 거죠?이러한 변화를 처리하는 가장 좋은 방법은 무엇입니까?변경사항을 구현하기 위해 어떤 툴(또는 접근 방식)을 사용하는 것이 가장 좋습니까?
스키마가 없는 데이터베이스의 중요한 이점 중 하나는 새 스키마 레이아웃으로 전체 데이터베이스를 업데이트할 필요가 없다는 것입니다.DB에 있는 문서 중 일부에 특정 정보가 없는 경우 코드가 대신 적절한 작업을 수행하거나 해당 레코드로 작업을 수행하도록 선택할 수 있습니다.
또 다른 선택사항은 문서를 다시 볼 때만 필요에 따라 게으르게 업데이트하는 것입니다.이 경우 레코드별/문서 버전 플래그를 선택할 수 있습니다. 이 플래그는 처음에는 나타나지 않을 수도 있습니다(따라서 '버전 0'을 나타냅니다).하지만 그것조차도 선택 사항입니다.대신 데이터베이스 액세스 코드는 필요한 데이터를 찾고, 코드 업데이트 후 추가된 새로운 정보이기 때문에 존재하지 않는 경우 최대한 결과를 입력합니다.
를 들어, 를들어, 환변 _id:false
표으로로MongoId
때 후에 쓸 때), 필드, 또가읽때 (힐는업후다때쓰질여시고에트그리이데코드또,▁field그리), 고▁the,▁the_id:false
가 현재 설정되어 있습니다. 그런 다음 반드시 필요한 경우에만 변경하고 기록합니다.
컬렉션을 검토하고 각 문서에 새 필드를 추가할 스크립트를 작성해야 합니다.정확한 방법은 DB의 크기와 스토리지 시스템의 성능에 따라 달라집니다.문서에 필드를 추가하면 크기가 변경되어 대부분의 경우 재배치됩니다.이 작업은 IO에 영향을 미치며 IO에 의해 제한됩니다.컬렉션이 몇 천 개의 문서에 불과하거나 최대 10만 개에 불과할 경우 전체 컬렉션이 메모리에 저장되고 이후에 모든 IO가 발생하기 때문에 한 번의 루프에서 반복할 수 있습니다.그러나 수집이 사용 가능한 메모리를 훨씬 초과하는 경우 접근 방식이 더 복잡해집니다.우리는 보통 MongoDB의 프로덕션 사용에서 다음 단계를 따릅니다.
- 시간 초과로 커서 열기=False
- 문서 덩어리를 메모리로 읽기
- 이 문서에 대한 업데이트 쿼리 실행
- IO 하위 시스템의 과부하 및 운영 애플리케이션의 손상을 방지하기 위해 잠시 동안 절전 모드로 전환
- 완료될 때까지 반복
- 커서를 닫습니다 :)
문서 청크의 크기와 절전 기간을 실험적으로 결정해야 합니다.일반적으로 마이그레이션 기간 동안 mongostats에서 QR/QW를 사용하지 않습니다.느린 드라이브(Amazon의 EBS와 같은)의 대규모 수집의 경우, 이 IO 안전 접근 방식은 몇 시간에서 며칠까지 걸릴 수 있습니다.
@Michael Korbakov 대답을 확장하면서, 나는 그의 단계를 실행했습니다.mongo
셸 스크립트(MongoDB 참조 매뉴얼 참조 정보)mongo
셸 스크립트).
중요: MongoDB 참조 매뉴얼에 명시된 대로 스크립트 실행mongo
셸은 각 배치 가져오기 및 대량 실행에 대한 연결 지연 시간을 줄이기 때문에 성능에 도움이 될 수 있습니다.
고려해야 할 단점은mongo
셸 명령은 항상 동기화되지만 대량 실행은 이미 각 청크에 대한 병렬 처리를 수행하므로 이 사용 사례에 적합합니다.
코드:
// constants
var sourceDbName = 'sourceDb';
var sourceCollectionName = 'sourceColl';
var destDbName = 'destdb';
var destCollectionName = 'destColl';
var bulkWriteChunckSize = 1000;
// for fetching, I figured 1000 for current bulkWrite, and +1000 ready for next bulkWrite
var batchSize = 2000;
var sourceDb = db.getSiblingDB(sourceDbName);
var destDb = db.getSiblingDB(destDbName);
var start = new Date();
var cursor = sourceDb[sourceCollectionName].find({}).noCursorTimeout().batchSize(batchSize);
var currChunkSize = 0;
var bulk = destDb[destCollectionName].initializeUnorderedBulkOp();
cursor.forEach(function(doc) {
currChunkSize++;
bulk.insert({
...doc,
newProperty: 'hello!',
}); // can be changed for your need, if you want update instead
if (currChunkSize === bulkWriteChunckSize) {
bulk.execute();
// each bulk.execute took for me 130ms, so i figured to wait the same time as well
sleep(130);
currChunkSize = 0;
bulk = destDb[destCollectionName].initializeUnorderedBulkOp();
}
});
if (currChunkSize > 0) {
bulk.execute();
currChunkSize = 0;
}
var end = new Date();
print(end - start);
cursor.close();
언급URL : https://stackoverflow.com/questions/14290568/how-to-handle-mongodb-schema-change-in-production
'programing' 카테고리의 다른 글
R에서 print()로 새 줄 인쇄 (0) | 2023.06.28 |
---|---|
SQL Server에서 VARCHAR에서 숫자가 아닌 문자를 가장 빨리 제거하는 방법 (0) | 2023.06.28 |
스프링 부트 테스트: 모든 테스트에 대해 컨텍스트가 로드됩니까? (0) | 2023.06.28 |
데이터셋과 데이터 리더 중 어느 것이 더 좋습니까? (0) | 2023.06.28 |
UISwip 제스처 인식기의 방향 설정 (0) | 2023.06.28 |