글모음

‘mongodb’ 꼬리말(tag)이 달린 글들

The Data Structure of MongoDB (2)

글 : 이승용

 
이번에는 MongoDB 데이터 구조(1)에 이어 두번째로 MongoDB가 데이터를 저장하는 기본 단위인 레코드record와 레코드들의 그룹핑인 익스텐트extent 구조에 대해 알아본다. MongoDB의 익스텐드는 자료 구조 관점에서 보면 연결되어 있는 레코드들의 헤더 역할을 수행하는 것 뿐만 아니라, 레코드 데이터를 로컬 스토리지에 저장하기 위한 파일로 처리한다.[1]
 

MongoDB 레코드 구조

MongoDB는 도규멘트document 로 구성된 데이터를 RDB의 열row과 같은 개념으로 처리한다. 하지만, MongoDB는 NoSQL의 특징인 RDB와는 달리 스키마schema 구조를 가지고 있지 않기 때문에 도규멘트에 저장되는 데이터 형식에 구애를 받지 않는다. 즉, RDB는 테이블에 속하는 모든 열이 같은 데이터 형식을 가지고 있어야 하지만, NoSQL은 열에 저장되는 데이터 형식이 상이하여도 문제가 발생되지 않는다.[2]

mongo_record_structure

[그림 1] MongoDB의 레코드 구조

[그림 1]은 MongoDB의 레코드 구조를 보여준다. 헤더는 총 16바이트 크기를 가지며, 도큐멘트를 BSON 객체 형태로 저장하고 있다. 한가지 주의할 점은 MongoDB가 저장하는 도규멘트의 크기는 필드명을 포함하고 있다는 것이다. RDB를 개발한 사용자들이 흔히 이 점을 유념하지 않아 도규멘트 크기가 벗어나는 경우가 종종 발생하기도 한다. 만약 도큐멘트 { personal nick name :  test } 를 저장한다고 생각하면, 필드명 ‘personal nick name’이 [그림 1]의 data 영역에 같이 저장되기 때문에 1만명의 사용자 닉네임을 저장한다고 하면 ‘personal nick name’이 1만번 중복되어 저장된다. 따라서, MongoDB를 사용할 때는 필드명 설정에 신중할 필요가 있다. [표 1]은 [그림 1]의 각 필드명에 대한 설명을 보여준다.
 
[표 1] MongoDB의 레코드 구조

필드명

내용

Size

헤더를 포함하고 있는 레코드의 크기, BSON 객체의 크기는 Size 필드에서 헤더 크기인 16을 빼면 된다.

Extent Offset

해당 레코드가 속해 있는 익스텐션의 Offset 주소[3]

Next Offset

다음 레코드를 가리키는 Offset 주소

Prev Offset

이전 레코드를 가리키는 Offset 주소

bson object

도큐멘트를 구성하는 BSON 객체[4]

[표 1]에서 레코드에서 저장되어 있는 모든 위치 정보(Extent Offset, Next Offset, Prev Offset)들이 4바이트 정수형 데이터로 저장한 이유는, 동일한 익스텐트 안에 저장되는 데이터이기 때문에 익스텐트 시작 주소의 상대 주소 값을 저장하여 중복된 데이터 영역을 없애 데이터 저장 크기를 줄일 수 있기 때문이다.
 

MongoDB 익스텐트 구조

MongoDB의 익스텐드는 레코드들의 그룹을 말한다. 익스텐드는 고유한 네임스페이스를 가지고 있기 때문에, 익스텐드에 포함된 레코드는 동일한 네임스페이스에 존재하는 데이터가 된다. 즉, 이전 글의 [그림 1]과 같이 MongoDB의 컬렉션은 한 개 이상의 익스텐드로 구성된다. MongoDB는 데이터베이스.컬렉션 형태의 데이터 표기법을 가지고 있다. 예를 들어, personal 데이터베이스의 user 라는 컬렉션이 존재한다고 가정하면, 데이터 삽입을 personal.user.insert( { personal_name : ‘이승용’ } ) 과 같이 사용한다. 이때 personal.user 의 형태가 네임스페이스를 의미한다. [그림 2]는 MongoDB의 익스텐드 구조를 보여준다.

