MongoDB GridFS 튜토리얼

2012.10.28 13:39

가을의 곰을... 조회 수:4079

 

 

 

 

MongoDB GridFS 튜토리얼

[출처] http://nodeqa.com/extend_ref/2

Introduction

MongoDB 안에 Large Objects 를 저장할 수 있는 파일시스템 입니다. 간단하게 파일을 저장하여 사용할 수 있고, MongoDB가 설치되어 있으면 자매품격으로 따라오는 녀석입니다. 저장방식은 1개의 파일당 MAX 2GB 사이즈까지 저장가능하며, 256k chunk 단위로 나누어져 저장합니다. 이는 chunks collections 에 나누어진 document 으로 저장됩니다. 이와 meta, filename, content type, 다른 옵션들은 files collection 에 저장됩니다. 즉 files collection 과 chunks collections 은 1:n 관계를 가진다.

Spec

GridFS 는 데이타를 저장하기 위해 2개의 collection 구성됩니다.

  • files : metadata 포함
  • chunks : binary chunks (BSON)

GridFS는 하나의 데이타베이스 안에서 네임스페이스를 가질 수 있습니다. 아무것도 지정하지 않은면 기본은 fs 이며, fs.files, fs.chunks Collection이 기본으로 생성됩니다.

2개의 collection 구성

files

files의 document 구조를 알아보겠습니다.

{
  "_id"        : <unspecified>,    // unique ID for this file
  "length"     : data_number,      // size of the file in bytes
  "chunkSize"  : data_number,      // size of each of the chunks.  Default is 256k
  "uploadDate" : data_date,        // date when object first stored
  "md5"        : data_string       // result of running the "filemd5" command on this file's chunks
}

위 내용은 기본적으로 생성되는 필드이며, 아래와 같이 임의로 지정한 여러필드를 추가할 수 있습니다.

{
  "filename" : data_string,               // human name for the file
  "contentType" : data_string,            // valid mime type for the object
  "aliases" : data_array of data_string,  // optional array of alias strings
  "metadata" : data_object,               // anything the user wants to store
}

파일 1개가 저장되면, files collection 에는 1개의 row가 입력됩니다.

chunks

files collection 과 1:n 으로 관계지어지는 collection 입니다.

경축! 아무것도 안하여 에스천사게임즈가 새로운 모습으로 재오픈 하였습니다.
어린이용이며, 설치가 필요없는 브라우저 게임입니다.
https://s1004games.com

{
  "_id"      : <unspecified>,         // object id of the chunk in the _chunks collection
  "files_id" : <unspecified>,         // 일명 files.id FK 라고 생각하면 됩니다.
  "n"        : chunk_number,          // 256k 단위 chunk의 순번입니다. (예) 1,2,3
  "data"     : data_binary,           // BSON binary 형태의 데이타입니다. 
}

files.id와 chunks.filesid 는 FK 형식으로 이어지는 구조입니다.

사용용도

제가 사용한 경우는 PostgreSQL 의 각종 로그정보를 Report (html)으로 자세하게 받아볼 수 있는 pgfouine을 사용하는 과정에서 이 데이타를 API 형식으로 확인하는 프로젝트에서 이용되었습니다.

API형식은 http://host/{hostname}/{date} 으로 되어 있어서, 수천대의 서버의 자세한 로그정보를 손쉽게 꺼내어 확인할 수 있었습니다.

Utility mongofiles

MongoDB 설치경로의 bin 디렉토리에 mongofiles 라는 명령어가 있습니다. 이것은 GridFS 에 간단하게 저장 및 삭제, 검색, 목록 등 많은 명령을 할 수 있는 도구입니다.

help

$ mongofiles -h
ERROR: required parameter is missing in 'host'

usage: mongofiles [options] command [gridfs filename]
command:
  one of (list|search|put|get)
  list - list all files.  'gridfs filename' is an optional prefix 
         which listed filenames must begin with.
  search - search all files. 'gridfs filename' is a substring 
           which listed filenames must contain.
  put - add a file with filename 'gridfs filename'
  get - get a file with filename 'gridfs filename'
  delete - delete all files with filename 'gridfs filename'
