我们先看下MongoDB存储小文件系统的例子:

先采用MongoDB的mongofiles执行文件上传:

通过mongos命令查看文件存储情况:

  1. switched to db test
  2. > show collections
  3. fs.chunks
  4. fs.files
  5. restaurants
  6. user
  7. > db.fs.files.find()
  8. { "_id" : ObjectId("58bcf683afa0fa20bc854a2b"), "chunkSize" : 261120, "uploadDat
  9. 99fff57c8a54d3adf78b", "filename" : "E:\\deliveryTask.doc" }

可以看到文件上传成功了

上传一个大于16MB的文件试一试:

通过mongos命令查看文件存储情况:

  1. > db.fs.files.find()
  2. { "_id" : ObjectId("58bcf683afa0fa20bc854a2b"), "chunkSize" : 261120, "uploadDate" : ISODate("2017-03-06T05:41:23.604Z"), "length" : 2971, "md5" : "5434b803306299fff57c8a54d3adf78b", "filename" : "E:\\deliveryTask.doc" }
  3. { "_id" : ObjectId("58bd02a7afa0fa21d4a14b2c"), "chunkSize" : 261120, "uploadDate" : ISODate("2017-03-06T06:33:12.013Z"), "length" : 24183487, "md5" : "bbfe4d8579372aa0729726185997e908", "filename" : "E:\\synch.rar" }

也成功了,

查看chunks:

下面分别是查询、下载、删除操作:

  1. D:\MongoDB\Server\3.2\bin>mongofiles.exe search rar
  2. 2017-03-06T14:45:31.974+0800 connected to: localhost
  3. E:\synch.rar 24183487
  4. 2017-03-06T14:47:17.841+0800 connected to: localhost
  5. finished writing to D:\mongodb_download.rar
  6. D:\MongoDB\Server\3.2\bin>mongofiles.exe delete E:\synch.rar
  7. 2017-03-06T14:47:56.649+0800 connected to: localhost
  8. successfully deleted all instances of 'E:\synch.rar' from GridFS
  9. D:\MongoDB\Server\3.2\bin>mongofiles.exe list
  10. E:\deliveryTask.doc 2971

实际上,我们还可以自定义集合的前缀,默认是fs,或者设置chunk的大小,默认是256KB。

那么在实际场景的分布式文件存储系统中如何确定改用哪种存储方案呢,可以采用如下方式:

  1. 对于用户上传的任何文件,在客户端进行大小判断;
  2. 当文件大小小于16MB时,则直接存储到MOngoDB普通集合中
  3. 当文件大小大于16MB时,上传到GridFS中,利用集合fs.files以及fs.chunks来保存文件
  4. 当用户下载文件时,再根据不同文件的大小属性不同到不同的集合中查找

另外,对于fs.chunks文件我们可以分片存储,片键可以选择索引字段{“files_id”},该字段尽量保证了此文件在所有被分割的chunk都在同一个片上,fs.files不需要分片,此集合只保存文件的元数据信息,数据量不大,同时还可以设置默认块大小(256KB)

需要注意的另一点是:文件分块大小为256KB,而分片的块大小默认64MB,不要搞混了。