【MongoDB是什么?】

MongoDB是一个基于分布式文件存储的数据库。由C++语言编写。旨在为WEB应用提供可扩展的高性能数据存储解决方案。

MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功能最丰富,最像关系数据库的。它支持的数据结构非常松散,是类似json的bson格式,因此可以存储比较复杂的数据类型。Mongo最大的特点是它支持的查询语言非常强大,其语法有点类似于面向对象的查询语言,几乎可以实现类似关系数据库单表查询的绝大部分功能,而且还支持对数据建立索引。

(注:以上内容选自百度百科)

其实Mongodb中有一个重要功能--GridFS,但并不为人所熟悉。本文主要讲解如何更好地使用GridFS功能,结合实践中的案例分享经验。

【Mongobd的重要模块--GridFS】

GridFS是Mongo的一个子模块,使用GridFS可以基于MongoDB来持久存储文件。并且支持分布式应用(文件分布存储和读取)。作为MongoDB中二进制数据存储在数据库中的解决方案,通常用来处理大文件,对于MongoDB的BSON格式的数据(文档)存储有尺寸限制,最大为16M。但是在实际系统开发中,上传的图片或者文件可能尺寸会很大,此时我们可以借用GridFS来辅助管理这些文件。

GridFS不是MongoDB自身特性,只是一种将大型文件存储在MongoDB的文件规范,所有官方支持的驱动均实现了GridFS规范。GridFS制定大文件在数据库中如何处理,通过开发语言驱动来完成、通过API接口来存储检索大文件。

<使用场景>

▲如果您的文件系统在一个目录中存储的文件的数量有限,你可以使用GridFS存储尽可能多的文件。

▲当你想访问大型文件的部分信息,却不想加载整个文件到内存时,您可以使用GridFS存储文件,并读取文件部分信息,而不需要加载整个文件到内存。

▲当你想让你的文件和元数据自动同步并部署在多个系统和设施,你可以使用GridFS实现分布式文件存储。

【GridFS存储原理】

GridFS使用两个集合(collection)存储文件。一个集合是chunks, 用于存储文件内容的二进制数据;一个集合是files,用于存储文件的元数据。

GridFS会将两个集合放在一个普通的buket中,并且这两个集合使用buket的名字作为前缀。MongoDB的GridFs默认使用fs命名的buket存放两个文件集合。因此存储文件的两个集合分别会命名为集合fs.files ,集合fs.chunks。

当然也可以定义不同的buket名字,甚至在一个数据库中定义多个bukets,但所有的集合的名字都不得超过mongoDB命名空间的限制。

MongoDB集合的命名包括了数据库名字与集合名字,会将数据库名与集合名通过“.”分隔(eg:<database>.<collection>)。而且命名的最大长度不得超过120bytes。

当把一个文件存储到GridFS时,如果文件大于chunksize (每个chunk块大小为256KB),会先将文件按照chunk的大小分割成多个chunk块,最终将chunk块的信息存储在fs.chunks集合的多个文档中。然后将文件信息存储在fs.files集合的唯一一份文档中。其中fs.chunks集合中多个文档中的file_id字段对应fs.files集中文档”_id”字段。

读文件时,先根据查询条件在files集合中找到对应的文档,同时得到“_id”字段,再根据“_id”在chunks集合中查询所有“files_id”等于“_id”的文档。最后根据“n”字段顺序读取chunk的“data”字段数据,还原文件。

存储过程如图下所示:

fs.files 集合存储文件的元数据,以类json格式文档形式存储。每在GridFS存储一个文件,则会在fs.files集合中对应生成一个文档。
▲fs.files集合中文档的存储内容如下:

fs.chunks 集合存储文件文件内容的二进制数据,以类json格式文档形式存储。每在GridFS存储一个文件,GridFS就会将文件内容按照chunksize大小(chunk容量为256k)分成多个文件块,然后将文件块按照类json格式存在.chunks集合中,每个文件块对应fs.chunk集合中一个文档。一个存储文件会对应一到多个chunk文档。
▲ fs.chunks集合中文档的存储内容如下:

为了提高检索速度 MongoDB为GridFS的两个集合建立了索引。fs.files集合使用是“filename”与“uploadDate” 字段作为唯一、复合索引。fs.chunk集合使用的是“files_id”与“n”字段作为唯一、复合索引。

【如何使用GridFS?】

<使用shell命令>
mongoDB提供mingofiles工具,可以使用命令行来操作GridFS。其实有四个主要命令,分别为:
put —存储命令
get —获取命令 
list —列表命令
delete —删除命令
这些命令都是按照filename操作GridFS中存储的文件的。

<使用API>
MongoDB支持多种编程语言驱动。比如c、java、C#、nodeJs等。因此可以使用这些语言MongoDB驱动API操作,扩展GridFS。

【经验分享】

▲ GridFs不会自动处理md5值相同的文件,也就是说,同一个文件进行两次put命令,将会在GridFS中对应两个不同的存储,对于存储来说,这是一种浪费。对于md5相同的文件,如果想要在GridFS中只有一个存储,需要通过API进行扩展处理。

▲ MongoDB 不会释放已经占用的硬盘空间。即使删除db中的集合 MongoDB也不会释放磁盘空间。同样,如果使用GridFS存储文件,从GridFS存储中删除无用的垃圾文件,MongoDB依然不会释放磁盘空间的。这会造成磁盘一直在消耗,而无法回收利用的问题。

那么怎样才能释放磁盘空间呢?