options:
  --help                  produce help message
  -v [ --verbose ]        be more verbose (include multiple times for more 
                          verbosity e.g. -vvvvv)
  --version               print the program's version and exit
  -h [ --host ] arg       mongo host to connect to ( <set name>/s1,s2 for sets)
  --port arg              server port. Can also use --host hostname:port
  --ipv6                  enable IPv6 support (disabled by default)
  -u [ --username ] arg   username
  -p [ --password ] arg   password
  --dbpath arg            directly access mongod database files in the given 
                          path, instead of connecting to a mongod  server - 
                          needs to lock the data directory, so cannot be used 
                          if a mongod is currently accessing the same path
  --directoryperdb        if dbpath specified, each db is in a separate 
                          directory
  --journal               enable journaling
  -d [ --db ] arg         database to use
  -c [ --collection ] arg collection to use (some commands)
  -l [ --local ] arg      local filename for put|get (default is to use the 
                          same name as 'gridfs filename')
  -t [ --type ] arg       MIME type for put (default is to omit)
  -r [ --replace ]        Remove other files with same name after PUT

TEST

// 파일을 생성합니다.
$ echo "Hello World" > testfile.txt

// testfile.txt를 GridFS에 입력합니다.
[root@nodejs:~]# mongofiles put testfile.txt 
connected to: 127.0.0.1
added file: { _id: ObjectId('501a6bba8714e1003494b283'), filename: "testfile.txt", chunkSize: 262144, uploadDate: new Date(1343908794415), md5: "e59ff97941044f85df5297e1c302d260", length: 12 }
done!

// GridFS에 저장되어 있는 파일 목록을 확인합니다.
$ mongofiles list
connected to: 127.0.0.1
testfile.txt    12

