php7 mongodb gridfs,第7回 GridFS——在MongoDB中保存大容量文件的方法

01fac6460a22031b8af8da5848698a70.png

GridFS的概要

能在MongoDB中保存的Document尺寸一般有最大16Mbyte的限制。这对于保存一般的文本文件是非常足够的尺寸,但要保存一些巨大的文本文件以及视频等Binary data时,就会出现超出16Mbyte的情况。想在MongoDB中保存16Mbyte以上的文件时,通过使用GridFS这种接口,可以将数据进行多个分割来进行保存。这次,我将解说处理MongoDB中处理大尺寸文件的功能——GridFS。

GridFS的概要图

TH400_001.jpg

图:左青:大文件 左蓝:girdFS interface(mongofile或者是driver) 黄:1.将文件分割到chunk中,写入文件。 2.文件的元数据(文件名、尺寸等等)的写入

上图例:文件 collection

右Mongod以下:chunk用collection、Binary data、Binary data、Binary data、元数据用collection、元数据。

被分割的数据我们称之为chunk,作为Binary data保存在Document中。

用数据库来管理文件的优点

话说回来,用数据库管理文件有怎样的好处呢。

在大部分系统之中,图片/音频/视频等大尺寸Binary data使用OS的文件系统进行保存。使用文件系统的话,就能用用习惯的接口访问文件。但是根据情况不同,文件被保存在数据库中,管理起来就会更有效率。以下我试着整理了用数据库来管理文件的优点。

元数据管理简便

不仅是文件,也能通过数据库对文件相关的元数据进行同时管理。比如,文件的尺寸与制成者,制成时间等。视频文件的话也可以管理播放次数。在数据库中与文件相关的元数据也非常简便,有扩张性。另外,包含元数据的备份也很容易。

不受文件系统的上限限制

在OS中,对文件数以及目录数有上限。比如,ext3的情况下,目录内的子目录以及文件数的上限是32000。

试着简单操作下gridFS吧

在MongoDB中使用GridFS不需要特别的设定以及使用方法。基于Replica set/ sharding也可以使用。那么让我们来试着使用GridFS在MongoDB中保存文件吧。

这次我们使用在MongoDB标准版准备的Command-line tool——mongofiles。命令的选项我们将在下章进行详细说明。

首先作成用1MB.file这个文件名保存的文件。在下面的例子中作成文件尺寸1MB。

$ dd if=/dev/zero of=1MB.file bs=1M count=1

使用mongofiles,在girdtest这个数据库中保存刚刚制成的1MB的file。

$ mongofiles -v -d gridtest put 1MB.file

Wed Feb 20 15:23:27 creating new connection to:127.0.0.1:27017

Wed Feb 20 15:23:27 BackgroundJob starting: ConnectBG

Wed Feb 20 15:23:27 connected connection!

connected to: 127.0.0.1

added file: { _id: ObjectId('51246bdfa3264162c8e99716'),

filename: "1MB.file", chunkSize: 262144,

uploadDate: new Date(1361341409698),

md5: "b6d81b360a5672d80c27430f39153e2c",

length: 1048576 }

done!

运行结果如上所示的话就代表保存成功了。

关于collection结构

让我们从mongo shell开始确认GridFS的collection吧。连接mongoDB选择girdtest数据库。

$ mongo> use gridtest

确认collection。

> show collectionsfs.chunksfs.filessystem.indexes

Index之外,也有fs.chunks以及fs.files这样的collection。各自的功能分别如下所示。

fs.chunks

GridFS中,将文件作为chunk在一定尺寸中分割,保存在fs.chunks collection中。分割文件的默认尺寸是256KB。

fs.files

在fs.files collection中保存着文件名、上传时间,MD5 hash信息、文件尺寸等元数据。可以追加任意元数据。

关于被保存的元数据在官方document中有详细信息。

在下一章中,我将说明GridFS的两种操作方法:mongofiles以及ruby driver。

使用mongofiles的GridFS的操作

Mongofile是MongoDB标准版中准备的命令行工具。在安装了MongoDB的目录的bin之中。使用这个mongofiles,来试着操作GridFS吧。

各命令共通的命令行工具

V选项输出了详细内容