[그림 2]와 구성된 MongoDB의 익스텐트는 한 개의 네임스페이스를 가지고 있기 때문에, 한 개의 컬렉션은 여러개의 익스텐트를 가질 수 있지만, 역은 성립하지 않는다.(한 개의 익스텐트에 두 개의 컬렉션이 저장되지 않는다.)  [그림 2]의 위치 정보 – My Location, Next Extent, Prev Extent, First Record, Last Record – 들은 모두 8바이트 크기를 가지고 있다. 64비트 컴퓨터의 주소는 64비트 크기를 가지고 있기 때문에 8바이트 크기를 가진다. 그리고 size 필드가 4바이트로 규정되어 있다. MSBMost Significant Bit 를 제외하면 2GB의 크기 까지 익스텐트의 크기를 지정할 수 있다. 

mongo_extent_structure

[그림 2] MongoDB의 익스텐트 구조

익스텐드는 헤더 4바이트와 데이터 172바이트로 구성되어, 총 178바이트의 크기를 가진다. 헤더에는 781231[5]이라는 값을 가지고 있으며, 16진수로 0x000BEBAF를 가진다. 익스텐드 데이터 영역에 대한 자세한 사항은 [표 2]를 보기 바란다. [표 2]에 저장된 모든 위치 정보는 8바이트 크기를 가지며, 상위 4바이트는 볼륨 정보를, 하 위4바이트는 오프셋 위치를 나타낸다.
 
[표 2] MongoDB의 익스텐드 구조

필드명

내용

Magic

4바이트 헤더이며, 정수 781231 값을 가진다.

My Location

해당 익스텐드가 저장된 위치 정보를 나타낸다.

Next Extent

다음 익스텐드를 가리키는 위치 정보

Prev Extent

이전 익스텐드를 가리키는 위치 정보

Namespace

해당 익스텐드의 네임 스페이스[6]

Size

해당 익스텐드의 크기

First Record

해당 익스텐드에 포함된 첫번째 레코드 위치 정보

Last Record

해당 익스텐드에 포함된 마지막 레코드 위치 정보

 


 

[1] MongoDB는 로컬 스토리지에 데이터베이스 명으로 확장자가 숫자로 증분하는 형태의 파일을 가진다. 예를 들어 test.1이라고 하면, test라는 데이터베이스의 첫번째 익스텐트를 의미한다.
[2] NoSQL의 기본 개념이 스키마 프리schema free 이기 때문에, RDB 사용하는 사용자가 가장 많이 혼동하는 부분이다. NoSQL을 RDB처럼 사용할 수 있지만, RDB처럼 데이터를 관리하지 않는다. 즉, 어떤 부분은 RDB보다 빠른 결과를 가져오지만, 어떤 부분은 RDB 보다 느린 경우가 발생한다.
[3] MongoDB는 모든 위치를 DiskLoc이라는 구조체를 사용하는데, volume 정보와 offset 정보 두 개를 가지는 구조체이다. 여기서 말하는 offset은 DiskLoc의 offset 주소와 동일하다.
[4] BSON 객체의 구조는 http://bsonspec.org/#/specification 참고.
[5] 필자는 혹시 MongoDB 개발자가 78년 12월 31일이라고 재미있는 상상을 해본다.
[6] MongoDB의 최대 네임스페이스 크기는 128바이트이다.

  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
Categories: MongoDB Tags: ,

The Data Structure of MongoDB (1)

글 : 이승용

 