// 로컬에 저장되어 있는 testfile.txt 를 삭제합니다.
$ rm testfile.txt 
rm: remove 일반 파일 `testfile.txt'? y           

// 다시 해당 파일을 GridFS 으로부터 다운로드 하여 복구합니다.
[root@nodejs:~]# mongofiles get testfile.txt
connected to: 127.0.0.1
done write to: testfile.txt

// 다운로드된 파일을 확인합니다.
[root@nodejs:~]# cat testfile.txt 
Hello World

Collection 확인

위의 TEST 과정을 거치면 자동으로 fs.files, fs.chunks collection이 생성됩니다.

$ mongo
MongoDB shell version: 2.0.2
connecting to: test
> use test
switched to db test
> show collections
fs.chunks                  // 확인!
fs.files                   // 확인!
system.indexes

그럼 collections 의 데이타를 확인해보겠습니다.

# 이건가? 

> fs.files.find()
Thu Aug  2 21:11:46 ReferenceError: fs is not defined (shell):1

# 역시 에러네요. 오랜만에 mongodb를 ㅋㅋ 다시한번 

# testfile.txt의 정보를 확인할 수 있습니다.
> db.fs.files.find()
{ "_id" : ObjectId("501a6bba8714e1003494b283"), "filename" : "testfile.txt", "chunkSize" : 262144, "uploadDate" : ISODate("2012-08-02T11:59:54.415Z"), "md5" : "e59ff97941044f85df5297e1c302d260", "length" : 12 }

# n이 0부터 시작되고, data는 바이너리형태인것을 확인합니다.
# 그리고, files_id 는 ObjectId 형식으로 동일한 내용인것을 알 수 있습니다.
> db.fs.chunks.find()
{ "_id" : ObjectId("501a6bba7e0a7ee0226fb956"), "files_id" : ObjectId("501a6bba8714e1003494b283"), "n" : 0, "data" : BinData(0,"SGVsbG8gV29ybGQK") }

추가로 Python 에서 사용했던 소스

pymongo installation

python에서는 pymongo 를 추천합니다.

$ easy_install pymongo
Searching for pymongo
Reading http://cheeseshop.python.org/pypi/pymongo/
Reading http://github.com/mongodb/mongo-python-driver
Reading http://cheeseshop.python.org/pypi/pymongo/2.2.1
Best match: pymongo 2.2.1
Downloading http://pypi.python.org/packages/source/p/pymongo/pymongo-2.2.1.tar.gz#md5=b9e9f844208971f42862d5a205cab1c7
Processing pymongo-2.2.1.tar.gz
Running pymongo-2.2.1/setup.py -q bdist_egg --dist-dir /tmp/easy_install-vTfsvW/pymongo-2.2.1/egg-dist-tmp-uib8Bs
zip_safe flag not set; analyzing archive contents...
Adding pymongo 2.2.1 to easy-install.pth file

Installed /usr/lib/python2.4/site-packages/pymongo-2.2.1-py2.4-linux-x86_64.egg
Processing dependencies for pymongo

대략 이런 클래스

pgfouine 작업할 때 작성한 클래스입니다. 참고하세요.

!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
 * MongoGridFS Wrapper
 *
 * @author nanhapark
'''

# pymongo
from pymongo.connection import Connection
from pymongo.objectid import ObjectId
from gridfs import GridFS

# util
import types

class MongoGridFS:
  def __init__(self): pass
  def connect(self, host, port):
    if isinstance(port, types.StringType) == True:
      port = int(port)

    self.instanceConnection = Connection(host, port)

  def setDB(self, dbname):
    self.db = self.instanceConnection[dbname]

  def setGridFS(self, prefix = 'fs'):
    self.fs = GridFS(self.db, prefix)

  def put(self, data, **kwargs):
    self.fs.put(data, **kwargs)

  def get(self, filename):
    out = self.fs.get_last_version(filename)
    return out.read()


def main():
  # 객체생성
  o = MongoGridFS()

  # 접속
  o.connect('localhost', 27017)

  # db connect
  o.setDB('test')

  # GridFS 객체 생성
  o.setGridFS()

  # hello.txt 파일등록
  o.put('hello.txt', filename="hello.txt")

  # 가져오기
  ret = o.get('hello.txt')
  print ret

if __name__ == '__main__':
  main()

결론

pgfouine 프로젝트시에 어떻게 하면 html을 쉽게 저장 / 분산할 수 있을까 생각하다가, Mongodb GridFS를 알게 되었는데, 거창한 FileSystem 보다는 훨씬 심플하고 장난감(?) 같은 느낌이랄까요? 그럼 이만 감사합니다. KIN플하세요. ~~~

© Copyright Since 2012 nanhapark All Rights reserved.Licensed by nanhapark 크리에이티브 커먼즈 라이선스

본 웹사이트는 광고를 포함하고 있습니다.
광고 클릭에서 발생하는 수익금은 모두 웹사이트 서버의 유지 및 관리, 그리고 기술 콘텐츠 향상을 위해 쓰여집니다.
번호 제목 글쓴이 날짜 조회 수
211 아파치와 톰캣을 활용한 대용량 웹서비스 운영 file 가을의 곰을... 2013.01.02 3494
210 웹서버 부하 분산을 위한 허접한 로드밸런싱 가을의 곰을... 2013.01.02 4564
209 L4 로드밸런싱 설정 및 운용 file 가을의 곰을... 2013.01.02 3763
208 2D 가벼운 게임제작툴들 소개.... file 가을의 곰을... 2012.12.31 4722
207 java :: 자바실행 파일 만들기 file 가을의 곰을... 2012.12.30 3858
206 모바일 IP (Mobile IP) 가을의 곰을... 2012.12.26 3885
205 Metro Style App 프로그래밍 강좌 모음 file 가을의 곰을... 2012.12.25 4862
204 인텔이 바라본 '2013년 IT시장' file 가을의 곰을... 2012.12.23 3116
203 [알아봅시다] CCL 3.0 크리에티브 커먼스 unported 라이센스 file 가을의 곰을... 2012.12.04 7128
202 [기획-PCC] (1) ‘퍼스널 클라우드 컴퓨팅’이 다가온다 file 가을의 곰을... 2012.11.29 6666
201 HTML5, JavaScript, JQuery 강좌 모음 가을의 곰을... 2012.11.17 7757
200 HTML 5 동영상 강좌 가을의 곰을... 2012.11.17 3444
199 [펌] 하둡 전문가로 가는 길 : way to expert of Hadoop : big data tech 가을의 곰을... 2012.11.16 5537
198 NoSQL은 생각보다 쓸만하지 않다 file 가을의 곰을... 2012.11.11 5000
197 [기고]약정 벗은 안드로이드, 서버가 되다…'서품폰' file 가을의 곰을... 2012.11.04 6249
196 MongoDB에서 Java 응용 프로그램 개발하기 - 30분 가이드 file 가을의 곰을... 2012.10.28 9198
» MongoDB GridFS 튜토리얼 file 가을의 곰을... 2012.10.28 4079
194 웹 마이닝 요약 도큐먼트 : Web Mining Survey Document file 가을의 곰을... 2012.10.10 4337
193 [perl script] perl 사용 팁 file 가을의 곰을... 2012.10.10 4331
192 [파이썬] scrapy 로 웹 사이트 크롤링 가을의 곰을... 2012.10.09 11894
대표 김성준 주소 : 경기 용인 분당수지 U타워 등록번호 : 142-07-27414
통신판매업 신고 : 제2012-용인수지-0185호 출판업 신고 : 수지구청 제 123호 개인정보보호최고책임자 : 김성준 sjkim70@stechstar.com
대표전화 : 010-4589-2193 [fax] 02-6280-1294 COPYRIGHT(C) stechstar.com ALL RIGHTS RESERVED