데이터이야기

DB 노하우, 데이터직무, 다양한 인터뷰를 만나보세요.

MongoDB의 논리적/ 물리적 구조

데이터 이야기
작성자
dataonair
작성일
2015-05-29 00:00
조회
6751


MongoDB의 논리적 구조



안녕하세요 주종면입니다. 지난 기사에서는 MongoDB를 선택하는데 있어서 중요한 이슈 중에 하나인 비용적인 측면에 대해 말씀 드렸다면 이번 기사에서는 다시 기술적인 측면을 다루어 보도록 하겠습니다. MongoDB는 RDB 처럼 데이터베이스 관리 시스템 중에 하나이며 사용자의 데이터는 논리적 구조와 물리적 구조로 생성 및 저장됩니다. 이번 기사에서는 MongoDB의 논리적 구조에 대해 알아보고 다음 기사에서는 물리적 구조에 대해 보다 자세히 설명하도록 하겠습니다 기본적으로 MongoDB를 구동하게 되면, 다음과 같이 3가지(프로세스, 메모리, 파일) 영역이 활성화 됩니다.

dbin_400.jpg

1) 프로세스 영역
- 클라이언트 프로세스(Mongo.exe)
- 서버 프로세스(MongoD,exe)

2) 메모리 영역
- Memory Cach 영역
- Journal 영역
- Resident 영역(Working Set)

3) 파일 영역
- 데이터 파일
- JOURNAL 파일



1. 물리적 구조 (데이터 파일 & 저널 파일)

다음은 MongoDB의 물리적 구조에 대한 설명입니다.

1) 32 Bit 시스템 환경에서 네임스페이스(Namespace) 파일의 최초 크기는 16MB가 할당되며 데이터 파일은 최초 32 MB 크기로 생성됩니다. 데이터 파일과 네임스페이스 파일의 두 번째 파일의 크기는 32MB의 배수로 증가되며 최대 파일의 크기는 2GB 입니다. (64 Bit 시스템 환경에서는 최초 16MB이며, 64 MB 단위 로 파일의 크기는 커지며 저널 파일은 1GB 크기로 생성됩니다.)

2) 네임스페이스 파일에는 컬렉션의 First Extent와 LastExtent에 대한 정보와 Meta Data, 인덱스 정보, FreeList 정보가 저장됩니다.



C:\> CD C:\MONGODB\BIN
C:\> mongod --dbpath d:\mongodb\db1 --journal --journalCommitInterval 10 --dbpath에서는 데이터 파일이 생성될 경로를 지정하고 -journal은 백업 데이터가
저장될 수 있도록 기능을 설정합니다. Fri Dec 30 13:34:11 [initandlisten] MongoDB starting : pid=3592 port=27017
dbpath= c:\mongodb\db1\ 64-bit host=PLAN
Fri Dec 30 13:34:11 [initandlisten] db version v2.0.2, pdfile version 4.5
Fri Dec 30 13:34:11 [initandlisten] git version:
514b122d308928517f5841888ceaa4246a7f18e3
Fri Dec 30 13:34:11 [initandlisten] build info: windows (6, 1, 7601, 2, 'Service Pack 1') BOOST_LIB _VERSION=1_42
Fri Dec 30 13:34:11 [initandlisten] options: { dbpath: " c:\mongodb\db1" }
Fri Dec 30 13:34:11 [initandlisten] journal dir=c:/testdb/journal
Fri Dec 30 13:34:11 [initandlisten] recover : no journal files present, no recovery needed
Fri Dec 30 13:34:11 [initandlisten] preallocateIsFaster=true 9.36
Fri Dec 30 13:34:14 [initandlisten] preallocateIsFaster=true 9.04
Fri Dec 30 13:34:14 [initandlisten] preallocateIsFaster check took 3.447 secs
Fri Dec 30 13:34:14 [initandlisten] preallocating a journal file
c:\mongodb\db1/journal/prealloc.0 journal 파일의 경로와 파일명
20971520/1073741824 1%
41943040/1073741824 3%다음은 mongoD 구동 후 MongoDB 내의 논리적 구조를 확인하는 방법입니다.> show dbs
SALES 0.078125GB SALES DB명과 현재 크기 (논리적 구조)
admin 0.078125GB admin DB명과 현재 크기 (논리적 구조)
local 0.078125GB lcoal DB명과 현재 크기 (논리적 구조)
test 0.078125GB test DB명과 현재 크기 (논리적 구조)
> exit다음은 논리적 구조에 대한 물리적 구조를 확인하는 방법입니다.2012-08-01 오후 02:35