빅데이터가 소개되면서 NoSQL이 각광받게 되었으며, 그 중 MongoDB는 NoSQL에서 선두 자리를 차지하고 지속적으로 발전되고 있다.다. 오픈 소스인 MongoDB는 누구가 그 내부 구조를 살펴 볼 수 있음에도 불구하고 방대한 양 때문에 MongoDB에 대한 내부 구조에 대해 자세하게 논하지는 못하고 있다. 사실 끊임없이 업그레이드되는 프로젝트의 내부 구조를 매번 분석한다는 것도 매우 어렵다. 하지만, 필자는 이번 기회에 필자가 분석한 MongoDB의 내부 데이터 구조를 살펴봄으로써, NoSQL의 기술 트랜드가 어떠한 방식으로 발전되고 있는지 알아보고, 개선 방향에 대해서도 살펴보기로 한다. 이번에는 그 첫번째로 MongoDB에서 사용되는 데이터 구조의 용어를 기본 개념만 알아본다.

MongoDB의 데이터 구조는 크게 데이터를 저장하는 레코드record와 인덱스를 저장하는 버켓bucket으로 구성된다. MongoDB는 BSON 객체를 데이터 저장 단위로 사용하기 때문에, 저장하고 있는 모든 데이터를 BSON 객체의 이중연결리스트double linked list구조로 구성하고, BSON 객체를 저장하는 노드를 레코드로 정의한다. 반면 인덱스는 레코드에 저장된 데이터를 빠르게 찾기 위해 b-tree 형태로 저장된 노드 구조를 가지며, b-tree 노드를 버켓이라고 정의한다.

MongoDB는 대용량 데이터를 HDD에 쉽게 저장할 수 있는 단위로 레코드들을 그룹핑grouping하는데, 이를 익스텐드extent라고 한다. MongoDB의 익스텐드는 자료 구조 관점에서 보면 연결되어 있는 레코드들의 헤더 역할을 수행하는 것이지만, 이 익스텐드들을 이용하여 MongoDB는 HDD에 저장될 파일과 삭제된 레코드를 관리한다.

 

MongoDB 데이터 구조

[그림 1] MongoDB 데이터 구조

 

[그림 1]은 앞에서 설명한 MongoDB의 데이터 구조가 유기적으로 수행되는 모습을 도식화한 것이다. 사용자가 하나의 데이터베이스를 만들었다면, MongoDB는 데이터베이스와 관련된 한 개의 네임스페이스namespace를 만든다.[1] 데이터베이스 네임스페이스는 RDB의 테이블과 동일한 MongoDB의 컬렉션collection 네임스페이스와 데이터베이스 별로 삭제된 레코드 리스트를 가지고 있는 프리 익스텐드Free Extent 리스트를 가진다. 컬렉션 네임스페이스는 사용자가 insert 질의를 통해 정의한 컬렉션 명으로 구성되며, 컬렉션 생성과 동시에 _id 필드의 기본 인덱스 네임스페이스를 가지게 된다. 만약 사용자가 _id 이외의 필드를 인덱스를 구성하였다면, 생성된 인덱스 필드에 하나의 인덱스 네임스페이스가 구성되고, 필드 값은 b-tree 형태로 인덱스를 구성한다.

MongoDB는 데이터를 저장하는 레코드나 인덱스를 저장하는 버켓이나 모두 데이터를 저장하는 공간이다. MongoDB의 데이터 저장소는 메모리 맵 파일Memory Mapped File을 사용한 가상 메모리를 사용한다. 가상 메모리는 시스템이 지원하는 운영체제 버전에 따라 가상 주소 공간을 할당 받게 되고 할당 받은 주소 공간을 마치 파일을 처리하는 방식으로 프로그램을 구성할 수 있다.[2]

