GridFS是一种在MongoDB中存储大二进制文件的机制。使用GridFS存文件有如下几个原因:
利用Grid可以简化需求。要是已经用了MongoDB,GridFS就可以不需要使用独立文件存储架构。
GridFS会直接利用业已建立的复制或分片机制,所以对于文件存储来说故障恢复和扩展都很容易。
GridFS可以避免用于存储用户上传内容的文件系统出现的某些问题。例如,GridFS在同一个目录下放置大量的文件是没有任何问题的。
GridFS不产生磁盘碎片,因为MongoDB分配数据文件空间时以2GB为一块。
使用场景:如果你的系统有如下情景:
1) 有大量的上传图片(用户上传或者系统本身的文件发布等)
2) 文件的量级处于飞速增长,有可能打到单机操作系统自己的文件系统的查询性能瓶颈,甚至超过单机硬盘的扩容范围.
3) 文件的备份(不适用gridfs这种三方也可以做,但是不尽方便),文件系统访问的故障转移和修复..
4) 文件的索引,存储除文件本身以外还需要关联更多的元数据信息(比如,不仅仅存储文件,还要保存一些文件的发布式作者/发布时间/文件tag属性等等自定义信息)并且需要索引的...
5) 基于4),对文件的分类模糊,如果采用操作系统的文件系统,文件夹分类关系混乱或者无法分类时..
6) 当前系统是基于web的,对图片的访问根据url了规则路由的..(普通文件系统也可以)
7) 文件尺寸较小,而且众多,且文件有可能被迁移/删除等..
在Mongodb中以GridFSB方式存放文件有两种方式:
1、命令行方式mongofiles 2、客户端驱动编程
1、命令行方式mongofiles
mongofiles命令行下向Mongodb数据库中插入文件数据。
mongofiles -host 127.0.0.1:27017 -d mydb put 文件名
向数据库mydb中插入一个文件,其中put为命令,表示向Mongodb中上传文件,get、delete分别表示取得文件和删除文件。
执行 db.fs.files.find()即可看到GridFS中的文件列表.
mongo自带有一个实现mongofliles,基本操作如下: 列出所有文件: mongofiles list 上传一个文件: mongofiles put xxx.txt 下载一个文件: mongofiles get xxx.txt 查找文件: mongofiles search xxx //会查找所有文件名中包含“xxx”的文件 mongofiles list xxx //会查找所有文件名以“xxx”为前缀的文件 参数说明: �Cd 指定数据库 ,默认是fs,Mongofiles list �Cd testGridfs -u �Cp 指定用户名,密码 -h 指定主机 -port 指定主机端口 -c 指定集合名,默认是fs -t 指定文件的MIME类型,默认会忽略
2、使用API来存取文件
我一般用python调用pymongo管理mongodb的聚集
这个是国外的一篇pymongo管理gridfs的文档,写的还行。
http://blog.pythonisito.com/2012/05/gridfs-mongodb-filesystem.html
很多时候我们可以搭配nginx用,让nginx直接读取gridfs的文件。
安装nginx-gridfs wget https://download.github.com/mdirolf-nginx-gridfs-v0.8-0-gb5f8113.tar.gz tar �Czxvf mdirolf-nginx-gridfs-v0.8-0-gb5f8113.tar.gz mv mdirolf-nginx-gridfs-v0.8-0-gb5f8113 mdirolf-nginx-gridfs-v0.8 wget https://download.github.com/mongodb-mongo-c-driver-v0.3-0-g74cc0b8.tar.gz tar �Czxvf mongodb-mongo-c-driver-v0.3-0-g74cc0b8.tar.gz mv mongodb-mongo-c-driver-v0.3-0-g74cc0b8/* mdirolf-nginx-gridfs-v0.8/mongo-c-driver rm �Crf mongodb-mongo-c-driver-v0.3-0-g74cc0b8 安装nginx,指定nginx-gridfs目录与nginx联合编译 wget http://nginx.org/download/nginx-1.0.1.tar.gz tar �Czxvf nginx-1.0.1.tar.gz cd nginx-1.0.1 ./configure --prefix=/usr/local/nginx --with-openssl=/usr/include/openssl --with-http_stub_status_module --add-module=/home/cdh/Downloads/mdirolf-nginx-gridfs make �Cj8 sudo make install �Cj8 配置nginx-gridfs location /pics/ { gridfs pics field=filename type=string; mongo 127.0.0.1:27017; } gridfs:nginx识别插件的关键字 pics:db名 [root_collection]: 选择collection,如root_collection=blog, mongod就会去找blog.files与blog.chunks两个块,默认是fs [field]:查询字段,保证mongdb里有这个字段名,支持_id, filename, 可省略, 默认是_id [type]:解释field的数据类型,支持objectid, int, string, 可省略, 默认是int [user]:用户名, 可省略 [pass]:密码, 可省略 mongo:mongodb url http://localhost/pics/photo.jpg 能下载图片就说明成功了
gridfs 都是应用到偏海量,又不到海量的文件需求场景下的,不然咱们也不会花这么多功夫来搞这个了。
在这种需求下,可以用分片和主从把压力分切开。
mkdir -p /data/shard/s0 mkdir -p /data/shard/s1 mkdir -p /data/shard/log mkdir -p /data/shard/config #启动shard server ./mongod --shardsvr --port 20000 --dbpath /data/shard/s0 --fork --logpath /data/shard/log/s0.log --directoryperdb ./mongod --shardsvr --port 20001 --dbpath /data/shard/s1 --fork --logpath /data/shard/log/s1.log --directoryperdb #启动配置服务器config server ./mongod --configsvr --port 30000 --dbpath /data/shard/config --fork --logpath /data/shard/log/config.log --directoryperdb #启动route server mongos mongos --port 40000 --configdb localhost:30000 --fork --logpath /data/shard/log/route.log --chunkSize 1 #添加分片 ./mongo admin --port 40000 #链接mongos db.runCommand({addshard:"localhost:20000"}) #添加分片1 db.runCommand({addshard:"localhost:20001"}) #添加分片2 db.runCommand({enablesharding:"test"}) #设置test库开启分片 db.runCommand({shardcollection:"test.users",key:{_id:1}}) #设置test.users集合分片和分片的主键 #验证sharding use test #插入50万数据 for(var i=1;i<=500000;i++) db.users.insert({age:i,name:"zx",addr:"beijing",country:"china"}) db.users.stats() #查看users的分片情况
本文出自 “峰云,就她了。” 博客,谢绝转载!