GridFS 란?

cointreau·2022년 10월 18일

GridFS 란?

  • MongoDB 내 large objects 를 저장할 수 있는 파일 시스템


❓ 저장 방법

  1. 파일당 2gb 까지 저장이 가능
  2. 256kb 의 청크 단위로 나뉘어 저장이 되며, 마지막 청크는 필요에 따라 커질 수도 있음
  3. 파일을 저장하기 위해 2개의 collection 을 사용하며, files 의 document :chunks 의 document = 1:n 매핑
    1. files: 메타 정보를 담는 컬렉션(_id, filename, length, chunkSize, uploadDate 및 기타 arguments)
    2. chunks: 파일 청크를 포함하는 컬렉션(files_id(files 의 _id와 동일), payload...)


❓ 사용 툴

❓ 장점

  1. 👍 속도에 있어서 file system 보다 10% 정도 느리지만, 실시간으로 사용할 수 있을 만큼 빠르다고 함(stackoverflow 발...)
  2. 👍 mongodb 에 내장된 replication/backup 을 사용할 수 있음
  3. 👍 파일이 청크 단위로 나뉘기 때문에 파일을 모두 로드하지 않고 특정 부분에 access 해서 사용하기 좋음(streaming, 메모리 집약적인 task...)
  4. 🙄 우리 서비스에서는, UI 는 몰라도 BE 에서 특정 부분만 access 해서 사용할 일은 없을듯...


❓ 운영

  1. 🙄 서버 용량이 넉넉하지 않은데 괜찮을지.... 단순 document 만 저장해서 사용할 때는 document 당 용량이 작으니까 저장 정책에 대해 신경쓰지 않았는데 gridfs 를 이용해서 대용량의 파일을 db 서버에서 관리할 시 저장정책에 대해 신경쓰지 않을 수 없음

  2. 아래 내용은 gridFS 뿐 아니라, mongodb 자체에 대한 것

    RDBS 는 delete 시 물리적인 디스크 공간이 확보되지만, mongodb 는 remove 로 document 를 삭제하거나 collection 을 drop 해도 실제 디스크의 물리적인 공간이 확보되지 않는다. mongodb 는 디스크를 미리 할당해서 사용하는 방식인 storage engine 방식을 사용하기 때문. 따라서 실제 확보를 위해서는...

    db.repairDatabase() 를 통해 백업 세트를 복제하여 재구성: 현재 내용을 복제를 한 뒤 재구성을 하는 거라서 현재 디스크 사용량의 2배가 필요하고 실행시간이 길며, 재구성 중 lock 이 걸림

    collection 마다 compact 명령을 수행: 2gb 정도 필요하며, 이미 할당되었던 공간의 파편화를 정리하여 사용가능하게 해주는 방식으로, 실제 가용 용량이 늘어나지는 않는다고 함
    TTL Index: 약간 결이 다른 내용인데, 일정 시간이 지나면 document 를 자동으로 삭제하도록(백그라운드 작업) 애초에 collection 을 구성하는 것. 단 이는 gridfs 에는 적합하지 않아보임(컬렉션이 files, chunks 로 분리되어 있고, files 에서만 TTL Index 를 만들어서 삭제한다고 해봐야 실제 데이터에 해당하는 chunks 에는 남아있으므로 의미가 없음)



❓ How to use?(with pymongo)

from pymongo import MongoClient
from gridfs import GridFS


# database 연결 및 생성

client = MongoClient(host='localhost', port=27017)

mydb = client['cointreau']
client.list_database_names()

['admin', 'local', 'cointreau']

# gridFS 객체 생성
client.fs = GridFS(mydb)


# file 을 binary 형태로 읽어서 db에 저장
with open('./abcd.jpg', 'rb') as data:
    # filename 이 별로 의미가 없는듯, 임의의 parameter user/jobid 을 추가로 넣어서 이걸 바탕으로 확인 가능
    uid = client.fs.put(data, filename='abcd.jpg', user='cointreau', jobid='1234')
uid

ObjectId('634cec9bba27109b61ef6b8e')

# file name으로 file get
print('## 파일 리스트')

file_lst = list(client.fs.find())
for ID in file_lst:
    print(ID._id, ID.filename)

# 특정 field 로 get

print('\n## 특정 field로 get')
for ID in client.fs.find({'user': 'yun'}):
    print(ID._id, ID.filename, ID.user, ID.jobid)

## 파일 리스트
634cec9bba27109b61ef6b8e abcd.jpg

## 특정 field로 get
634cec9bba27109b61ef6b8e abcd.jpg cointreau 1234

# delete 는 파일 id 로 할 수 있음, 여기서만 지우면 files/chunks 컬렉션에서 모두 지워짐.
client.fs.delete(file_lst[0]._id)




참조 사이트
https://comphy.tistory.com/m/879
https://severalnines.com/blog/storing-files-mongodb-gridfs/
https://studio3t.com/knowledge-base/articles/mongodb-gridfs/
https://parkingcloud.github.io/skills/skills_mongodb/

0개의 댓글