journal ? JOURNAL 파일이 생성될 경로
2012-08-02 오후 12:15 16,777,216 test.ns ? TEST DB의 NameSpace
2012-08-02 오후 12:14 67,108,864 test.0 ? TEST DB의 첫 번째 Data-File
2012-08-04 오전 11:47 16,777,216 admin.ns ? admin DB의 NameSpace
2012-08-04 오전 11:46 67,108,864 admin.0 ? admin DB의 첫 번째 Data-File
2012-08-04 오후 12:10 16,777,216 local.ns ? local DB의 NameSpace
2012-08-04 오후 12:10 67,108,864 local.0 ? local DB의 첫 번째 Data-File
2012-08-05 오후 09:33 16,777,216 SALES.ns ? SALES DB의 NameSpace
2012-08-05 오후 09:33 67,108,864 SALES.0 ? SALES DB의 첫 번째 Data-File다음은 JOURNAL 파일을 확인하는 방법입니다.C:\> CD C:\MONGODB\DB1\JOURNAL
C:\mongodb\db1\journal> dir2012-08-01 오후 12:14 1,073,741,824 j._0 ? 첫 번째 JOURNAL 파일
2012-08-02 오후 10:44 1,073,741,824 prealloc.1 ? 두 번째 JOURNAL 파일



2. 논리적 구조

1) 이번에는, 논리적 구조에 대해 알아 보겠습니다. 하나의 데이터베이스는 여러 개의 도큐멘트로 구성되며 하나의 Document는 여러 개의 Extent로 구성됩니다. 또한, 하나의 Extent는 여러 개의 Data Store로 구성되어 있습니다. 결론적으로, MongoDB에서 데이터를 저장하는 가장 작은 논리적 구조는 데이터 레코드 입니다.

Database ? Collections ? Extents ? Data Records(Documents)
dbin_401.jpg

2) 컬렉션 크기는 createCollection에 의해 생성될 때 결정되며 익스텐트 기본 크기는 8K이 며 insert, save 메소드에 의해 컬렉션이 생성될 때 기본 크기는 4K로 생성됩니다.



(Ex) db.createCollection(“s_emp", {capped:false, size:100000}); > db.createCollection("s_emp", {capped:false, size:8192 })
{ "ok" : 1 } ? CAPPED 컬렉슨을 최초 크기 8192 Byte 크기로 생성
>
> db.s_emp.validate();
{
"ns" : "sales.s_emp",
"firstExtent" : "0:c4000 ns:sales.s_emp",
"lastExtent" : "0:c6000 ns:sales.s_emp",
"extentCount" : 1, 활성화된 Extent 개수
"datasize" : 0,
"nrecords" : 0,
"lastExtentSize" : 4096, 마지막 Extent의 크기
"padding" : 1,
"firstExtentDetails" : {
"loc" : "0:c4000",
"xnext" : "0:c6000",
"xprev" : "null",
"nsdiag" : "sales.s_emp",
"size" : 8192, 활성화된 Extent 크기
"firstRecord" : "null",
"lastRecord" : "null"
},
"deletedCount" : 2,
"deletedSize" : 11936,
"nIndexes" : 1,
"keysPerIndex" : {
"sales.s_emp.$_id_" : 0
},
"valid" : true,
"errors" : [ ],
"warning" : "Some checks omitted for speed. use {full:true}
option to do more thorough scan.",
"ok" : 1
}
> db.s_emp.insert({ empno : 1101 })
>
> db.s_emp.validate();
{
"ns" : "SALES.s_emp",
"firstExtent" : "0:11000 ns:SALES.s_emp",
"lastExtent" : "0:13000 ns:SALES.s_emp",
"extentCount" : 2,
"datasize" : 40, 입력된 데이터 크기
"nrecords" : 1, 입력된 Document 수
"lastExtentSize" : 4096,
"padding" : 1,
"firstExtentDetails" : {
"loc" : "0:11000",
"xnext" : "0:13000",
"xprev" : "null",
"nsdiag" : "SALES.s_emp",
"size" : 8192,
"firstRecord" : "null",
"lastRecord" : "null"
},
"deletedCount" : 2,
"deletedSize" : 11880,
"nIndexes" : 1,
"keysPerIndex" : {
"SALES.s_emp.$_id_" : 1
},
"ok" : 1
}
>



3. 익스텐트와 데이터 레코드

1) MongoDB에서 Extent는 데이터가 저장되는 논리적인 단위입니다. 하나의 Extent에 얼마나 적절하게 데이터를 잘 저장하느냐는 읽기/쓰기에 있어 성능을 좌우하는 요소가 될 수 있습니다.