用d选项指定数据库名

追加文件

要追加文件就应该使用put。在此,我们在gridtest数据库中追加1MB.file这个文件。

$ mongofiles -v -d gridtest put 1MB.file

即使用同样文件名追加的,只要不被覆盖,就能作为别的object来追加。覆盖的情况时,请指定-r 选项。

$ mongofiles -v -d gridtest -r put 1MB.file

取得文件

文件的取得请使用get

$ mongofiles -v -d gridtest get 1MB.file

有同样文件名的情况,可以取得之后追加的项目。

文件的list表示

要将文件表示成表,请使用list。可以显示文件名以及文件尺寸。有同样文件名的情况下,被表示成复数。在下例中,1MB.file这个名字的文件记录了2个。

$ mongofiles -v -d gridtest list

Wed Feb 20 16:08:01 creating new connection to:127.0.0.1:27017

Wed Feb 20 16:08:01 BackgroundJob starting: ConnectBG

Wed Feb 20 16:08:01 connected connection!connected to: 127.0.0.1

1MB.file 1048576

1MB.file 1048576

image01.png 524288

image02.png 262144

删除文件

文件的删除使用delete。。

[注意]

同样文件名的数据会被全部删除,请大家注意。

$ mongofiles -v -d gridtest delete 1MB.file

文件搜索

文件的搜索使用search。指定的文字列包含文件名的情况下,会被显示。

$ mongofiles -v -d gridtest search 1MB

使用ruby的GridFS的操作

通过使用 ruby用MongoDB官方driver,可以从Ruby操作GridFS。Driver可以从gem开始安装。

$ gem install mongo

虽然不是必要的,同样地在gem中安装bson_ext的话,可以实现BSON处理的高速化。

$ gem install bson_ext

首先进行准备。要从Ruby中处理GridFS的话,需要在fs.chunks中制成index。通过在mongofiles中登陆文件,可以自动制成index。

$ dd if=/dev/zero of=1MB.file bs=1M count=1$ mongofiles -d gridtest put 1MB.file

以下是对于gridtest数据库进行取得与保存,最后删除的脚本。追加文件时,可以登陆任意元文件。

require 'mongo'

db_name = "gridtest"

@con = Mongo::Connection.new

@db = @con[db_name]

@grid = Mongo::Grid.new(@db)

@collection = @db["fs.files"]

file_id = @grid.put(File.binread("1MB.file"),

:filename => "1MB.file",

:tags => ["mongo","database","book"],

:memo => "sample file",

:owner => "mongonouchi")

puts "get file_id=#{file_id}"

puts "filename = #{@grid.get(file_id).filename}"

puts ""

@collection.find({:_id => BSON::ObjectId(file_id.to_s)}).each{ |doc|

puts doc.inspect

}

puts ""

puts "delete file_id=#{file_id}"

@grid.delete(file_id)

上述作为grid_sample.rb保存,以下是输出例。为了大家方便看,我分行写的。被输出的file_id根据环境发生改变。

$ ruby grid_sample.rb

get file_id=512ac8a2af1fe66a0e000001

filename = 1MB.file

{"_id"=>BSON::ObjectId('512ac8a2af1fe66a0e000001'),

"filename"=>"1MB.file",

"contentType"=>"binary/octet-stream",

"length"=>1048576,

"chunkSize"=>262144,

"uploadDate"=>2013-02-25 02:12:50 UTC,

"md5"=>"b6d81b360a5672d80c27430f39153e2c",

"tags"=>["mongo", "database", "book"],

"memo"=>"sample file",

"owner"=>"mongonouchi"

}

delete file_id=512ac8a2af1fe66a0e000001

其他工具

Mongofiles,在官方driver中也开发了其他能操作GridFS的工具。在此我们省略详细接受,有从Nginx开始直接GridFS操作的nginx-gridfs。

下次的主题

这次介绍了在MongoDB中处理大尺寸文件的GridFS。通过使用GridFS,图片以及动画等大文件也可以通过MongoDB来进行管理。

下次我想介绍就快发售的MongoDBv2.4的新功能。在MongoDB中追加了全文搜索,GeoJSON对应,hash document等先进功能。请大家多多期待。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值