[그림 1]과 같이 실질적인 데이터 저장 공간을 가지고 있는 레코드와 버켓은 그 크기에 맞는 가상 메모리의 주소를 가지고 있고, 사용자가 insert/update를 수행하였다면 MongoDB는 해당 레코드가 가리키는 가상 메모리 주소 공간에 데이터를 적재한다. 만약 사용자가 특정 위치의 데이터를 읽는다면, MongoDB는 해당 메모리 주소 공간에 할당된 데이터가 가상 메모리에 로딩되어 있는지 확인하고, 로딩되어 있지 않다면 파일에서 내용을 읽어 가상 메모리에 적재한다.[3]

또한 MongoDB는 백그라운드로 가상 메모리에 적재된 데이터를 HDD에 최대 2GB 단위로 파일을 구성한 볼륨volume으로 HDD에 데이터를 적재한다. 이를 플러쉬flush를 수행한다고 하며, 주기적으로 가상 메모리 공간에 로딩된 데이터를 HDD에 저장한다.[4]

 


[1] 사용자는 use 명령을 이용하여 데이터베이스를 선택한다.

[2] 32비트 OS에서는 가상 메모리의 한계로 2G만 선택할 수 있다. 여기서 2G는 Windows가 예약한 32비트 User Area 공간의 크기이다.

[3] MongoDB는 이러한 작업을 Page Fault Exception이 발생할 때 수행한다.

[4] 디폴트 주기 값은 60초로 설정되어 있다.


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
Categories: MongoDB Tags: ,

MongoDB is an Open Source!

글 : 이승용

MongoDB가 NoSQL의 강자로 자리잡기 시작하면서 장단점에 대한 기사를 종종 읽게 된다. 하지만, 세상만사 모든 일이 똑같지만 장점보다는 단점이 두각 되는 것은 어쩔 수 없는 이치인 것 같다. 2012년 초반에 PASTEBIN에 포스팅된 ‘Don’t use MongoDB’에도 MongoDB를 사용하면 안 되는 이유가 개제된 적이 있고, 거의 1년 만에 Bloter.net에서 다시 기사화된 것을 보면 MongoDB도 전세계적으로 유명한 데이터베이스가 되었구나 하는 생각이 든다.[1] 그리고, 1년 전에 논의된 내용이 아직도 유효한지는 모르겠지만,[2] 급변하는 IT 기술에 맞추어 볼 때, 필자는 오픈 소스 기술을 대하는 우리들의 자세가 문제가 있지 않나 생각해 본다.

대부분의 유명한 오픈 소스 기술들은 처음에 그들이 주장하는 기술이나 개념은 매우 놀라울 정도로 앞선 것들이다. 이러한 기술들이 개발자들에게 흥미를 유발시키고, 그리고 그 기술이 모든 것을 해결해 줄 수 있는 컴컴한 바닷가의 등불과 같이 안도의 길을 보게 한다. 기대가 크면 실망도 크기 마련이다. 해당 기술에 대한 정확한 분석이 있기 전까지 그들이 말하는 내용을 자기의 상황에 맞추어 모든 것이 해결된다고 판단해 버린 개발자는 신을 믿듯이 맹신하게 되고, 그 기대감이 자신의 기대치에 미치지 못한다고 판단하면, 홈쇼핑에서 물건을 잘 못산 것처럼 끔직한 비평가가 된다.

‘그들은 거짓말을 하고 있다.’ ‘그들이 다 된다고 했는데, 내가 원하는 기능이 아니다.’ 라는 식의 평가 없는 비평은 오픈 소스에 대한 바른 평가가 될 수 없다. 오픈 소스의 정신은 도전과 올바른 비평을 통해 발전의 방향을 공유하는 것이다. 만약 그들이 분석을 통한 비평으로 오픈 소스 기술을 올바르게 사용할 수 있는 방법을 연구하였다면, 전혀 새로운 기능들을 볼 수 있을 것이다. 오픈 소스는 상용화된 제품과는 달리 모든 기능들이 잘 정형화된 문서로 남지 않는다. 그렇다면, ‘어떻게 분석할 것인가?’ 바로 소스를 보는 것이다. 오픈된 소스를 통해 그들이 지원하지 않는 방법을 알아내고 이를 회피하는 방법 또는 보강하는 방법을 통해 새로운 기술을 습득하는 것이다.