2) 하나의 컬렉션을 위한 가장 적절한 익스텐트 크기를 결정하기 위해서는 적절한 분석과 논리적 설계가 요구됩니다.



> db.s_emp.count()
12346> db.s_emp.validate()
{
"ns" : "SALES.s_emp",
"firstExtent" : "0:11000 ns:SALES.s_emp",
"lastExtent" : "0:11c000 ns:SALES.s_emp",
"extentCount" : 6, 현재 활성화된 Extent 수
"datasize" : 641992, 전체 데이터 크기
"nrecords" : 12346, 입력된 Document 수
"lastExtentSize" : 1048576, 전체 Extent 크기
"padding" : 1,
"firstExtentDetails" : {
"loc" : "0:11000",
"xnext" : "0:13000",
"xprev" : "null",
"nsdiag" : "SALES.s_emp",
"size" : 8192,
"firstRecord" : "0:110b0",
"lastRecord" : "0:12f80"
},
<중략>
"valid" : true,
"errors" : [ ],
"warning" : "Some checks omitted for speed. use {full:true} option to do more thorough scan.",
"ok" : 1
}
> db.s_emp.validate( { full : true } )
? S_EMP에 확장된 모든 익스텐트 상태를 출력한다.
{
"ns" : "SALES.s_emp",
"firstExtent" : "0:11000 ns:SALES.s_emp",
"lastExtent" : "0:11c000 ns:SALES.s_emp",
"extentCount" : 6,
"extents" : [
{
"loc" : "0:11000", 첫 번째 Extent 정보
"xnext" : "0:13000",
"xprev" : "null",
"nsdiag" : "SALES.s_emp",
"size" : 8192,
"firstRecord" : "0:110b0",
"lastRecord" : "0:12f80"
},
{
"loc" : "0:13000", 두 번째 Extent 정보
"xnext" : "0:14000",
"xprev" : "0:11000",
"nsdiag" : "SALES.s_emp",
"size" : 4096,
"firstRecord" : "0:130b0",
"lastRecord" : "0:13f84"
},
<중략>
],
"datasize" : 641992,
"nrecords" : 12346,
"lastExtentSize" : 1048576,
"padding" : 1,
"firstExtentDetails" : {
"loc" : "0:11000",
"xnext" : "0:13000",
"xprev" : "null",
"nsdiag" : "SALES.s_emp",
"size" : 8192,
"firstRecord" : "0:110b0",
"lastRecord" : "0:12f80"
},
"objectsFound" : 12346,
"invalidObjects" : 0,
"bytesWithHeaders" : 839528,
"bytesWithoutHeaders" : 641992,
"deletedCount" : 5,
"deletedSize" : 564344,
"nIndexes" : 1,
"keysPerIndex" : {
"SALES.s_emp.$_id_" : 12346
},
"valid" : true,
"errors" : [ ],
"ok" : 1 }



초당 200,000건 이상의 빅 데이터를 MongoDB 내에 빠르게 쓰고 읽기 위해서는 최초 컬렉션을 생성할 때 충분한 논리적 구조와 물리적 구조에 대한 설계가 요구됩니다. 기존의 RDBMS에 비해 빠른 성능에 보장될 수 있는 것은 NoSQL이 가지고 있는 최적화된 구조와 유연성 있는 데이터 구조가 제공되기 때문이므로 충분한 분석과 설계가 요구됩니다.

* 위 글의 저작권은 ㈜플랜정보기술에 있으며 무단 복사 및 링크는 금지합니다.
해당 글에 대한 문의사항은 아래로 연락 주시기 바랍니다.

㈜플랜정보기술 주 종 면
- MongoDB inc. (MongoDB 개발 및 기술지원 업체) 한국 공식 파트너
- DBMS 컨설팅/유지보수/판매
jina6678@daum.net
010-3864-1858

www.pitmongo.co.kr
www.mongodb-korea.org





출처 : 한국데이터베이스진흥원

제공 : DB포탈사이트 DBguide.net