RDBMS에 대한 MongoDB의 성능
이 문서는 MongoDB Developer Center의 아티클 (opens in a new tab)을 번역한 것입니다.
어딘가에서 누군가는 왜 RDBMS 데이터베이스에 비해 MongoDB에서 우수한 성능을 얻을 수 있는지 궁금해할 것입니다. 그 비결은 무엇일까요? 저 또한 MongoDB의 내부 작동 방식, 특히 데이터 모델링, 고급 인덱스 방법, 그리고 마지막으로 WiredTiger 스토리지 엔진이 어떻게 작동하는지에 대해 배우기 전까지는 이 질문을 가지고 있었습니다.
제가 배운 것과 경험한 것을 공유하여 그 비결을 밝히고 여러분께 도움이 되었으면 합니다.
데이터 모델링: 임베디드 구조 (JOIN 없음)
MongoDB는 문서 지향 데이터 모델을 사용하여 데이터를 JSON과 유사한 BSON 문서에 저장합니다. 이를 통해 복잡한 데이터 구조를 효율적으로 저장하고 검색할 수 있습니다.
MongoDB의 모델은 RDBMS의 정규화 요구 사항에 비해 더 간단하고 성능이 뛰어난 쿼리로 이어질 수 있습니다.
성능 향상의 초기 단계는 애플리케이션의 쿼리 동작을 이해하는 것입니다. 이 이해를 통해 데이터 모델을 맞춤화하고 이러한 패턴에 효과적으로 부합하는 적절한 인덱스를 선택할 수 있습니다.
MongoDB의 최적화된 문서 크기(16MB)를 항상 기억하여 아래 이미지와 같이 이미지, 오디오, 비디오 파일을 동일한 컬렉션에 임베딩하는 것을 피할 수 있습니다.
애플리케이션의 쿼리 패턴에 맞게 데이터 모델을 사용자 정의하면 쿼리가 간소화되고, 삽입 및 업데이트 작업의 처리량이 증가하며, 샤딩된 클러스터 전체에 워크로드가 더 잘 분산됩니다.
MongoDB는 유연한 스키마를 제공하지만, 스키마 설계를 간과해서는 안 됩니다. 필요에 따라 스키마를 조정할 수 있지만, 프로젝트 초기부터 스키마 설계 모범 사례를 준수하면 나중에 광범위한 리팩토링의 필요성을 예방할 수 있습니다.
BSON 문서의 주요 장점은 애플리케이션에 필요한 방식으로 데이터를 유연하게 모델링할 수 있다는 것입니다. 문서 내에 배열과 하위 문서를 포함하면 복잡한 데이터 관계를 모델링하는 데 상당한 다재다능함을 제공합니다. 하지만 플랫, 테이블 형식, 컬럼 형식 구조, 간단한 키-값 쌍, 텍스트, 지리 공간 및 시계열 데이터, 또는 연결된 그래프 데이터 구조의 노드와 엣지를 모델링할 수도 있습니다. 애플리케이션에 이상적인 스키마 설계는 특정 쿼리 패턴에 따라 달라집니다.
MongoDB에서 컬렉션 내 임베딩은 RDBMS에서 여러 테이블에 저장하는 것과 어떻게 다른가요?
주소록/연락처에 대한 모범 사례 예시는 그룹과 프로필 사진 정보를 다른 컬렉션으로 분리하는 것입니다. 왜냐하면 n-n 관계와 이미지 크기 때문에 각각 커질 수 있으며, 16MB의 최적화된 문서 크기에 도달할 수 있기 때문입니다.
MongoDB에서 단일 컬렉션에 데이터를 임베딩하거나 최소한 컬렉션 수를 최소화하는 것은 RDBMS에서 여러 테이블에 저장하는 것과 비교하여 데이터 지역성으로 인해 상당한 성능 향상을 제공하며, 이는 아래 그림과 같이 데이터 탐색을 줄여줍니다.
데이터 지역성은 MongoDB 데이터 탐색이 더 빠른 주된 이유입니다.
차이점: 테이블 형식 vs 문서
테이블 형식 (Tabular) | MongoDB |
---|---|
모델 생성 단계 | 1. 스키마 정의 2. 앱 및 쿼리 개발 |
초기 스키마 | 제3정규형. 하나의 가능한 해결책 |
최종 스키마 | 비정규화될 가능성이 높음 |
스키마 진화 | 어렵고 최적화되지 않음. 다운타임 가능성 |
성능 | 보통 |
WiredTiger의 캐시 및 압축
WiredTiger는 MongoDB를 위한 오픈 소스, 고성능 스토리지 엔진입니다. WiredTiger는 문서 수준 동시성 제어, 압축, 인메모리 및 온디스크 스토리지 지원과 같은 기능을 제공합니다.
캐시:
- WiredTiger 캐시 아키텍처: WiredTiger는 메모리에서 데이터를 효율적으로 관리하기 위해 정교한 캐싱 메커니즘을 사용합니다. 캐시는 자주 액세스하는 데이터를 저장하여 디스크에서 읽을 필요성을 줄이고 전반적인 성능을 향상시킵니다.
- 메모리 관리: 캐시는 워크로드에 따라 메모리 사용량을 동적으로 관리합니다. 캐시에서 덜 자주 사용되는 데이터를 제거하는 축출(eviction) 및 자주 사용되는 데이터를 캐시로 이동하는 승격(promotion)과 같은 기술을 사용하여 메모리 활용도를 최적화합니다.
- 구성: WiredTiger는 사용자가 시스템의 사용 가능한 메모리와 워크로드 특성에 따라 캐시 크기를 구성할 수 있도록 합니다. 캐시 크기를 적절하게 설정하는 것은 최적의 성능을 달성하는 데 중요합니다.
- 내구성: WiredTiger는 수정된 데이터를 캐시에서 디스크로 플러시하여 내구성을 보장합니다. 이 프로세스는 시스템 장애 시 데이터 일관성을 유지하는 데 도움이 됩니다.
압축:
- 데이터 압축: WiredTiger는 데이터 압축을 지원하여 필요한 스토리지 공간의 양을 줄입니다. 데이터를 압축하면 상당한 디스크 공간 절약과 향상된 I/O 성능을 얻을 수 있습니다.
- 구성 가능한 압축: 사용자는 요구 사항에 따라 압축 옵션을 구성할 수 있습니다. WiredTiger는 다양한 압축 알고리즘을 지원하여 사용자가 워크로드와 성능 목표에 가장 적합한 것을 선택할 수 있도록 합니다.
- 장단점: 압축은 스토리지 비용을 줄이고 읽기/쓰기 성능을 향상시킬 수 있지만, 압축 및 압축 해제 과정에서 추가적인 CPU 오버헤드가 발생할 수 있습니다. 사용자는 장단점을 신중하게 고려하고 애플리케이션의 요구 사항에 맞는 압축 설정을 선택해야 합니다.
- 호환성: WiredTiger의 압축 기능은 애플리케이션에 투명하며 애플리케이션 코드를 변경할 필요가 없습니다. 엔진은 내부적으로 압축 및 압축 해제를 처리합니다.
전반적으로 WiredTiger의 캐시 및 압축 기능은 효율성과 성능 특성에 기여합니다. 메모리 사용을 최적화하고 구성 가능한 압축 옵션을 제공함으로써 WiredTiger는 속도와 스토리지 효율성 측면에서 MongoDB 사용자의 다양한 요구를 충족시키는 것을 목표로 합니다.
일부 RDBMS 시스템도 캐싱을 사용하지만, 성능상의 이점은 데이터베이스 시스템과 구성에 따라 달라질 수 있습니다.
고급 인덱싱 기능
NoSQL 데이터베이스인 MongoDB는 쿼리 성능을 최적화하고 효율적인 데이터 검색을 지원하기 위한 고급 인덱싱 기능을 제공합니다. 다음은 MongoDB의 고급 인덱싱 기능 중 일부입니다.
복합 인덱스 (Compound indexes)
MongoDB를 사용하면 여러 필드에 대해 복합 인덱스를 생성할 수 있습니다. 복합 인덱스는 특정 순서로 여러 필드에 대한 인덱스입니다. 이는 여러 기준을 포함하는 쿼리에 유용할 수 있습니다.
복합 인덱스에서 필드의 순서는 매우 중요합니다. MongoDB는 인덱스 필드를 왼쪽에서 오른쪽으로 일치시키는 쿼리에 대해 인덱스를 효율적으로 사용할 수 있습니다.
다중 키 인덱스 (Multikey indexes)
MongoDB는 배열에 대한 인덱싱을 지원합니다. 배열 필드를 인덱싱하면 MongoDB는 배열의 각 요소에 대해 별도의 인덱스 항목을 생성합니다.
다중 키 인덱스는 배열을 포함하는 문서로 작업하고 해당 배열 내의 요소를 기반으로 쿼리해야 할 때 유용합니다.
텍스트 인덱스 (Text indexes)
MongoDB는 전체 텍스트 검색을 지원하기 위해 텍스트 인덱스를 제공합니다. 텍스트 인덱스는 단어를 토큰화하고 어간 추출(stemming)하여 보다 유연하고 언어 인식적인 텍스트 검색을 가능하게 합니다.
텍스트 인덱스는 사용자가 대량의 텍스트 데이터에 대해 텍스트 검색 작업을 수행해야 하는 시나리오에 적합합니다.
지리 공간 인덱스 (Geospatial indexes)
MongoDB는 지리 공간 데이터를 포함하는 쿼리를 최적화하기 위해 지리 공간 인덱스를 지원합니다. 이 인덱스는 위치 기반 정보와 관련된 쿼리를 효율적으로 처리할 수 있습니다.
지리 공간 인덱스는 2D 및 3D 인덱싱을 지원하여 평면 및 구면 기하학을 모두 표현할 수 있습니다.
와일드카드 인덱스 (Wildcard indexes)
MongoDB는 와일드카드 인덱스를 지원하여 문서의 필드 중 일부만 포함하는 인덱스를 생성할 수 있습니다. 이는 특정 쿼리 패턴이 있고 모든 필드를 인덱싱하지 않고 해당 패턴에 맞게 최적화하려는 경우에 유용할 수 있습니다.
부분 인덱스 (Partial indexes)
부분 인덱스를 사용하면 지정된 필터 표현식을 만족하는 문서만 인덱싱할 수 있습니다. 이는 대규모 컬렉션이 있지만 특정 기준을 충족하는 문서의 하위 집합에 대한 인덱스를 생성하려는 경우에 유용할 수 있습니다.
해시 인덱스 (Hashed indexes)
해시 인덱스는 샤딩 시나리오에 유용합니다. MongoDB는 인덱싱된 필드의 값을 자동으로 해시하고 샤드 전체에 데이터를 분산시켜 데이터와 쿼리의 분포를 더 균등하게 제공합니다.
TTL (Time-To-Live) 인덱스
TTL 인덱스를 사용하면 일정 시간이 지난 후 컬렉션에서 문서를 자동으로 만료시킬 수 있습니다. 이는 세션 정보나 로그 항목과 같이 자연스러운 만료가 있는 데이터를 관리하는 데 유용합니다.
MongoDB의 이러한 고급 인덱싱 기능은 개발자에게 광범위한 시나리오 및 데이터 구조에 대한 쿼리 성능을 최적화할 수 있는 강력한 도구를 제공합니다. 이러한 기능을 적절하게 활용하면 MongoDB 데이터베이스의 효율성과 응답성을 크게 향상시킬 수 있습니다.
결론적으로, 전통적인 RDBMS 데이터베이스에 대한 MongoDB의 우수한 성능은 데이터 모델링, 고급 인덱싱 방법, 그리고 WiredTiger 스토리지 엔진의 효율성을 능숙하게 처리하는 데서 비롯됩니다. 데이터 모델을 애플리케이션 쿼리 패턴에 맞게 조정하고, MongoDB의 최적화된 문서 구조를 활용하며, 고급 인덱싱 기능을 활용함으로써 처리량을 향상시키고 워크로드를 더 효과적으로 분산시킬 수 있습니다.
MongoDB는 스키마 설계에 유연성을 제공하지만, 프로젝트 초기부터 스키마 설계 모범 사례의 중요성을 간과해서는 안 된다는 점을 기억하십시오. 이러한 사전 예방적 접근 방식은 나중에 발생할 수 있는 리팩토링 노력을 절약해 줄 수 있습니다.
MongoDB 및 데이터베이스 최적화 전략에 대한 추가 탐색 및 논의를 위해 저희 개발자 커뮤니티에 참여하는 것을 고려해 보십시오. 그곳에서 동료 개발자들과 교류하고, 통찰력을 공유하며, 데이터베이스 기술의 최신 개발 동향에 대한 최신 정보를 얻을 수 있습니다.
MongoDB로 계속해서 최적화하고 혁신하여 애플리케이션의 잠재력을 최대한 발휘하십시오.