운영 요인 및 데이터 모델
MongoDB용 애플리케이션 데이터를 모델링할 때는 MongoDB의 성능에 영향을 미치는 다양한 운영 요인을 고려해야 합니다. 예를 들어, 서로 다른 데이터 모델을 사용하면 더 효율적인 쿼리를 허용하거나, 삽입 및 업데이트 작업의 처리량을 늘리거나, 활동을 샤드 클러스터에 더 효과적으로 분산할 수 있습니다.
데이터 모델 을 개발할 때는 다음 고려 사항과 함께 애플리케이션의 모든 읽기 및 쓰기 (write) 작업 을 분석 합니다.
원자성
MongoDB에서 쓰기 작업은 단일 문서 내에 내장된 문서를 수정하는 경우에도 단일 문서 수준에서 원자적으로 이루어집니다. 한 번의 쓰기 작업으로 여러 문서가 수정되는 경우(예: db.collection.updateMany()
), 각 문서의 수정은 원자적이지만 작업 전체는 원자적이지 않습니다.
임베디드 데이터 모델
임베디드 데이터 모델은 여러 문서와 컬렉션에 걸쳐 정규화하는 대신 모든 관련 데이터를 단일 문서 하나에 결합합니다. 이 데이터 모델은 원자 조작을 용이하게 합니다.
단일 문서에 대한 원자성 업데이트를 제공하는 예제 데이터 모델은 원자 조작을 위한 모델 데이터를 참조하세요.
다중 문서 트랜잭션
관련 데이터 간의 참조를 저장하는 데이터 모델의 경우 애플리케이션은 이러한 관련 데이터를 조회하고 수정하기 위해 별도의 읽기 및 쓰기 작업을 수행해야 합니다.
여러 문서(단일 또는 여러 컬렉션)에 대한 읽기 및 쓰기의 원자성이 필요한 상황의 경우, 복제본 세트 및 샤딩된 클러스터에서의 트랜잭션을 포함한 분산 트랜잭션을 지원합니다.
자세한 내용은 거래를참조하세요.
중요
대부분의 경우 분산 트랜잭션은 단일 문서 쓰기에 비해 더 큰 성능 비용이 발생하므로 분산 트랜잭션의 가용성이 효과적인 스키마 설계를 대체할 수는 없습니다. 대부분의 시나리오에서 비정규화된 데이터 모델 (내장된 문서 및 배열) 은 계속해서 데이터 및 사용 사례에 최적일 것입니다. 즉, 대부분의 시나리오에서 데이터를 적절하게 모델링하면 분산 트랜잭션의 필요성이 최소화됩니다.
추가 트랜잭션 사용 고려 사항(예: 런타임 제한 및 oplog 크기 제한)은 프로덕션 고려사항을 참조하세요.
샤딩
MongoDB는 샤딩을 사용하여 수평 확장을 제공합니다. 이러한 클러스터는 대규모 데이터 세트와 처리량이 많은 작업을 통한 배포 서버를 지원합니다. 샤딩을 사용하면 사용자가 데이터베이스 내에서 컬렉션을 분할하여 컬렉션의 문서를 여러 mongod
인스턴스 또는 샤드에 분산할 수 있습니다.
샤딩된 컬렉션에 데이터와 애플리케이션 트래픽을 분산하기 위해 MongoDB는 샤드 키를 사용합니다. 적절한 샤드 키를 선택하면 성능에 중요한 영향을 미치며 쿼리 격리 및 쓰기 용량 증가를 활성화하거나 방지할 수 있습니다. 나중에 샤드 키를 변경할 수 있지만 샤드 키 선택을 신중하게 고려하는 것이 중요합니다.
Indexes
인덱스를 사용하여 일반적인 쿼리의 성능을 개선하세요. 쿼리에 자주 나타나는 필드와 정렬된 결과를 반환하는 모든 작업에 대해 인덱스를 구축하세요. MongoDB는 _id
필드에 고유 인덱스를 자동 생성합니다.
인덱스를 생성할 때 다음과 같은 인덱스 동작을 고려하세요.
각 인덱스에는 최소 8KB의 데이터 공간이 필요합니다.
인덱스를 추가하면 쓰기 작업의 성능에 부정적인 영향을 미칠 수 있습니다. 쓰기 대 읽기 비율이 높은 컬렉션의 경우 각 삽입은 인덱스도 업데이트해야 하므로 비용이 많이 듭니다.
읽기 대 쓰기 비율이 높은 컬렉션은 종종 추가 인덱스의 이점을 누릴 수 있습니다. 인덱스는 인덱싱되지 않은 읽기 작업에는 영향을 주지 않습니다.
활성화되면 각 인덱스는 디스크 공간과 메모리를 소비합니다. 이 사용량은 상당할 수 있으므로 작업 세트 크기가 특히 우려되는 경우 용량 계획을 위해 추적해야 합니다.
인덱스에 대한 자세한 내용과 쿼리 성능 분석 은 인덱싱 전략 을 참조하세요. 또한 MongoDB 데이터베이스 프로파일러 는 비효율적인 쿼리를 식별하는 데 도움이 될 수 있습니다.
많은 수의 컬렉션
특정 상황에서는 관련 정보를 단일 컬렉션이 아닌 여러 컬렉션에 저장하도록 선택할 수 있습니다.
다양한 환경 및 애플리케이션에 대한 로그 문서를 저장하는 샘플 컬렉션 logs
(을)를 고려해 보세요. logs
컬렉션에는 다음과 같은 형식의 문서가 포함되어 있습니다.
{ log: "dev", ts: ..., info: ... } { log: "debug", ts: ..., info: ...}
총 문서 수가 적으면 문서를 유형별 컬렉션으로 그룹화할 수 있습니다. 로그의 경우 logs_dev
및 logs_debug
와 같은 별도의 로그 컬렉션을 유지하는 것이 좋습니다. logs_dev
컬렉션에는 개발 환경과 관련된 문서만 포함됩니다.
일반적으로 컬렉션 수가 많다고 해서 큰 성능 저하는 없으며 성능은 매우 우수합니다. 고유한 컬렉션은 처리량이 많은 배치 처리에 매우 중요합니다.
컬렉션 수가 많은 모델을 사용하는 경우 동작을 살펴보세요.
각 컬렉션에는 몇 킬로바이트의 특정 최소 오버헤드가 있습니다.
_id
의 인덱스를 포함한 각 인덱스에는 최소 8 kB의 데이터 공간이 필요합니다.각 데이터베이스의 단일 네임스페이스 파일(예:
<database>.ns
)은 해당 데이터베이스의 모든 메타데이터를 저장하며, 각 인덱스와 컬렉션에는 네임스페이스 파일에 고유한 항목이 있습니다. 구체적인 제한 사항은 네임스페이스 길이 제한을 참조하세요.
컬렉션에 많은 수의 작은 문서가 포함되어 있습니다.
다수의 작은 문서가 포함된 컬렉션이 있는 경우 성능상의 이유로 포함을 고려해야 합니다. 이러한 작은 문서를 논리적 관계에 따라 그룹화할 수 있고 이 그룹화로 문서를 자주 검색하는 경우, 작은 문서를 내장된 문서 배열이 포함된 큰 문서로 '롤업'하는 방법을 고려해 볼 수 있습니다.
이러한 작은 문서를 논리적인 그룹으로 "롤업"하면 문서 그룹을 조회하는 쿼리에는 순차적인 읽기가 포함되고 무작위 디스크 액세스가 줄어듭니다. 또한 문서를 "롤업"하고 공통 필드를 더 큰 문서로 이동하면 이러한 필드의 인덱스에 도움이 됩니다. 공통 필드의 복사본 수가 줄어들고 해당 인덱스의 관련 키 항목 수가 줄어듭니다. 인덱스에 대한 자세한 내용은 인덱스를 참조하세요.
그러나 그룹 내에서 문서의 하위 집합만 조회해야 하는 경우가 많으면 문서를 '롤업'해도 더 나은 성능을 제공하지 못할 수 있습니다. 또한 별도의 작은 문서가 데이터의 자연스러운 모델인 경우에는 해당 모델을 유지해야 합니다.
작은 문서를 위한 스토리지 최적화
각 MongoDB 문서에는 일정량의 오버헤드가 포함되어 있습니다. 이 오버헤드는 일반적으로는 중요하지 않지만 컬렉션의 문서에 필드가 한두 개만 있는 경우처럼 모든 문서가 몇 바이트에 불과한 경우에는 중요한 문제가 될 수 있습니다.
이러한 컬렉션에 대한 저장 활용도를 최적화하기 위한 다음 제안 및 전략을 사용해 보세요.
_id
필드를 명시적으로 사용합니다.MongoDB 클라이언트는 각 문서에
_id
필드를 자동으로 추가하고_id
필드에 대해 고유한 12바이트 ObjectId를 생성합니다. 또한 MongoDB는 항상_id
필드를 인덱싱합니다. 작은 문서의 경우 이는 상당한 양의 공간을 차지할 수 있습니다.저장 사용을 최적화하기 위해 사용자는 컬렉션에 문서를 삽입할 때
_id
필드 값을 명시적으로 지정할 수 있습니다. 이 전략을 통해 애플리케이션은 문서의 다른 부분에서 공간을 차지했을_id
필드에 값을 저장할 수 있습니다._id
필드에는 어떤 값이라도 저장할 수 있지만, 이 값은 컬렉션에 있는 문서의 프라이머리 키로 사용되므로 고유하게 식별해야 합니다. 필드 값이 고유하지 않은 경우에는 컬렉션에 충돌이 발생할 수 있기 때문에 프라이머리 키로 사용할 수 없습니다.더 짧은 필드 이름을 사용합니다.
참고
필드 이름을 줄이면 표현력이 떨어지고 문서 크기가 크고 문서 오버헤드가 크게 우려되지 않는 경우 큰 이점을 제공하지 않습니다. 인덱스에는 미리 정의된 구조가 있으므로 필드 이름이 짧아도 인덱스 크기가 줄어들지 않습니다.
일반적으로 짧은 필드 이름을 사용할 필요는 없습니다.
MongoDB는 모든 문서에 모든 필드 이름을 저장합니다. 대부분의 문서에서 이는 문서가 사용하는 공간 중 극히 일부에 불과합니다. 그러나 작은 문서의 경우 필드 이름은 비례적으로 큰 공간을 나타낼 수 있습니다. 다음과 유사한 작은 문서 컬렉션을 사용해 보세요.
{ last_name : "Smith", best_score: 3.9 } 다음과 같이
last_name
필드를lname
으로 줄이고best_score
필드를score
로 줄이면 문서당 9바이트를 절약할 수 있습니다.{ lname : "Smith", score : 3.9 } 문서를 삽입합니다.
경우에 따라 다른 문서에 문서를 임베드하여 문서별 오버헤드를 절약할 수 있습니다. 컬렉션에 많은 수의 작은 문서가 포함됨을 참조하세요.
데이터 수명 주기 관리
데이터 모델링 결정 시 데이터 수명 주기 관리를 고려해야 합니다.
컬렉션의 TTL(Time to Live) 기능은 일정 기간이 지나면 문서를 만료시킵니다. 애플리케이션에서 일부 데이터를 제한된 기간 동안 데이터베이스에 유지해야 하는 경우 TTL 기능을 사용하는 것이 좋습니다.
또한 애플리케이션이 최근에 삽입된 문서만 사용하는 경우 고정 사이즈 컬렉션을 고려하세요. 고정 사이즈 컬렉션은 삽입된 문서의 선입선출(FIFO) 관리를 제공하고 삽입 순서에 따라 문서를 삽입하고 읽는 작업을 효율적으로 지원합니다.