목표

  • GridFS의 개념익히기
  • java-mongodb 드라이버를 이용한 간단한 몽고디비 연동 및 GridFS 샘플

책에 나온 GridFS

  • 어플리케이션에서 이미지, 섬네일, 비디오등 이진파일을 저장하기위해 파일 시스템에 의지.
  • 파일 시스템은 액세스를 빠르게 해주지만, 수 만건 이상의 파일 관리시에 데이터 구조에 혼란을 초래함.
  • 파일의 메타 데이터는 데이터 베이스에 저장할 경우 실제 파일과 메타데이터간의 정확한 백업이 복잡해짐.
  • 파일 구조와 백업을 간단히 하기위해 파일을 데이터 베이스 자체에 저장하는 것이 합리적일 경우 사용.
  • 파일 하나당 하나의 도큐먼트를 사용하는 것은 소량(1MB이하)의 이진객체에 적합.
  • 대용량의 파일은 GridFS를 사용.

GridFS의 개념

  • GridFS는 BSON 문서 크기 제한인 16MB를 초과하는 파일을 저장하고 검색하기위한 기능.
  • GridFS는 파일을 하나의 문서에 저장하는 대신 파일을 여러 부분의 chunk로 나누고 각 chunk를 별도의 문서로 저장한다.
  • 기본적으로 GridFS는 255KB의 chunk를 사용한다.
  • GridFS는 파일 청크 콜렉션(bucket.chunks), 파일 메타 데이터 콜렉션(bucket.files)을 사용하여 파일을 저장한다.
  • GridFS에 파일을 쿼리하면, 드라이버는 필요에 따라 청크를 재조합한다.
  • GridFS를 통해 저장된 파일에 대해 범위 쿼리를 수행 할 수 있다.
  • 비디오 또는 오디오 파일의 중간으로 건너 뛰는 것과 같이 파일의 임의 섹션에서 정보에 액세스 할 수도 있다.
  • GridFS는 16MB를 초과하는 파일을 저장할 때, 전체 파일을 메모리에 로드하지 않고 액세스하려는 파일을 저장 할 수있다.
  • 버전 2.4.10에서 변경 : 기본 청크 크기가 256KB에서 255KB로 변경됨.

GridFS 사용시기

  • 시스템보다 큰 파일을 저장하는 것이 MongoDB 데이터베이스에서 더 효율적일 수 있다.
  • 파일 시스템이 디렉토리의 파일 수를 제한하는 경우, GridFS를 사용하여 필요한만큼의 파일을 저장할 수 있다.
  • 일부 정보에 액세스하려는 경우 GridFS를 사용하여 전체 파일을 메모리로 읽지 않고 필요한 파일 섹션을 호출 할 수 있다.
  • 파일 및 메타 데이터를 여러 시스템 및 시설에 자동으로 동기화 및 배포하려는 경우 GridFS를 사용할 수 있다.
  • 분산 된 복제 세트를 사용할 때, MongoDB는 여러 mongod 인스턴스와 기능에 파일과 메타 데이터를 자동으로 배포 할 수 있다.
  • 전체 파일의 내용을 원자 적으로 업데이트해야하는 경우 GridFS 사용을 권장하지 않음.
  • 대안으로 각 파일의 여러 버전을 저장하고 메타 데이터에 파일의 현재 버전을 지정 한다.
  • 새 파일을 업로드 한 후 “최신”상태를 나타내는 메타 데이터 필드를 업데이트하고 필요하면 이전 버전을 제거.
  • 파일 크기가 16MB보다 작 으면 GridFS를 사용하는 대신 단일 문서에 파일을 수동으로 저장하는 것이 좋다.
  • BinData 데이터 형식을 사용하여 이진 데이터를 저장할 수 있다.
  • BinData 사용에 대한 자세한 내용은 드라이버 설명서를 참조하십시오.

몽고디비 연동 및 GridFS 샘플

  • java-mongodb 드라이버연동
//클라이언트 연결
MongoClient client = new MongoClient("localhost");
//데이터베이스 선택
MongoDatabase database = client.getDatabase("tutorial");
//컬렉션 선택
MongoCollection<Document> collection =  database.getCollection("numbers");
  • GridFS 샘플
//GridFS가 생성될 컬렉션 이름
final String bucket = "test";
//GridFS를 이용해 저장할 파일명
final String filename = "test.JPG";		 
//bucket명으로 지정한 GridFS연결 생성
GridFSBucket gridFSBucket = GridFSBuckets.create(database,bucket);
//사용자 정의 metadata에 저장될 샘플 BsonDocument
ObjectId etag = new ObjectId();
BsonDocument metadata = new BsonDocument();
metadata.put("_etag", new BsonObjectId(etag));
 
GridFSUploadOptions options = new GridFSUploadOptions().metadata(Document.parse(metadata.toJson()));
//GridFS를 이용해 저장할 파일 InputStream 생성
InputStream sourceStream = MongoConnector.class.getResourceAsStream(filename);

//GridFS를 이용해 파일 저장 후 _id값 받아오기	         
ObjectId _id = gridFSBucket.uploadFromStream( filename, sourceStream, options);
//저장된 _id값 출력
System.out.println(_id);
  • mongodb에서 확인
//생성된 GridFS 컬렉션 확인
> show tables;
numbers
test.chunks
test.files
//생성된 chunk 수 확인
> db.test.chunks.count()
25
//저장된 file 정보 확인
> db.test.files.find().pretty()
{
        "_id" : ObjectId("58477396f034dd1b840b32d4"),
        "filename" : "test.JPG",
        "length" : NumberLong(6341811),
        "chunkSize" : 261120,
        "uploadDate" : ISODate("2016-12-07T02:27:35.304Z"),
        "md5" : "48b2a854b5deb75370fcaaef52c865e6",
        "metadata" : {
                "_etag" : ObjectId("58477396f034dd1b840b32d3")
        }
}
>
  • 저장된 GridFS를 이용해 파일 가져오기
//bucket명으로 지정한 GridFS연결 생성
GridFSBucket downloadGridFs = GridFSBuckets.create(database,bucket);
//지정된 파일명에 해당하는 id가져오기
ObjectId fid = downloadGridFs.find(Filters.eq("filename", filename)).first().getObjectId();
//가져온 파일을 d:/mongo.JPG에 저장
downloadGridFs.downloadToStream(fid, new FileOutputStream(new File("d:/mongo.JPG")));