(1)可以通过修复数据库来回收磁盘空间,即在mongo shell中运行db.repairDatabase()命令或者db.runCommand({ repairDatabase: 1 })命令。(此命令执行比较慢)。

使用通过修复数据库方法回收磁盘时需要注意,待修复磁盘的剩余空间必须大于等于存储数据集占用空间加上2G,否则无法完成修复。因此使用GridFS大量存储文件必须提前考虑设计磁盘回收方案,以解决mongoDB磁盘回收问题。

(2)使用dump & restore方式,即先删除mongoDB数据库中需要清除的数据,然后使用mongodump备份数据库。备份完成后,删除MongoDB的数据库,使用Mongorestore工具恢复备份数据到数据库。

当使用db.repairDatabase()命令没有足够的磁盘剩余空间时,可以采用dump & restore方式回收磁盘资源。如果MongoDB是副本集模式,dump & restore方式可以做到对外持续服务,在不影响MongoDB正常使用下回收磁盘资源。

MogonDB使用副本集, 实践使用dump & restore方式,回收磁盘资源。70G的数据在2小时之内完成数据清理及磁盘回收,并且整个过程不影响MongoDB对外服务,同时可以保证处理过程中数据库增量数据的完整。

文章来自 http://rdc.hundsun.com/portal/article/703.html

MongoDB之GridFS相关推荐

  1. MongoDB:GridFS删除方法删除存储桶中的所有文件

    不久前,我们遇到了MongoDB GridFS的奇怪行为,这使我为MongoDB Java驱动程序创建了一个故障 单 . 今天,我在浏览器书签中找到了指向故障单的链接. 该票证目前尚未解决,因此我认为 ...

  2. 实验mongodb使用gridfs存放一个大文件

    1.启动mongoDB 2.使用gridfs存放大文件 3.观察fs.chunks和fs.files的情况 命令 db.fs.chunks.find()查到的是一些二进制文件: 转载于:https:/ ...

  3. MongoDB C++ gridfs worked example

    使用libmongoc,参考:http://mongoc.org/libmongoc/current/mongoc_gridfs_t.html #include <mongoc.h> #i ...

  4. Spring保存文件到MongoDB之GridFS支持

    为什么80%的码农都做不了架构师?>>>    问题 Spring上传来的文件,怎么保存到MongoDB中去类,这里暂时不考虑其他方案来保存文件,如文件系统,FTP等等之类的.假设, ...

  5. MongoDB(四)——GridFS

    GridFS MongoDB的一个重要子模块,可基于MongoDB来持久存储文件,并且支持分布式存储和读取. 持久存储:对应瞬时数据如内存,指保存到数据库中,能持久保存. 分布式存储:将数据分散地存储 ...

  6. java mongodb gridfs_MongoDB-4 GridFS 文件存储

    1. 配置config spring: data: mongodb: uri: mongodb://username:password@192.168.2.72:27017 database: myd ...

  7. .NET MongoDB Driver GridFS 2.2原理及使用示例

    一.API解读 1 GridFSBucketOptions 1)public string BucketName { get; set; } 获取或设置bucket名称 2)public int Ch ...

  8. 浅尝辄止MongoDB:GridFS

    一.为什么使用GridFS GridFS是MongoDB的一个子模块,使用GridFS可以基于MongoDB来持久存储文件,并且支持分布式应用(文件分布存储和读取).作为MongoDB中二进制数据存储 ...

  9. 第10周 Mongodb的GridFS与分片

    GridFS GridFS是一种将大型文件存储在MongoDB的文件规范. GridFS 规范提供了一种透明的机制,可以将一个大文件分割成为多个较小的文档.这将容许我们有效的保存大的文件对象,特别对于 ...

最新文章

  1. STL中的双向队列deque
  2. kettle 如何使用java代码
  3. C++ Primer 5th笔记(chap 16 模板和泛型编程)重载模板和类型转换
  4. 一种Android闪屏页实现方法(偏门别类)
  5. php 掌握jquery,完全掌握jquery tmpl模板
  6. Google Desktop 果然
  7. 漫话:如何给女朋友解释什么是2PC(二阶段提交)?
  8. Java中的时间和日期(下)
  9. 解决IP地址冲突的方法--DHCP SNOOPING
  10. HDU2008 数值统计【入门】
  11. 深入浅出讲解LDA主题模型(一)
  12. ORB_SLAM2探秘 第一章
  13. Linux学习笔记:wc查看文件字节数、字数、行数
  14. 分享一种MODIS数据下载方法
  15. jupyter notebook 拒绝连接 以及 查 IP
  16. 自主证件采集录入系统-嵌入式护照阅读器
  17. php silk v3 decoder,微信小程序语音搜索踩坑:silk文件格式转换,在PHP中使用
  18. 如何认识和投身 Web 3.0?
  19. python实现 Python蟒蛇绘制(嵩天老师 )
  20. 安装系统时出现“ 计算机意外地重新启动或遇到错误 ”

热门文章

  1. 单进程程序怎样在linux运行,linux下C程序:运行单个实例
  2. Lua虚拟机中的数据结构与栈
  3. WebService只能在本地使用,无法通过网络访问的解决办法
  4. WordPress Citizen Space插件跨站请求伪造漏洞
  5. html5 多文件选择
  6. wifi怎么设置找不到服务器,无线网 登入ip找不到服务器
  7. Redis之主从复制(Sentinel)
  8. PartitionStateMachine分析
  9. 怎样在html中显示时间,如何在网页上显示当前时间
  10. php实例化类的方法,在PHP中实例化类实例的不同方法