그리고, 자신이 알아낸 기술을 인터넷을 통해 공유함으로써, 다음 버전에서 더 좋은 제품이 될 수 있도록 지원할 수 있어야 하며, 또는 그러한 기술을 통해 새로운 사업 아이템을 모색하는 것도 좋을 것이다. 그러면, 비평하는 개발자는 초기 맹신논자처럼 무조건 적인 맹신이 아니라, 분석 있는 날카로운 비평가가 될 수 있고, 자신의 실력이 올라가고 있음을 알 수 있을 것이다.

필자가 바라본 MongoDB는 다른 어떤 제품보다도 매혹적인 부분이 충분히 있으며, 또한 10gen이 왜 이렇게 만들었을까 하는 부분도 보인다.[3] MongoDB는 다른 솔루션과 마찬가지로 아무런 준비 없이 바로 대규모 시스템에 도입할 수 있는 제품은 아니다. 충분히 분석하고 연구함으로써 자신의 시스템에 맞게 구축할 수 있는 최상의 오픈 소스임에는 틀림없다.



[1] 2013년 5월 기준으로 MongoDB는 전세계 데이터베이스 시장에서 7위를 자리잡고 있다. 출처 : http://db-engines.com/en/ranking

[2] 해당 포스트가 개제될 때, 글을 쓴 사람이 사용한 MongoDB 버전은 1.8에서 2.0 버전으로 바뀌던 시점이다. 현재 MongoDB는 버전 2.4.3까지 업그레이드 되었으며, NoSQL은 1개월만 지나도 새로운 기술이 나오는 시점에 1년전 이야기를 하는 것은 바람직하지 않다고 본다.

[3] 이러한 장단점들은 필자가 본 사이트를 통해 다루어볼 것이다.


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
Categories: 미분류 Tags:

New Released – Monad Management for MongoDB v2.2

11월 7th, 2012 한 개의 댓글

MongoDB 모니터링 및 관리도구인 Monad Management가 버전 2.2로 새롭게 업그레이드 했다. 이번 버전에서는  MongoDB 2.2의 데이터베이스별 락을 지원해주고 있으며, 그래프 시간대별 선택을 편리하게 제공해주는 time-slider control을 추가하였다. 이번 버전 역시 프리웨어로 제공된다. 자세한 업그레이드 내용은 다음과 같다.

1. Support MongoDB v2.2

  • New added “Lock Graph” Menu
    • Daemon-specific Lock Graph
    • DB-specific Lock Graph
    • Lock Graph by types
    • Group-specific Lock Graph
  • New Added “DB Graph” Menu
  • Support Daemon-specific information for MongoDB v2.2
  • Set option for switch function about MongoDB v2.0 and MongoDB v2.2

2. Improvement of Graph

  • Feature of date selection using slider control.
    • Support time-scaling function : 10 seconds, 1 minute, 5 minutes, 30 minutes, 1 hour.
    • Support Graph function : Accumulate Graph, Different Graph
  • Graph for Daemon detailed information
  • New added Graph function
    • Network In/Out Graph
    • Global Read/Write Graph
    • Lock Read/Write Graph
    • DB & Index Graph

3. Improvement of Dashboard

  • Added “Locks Sum” Graph
  • Global Lock Read/Write summary
  • DB Locks Read/Write summary

4. Improvement of Event

  • Support “Global Lock Read/Write” alert
  • Support “DB Locks Read/Write” alert

5. Converting Tool for previous version

  • Provide data converting tool for new version for user who using previous version (2.0.1)

ScreenShot

time-slider control in Graph

새롭게 첨가된 그래프 기능


  • Facebook
  • Twitter
  • Delicious
  • LinkedIn
  • StumbleUpon
  • Add to favorites
  • Email
  • RSS
Categories: 관리도구 Tags: ,