MongoDb果然是个好东西. 我在最近的一个项目实践中, 实验性的用到了这个东西.
在测试中,对于GridFS相当满意. 首先, 和传统的MogileFS不同, gridfs可以和其它的meta数据部署在同一个
db中,默认的会为gridfs的collection分别创建fs.files和fs.chunks.
当存储一个文件时,可以附加存入任意的附加信息,因为这些信息实际上也是一个普通的collection.
这个特性给我们省了好多的事情. 以前,如果要存储一个附件,通常的做法是,在主数据库中存放文件的属性,并且记录
文件的path.当查询某个文件时,需要首先查询数据库,获得path,然后从存储系统中获得相应的文件.
在使用gridfs时,则非常简单, 我们可以直接将这些信息直接存储到文件中. 比如下面的PHP代码,存储上传的文件到gridfs:
public function store($file,$attrs=array()) {
if (!is_file($file)) {
throw new CZone_Core_Service_Exception("File:$file not exists");
}
$defaults = array(
'content_type'=> null,
'art_id'=>-1,
'state' => self::STORE_STATE_TMP,
'created_on' => time(),
'is_thumb'=> false,
'md5'=> md5_file($file)
);
$asset_attrs = $attrs+$defaults;
if (!isset($asset_attrs['content_type'])) {
$asset_attrs['content_type'] = Doggy_Util_File::mime_content_type($file);
}
$fs = $this->db->get_fs();
return $fs->storeFile($file,$asset_attrs);
}
调用store时,可以附件任意属性数组. 之后, 检索文件时则可以根据这些属性来查找:
public function fetch_by_id($id) {
return $this->fetch(array('_id'=>$id));
}
public function delete_by_id($id) {
return $this->delete(array('_id'=>$id));
}
public function delete_art_assets($art_id) {
return $this->delete(array('art_id'=>$art_id));
}
public function delete_asset($asset_id) {
return $this->delete_by_id($asset_id) && $this->delete_asset_thumbs($asset_id);
}
public function delete($options) {
if (isset($options['_id'])) {
$options['_id'] = Doggy_Mongo_Db::id($options['_id']);
}
$fs = $this->db->get_fs();
return $fs->remove($options);
}
public function find_all($query=array(),$fields=array()) {
return $this->db->fs_find($query,$fields);
}
使用gridfs,可以把原先复杂的操作变得相当简单, 真正实现了mogodb设计者的想法,
数据库为什么不能做文件系统?
在实践中,我发现GridFS和之前研究的MogileFS一些基本方式其实是相通的. 只不过, mogilefs的存储节点是
使用了简化版本的DAV 而已.
从这个角度,完全可以设计一个基于mongo gridfs的mogilefs.
至于性能, 从我的体会来说, 还不错. 毕竟我的项目的目前看存储仅限于TB级别.
不过在生产环境中,国外有用于存储视频流的.
GridFS的一个优点是可以存储上百万的文件而无需担心扩容性.
通过同步复制,可以解决分布式文件的备份问题.
目前,mongo支持主-从和Replica Pairs以及受限的Master-Master Replication.
比较实用的还是前2种.
通过ARP-ping可以实现一个双机热备切换,类似我正在用的mysql的mmm.
在实验过后,感觉使用mongo是非常轻松. 很轻松就解决了高并发中经常会遇到的问题,
比如实时的日志处理,实时的统计,更新某个字段.
通过使用mongo的capped collection,可以实现cache, message queue等特性,无需附加成本.
还有share session.
部署
gridfs的部署的选择方案不多,大概有以下几种:
1. 通过mongo client 的script, 比如PHP.
优点是简单,缺点是每次都要读取mongo数据库. 虽然mongo的性能不错,但是似乎总是不忍.
另外,像PHP的DRIVER并不支持HTTP RANGE header,这样就无法支持断点续传.
2.使用Nginx module
http://github.com/mdirolf/nginx-gridfs
这是gridfs的nginx module. 可以通过nginx直接访问读取mongo gridfs中的文件.
和nginx对应的mogilefs module类似.
优点: 由于直接通过nginx,速度是最快的.
缺点: 只能通过file_path来查找,目前不支持_id来查找.因此必须在file_path上建立索引.
优化方案:
我自己构想了以下的优化方案:
1. squid/varnish+script-backend
在nginx前端加上一个squid或者varnish作为反向加速. 如果没有则通过 PHP脚本来获取.
应用场景: 特别适合读取频繁的文件,比如用户的头像,热门图片,缩略图等. 不适合大文件.
缺点: 文件的过期必须正确设置. 此外配置好varnish或者squid
2. 基于proxy_store或fastcgi-cache, try_files
这种方案的应用场景同1, 但都是使用nginx的相应模块即可实现.
通过对fastcgi/proxy进行cache或store,就可以实现文件按需存储.
当使用proxy_store时,当后端文件变动时,需要purge这些文件.实现起来不难.
对于大文件,我觉得性价比比较高的一个方案是:
使用Perl或者PHP写一个脚本作为fastcgi运行. 前端用nginx进行负载均衡.
如果使用Pelr则当前driver支持随机读取,支持断点续传. 用PHP则需要做个简单处理,
手动判断HEADER,并计算出offset,然后再读取相应的字节流.
注意,如果是用PHP,则最好的方案是单独编译一个PHP,仅保留”最基本”的特性.
这样,可以节省很多的资源占用,稳定性和速度也比较好.我建议的保留的特性有:
json+mongo+spl.
PHP driver要比Perl更为成熟,虽然二者核心开发者都是一个人. Perl目前还是beta,也没有特别
广泛的使用,但据说由于大部分使用的是PHP的C代码,所以还是非常可靠的.
其他一些信息:
1.通过runcommand可以直接在mongodb端运行处理脚本. 比如像mapreduce,或者一些需要读取数据然后进行处理的.
这些command则是使用javascript方式来编写的,很容易. 好处就是避免了数据在服务端和客户端之间的读取和传输,
提高效率.
2. sharding
sharding在目前开发版中已经具备,但还不成熟. 但是可以自己实现sharding比较好.因为目前的sharding还是比较硬性的.
3.灵活使用magic操作符和upsert,比如$inc,$all,$in 等等
这些轻松解决一些麻烦的操作.
3.其他的复制方案
对于文件系统, 其实可以通过一个脚本来定期将文件复制到其他的节点. 实现类似mogilefs的功能.
http://www.iteye.com/articles/1800
转载自:http://hi.baidu.com/wdxzas/blog/item/d798298b4c47e81ec8fc7a88.html
分享到:
相关推荐
文件收集 注意! 从2018年1月1日开始,此项目将进入“维护模式”。 这意味着我将不再通过github问题实现任何新功能或提供调试帮助或“一般支持”。 我将(在一段时间内)仍然考虑实现错误修复和通常有用的新的次要...
MongoDB 的 GridFS 是一个用于存储和检索大型文件的标准,它将文件拆分成多个小块(通常每个块为 256KB),以便更高效地存储和检索大文件。GridFS 分别在两个集合中存储元数据和文件内容:`files` 集合存储文件的元...
- **GridFS性能提升**:用于存储大文件的GridFS在2.6版本中也进行了优化,提高了上传和下载速度。 - **新的聚合框架**:MongoDB 2.6引入了一个全新的聚合框架,提供了更强大的数据分析能力,支持更复杂的聚合操作...
本次讨论的是MongoDB中的限定集(Capped Collections)和大文件存储(GridFS)两个特色功能。 首先,限定集是MongoDB中一种特殊的集合类型,它有一个固定大小的存储空间,当数据存储超过这个空间限制时,新插入的...
6. 数据库,收集,索引,用户,角色和功能:所有蒙戈对象的简单查看和管理 7. SSH隧道为蒙戈连接 8. 地图,减少操作的编辑器 9. 文件管理器工具GridFS的工作 10.用户界面mongodump和mongorestore公用事业 11.碎片和...
内容简介MongoDB如何帮你管理通过Web应用收集的海量数据呢?通过本书的权威解读,你会了解面向文档数据库的诸多优点,会发现MongoDB如此稳定、性能优越甚至能够无限水平扩展背后的原因。本书的两位作者均来自开发并...
- **目的**: GridFS是MongoDB用于存储大型文件(如图片、音频和视频文件)的标准机制。 - **实现**: 文件被拆分成小块存储在多个文档中。 #### 35. GridFS的解释 - **机制**: GridFS是一种文件存储规范,允许...
* 在 MongoDB 中删除收集的语法是 db.collection.drop() knowledge point 9: Profiler 在 MongoDB 中的作用 * MongoDB 数据库分析器显示针对数据库的每个操作的性能特征 * 您可以使用探查器找到比其慢的查询 ...
5. **GridFS支持**:MongoDB的GridFS是一个存储和检索大型文件的系统,驱动程序提供了对应的接口,便于操作大文件。 6. **文本搜索**:支持MongoDB的全文本搜索功能,可以对文档中的文本字段进行索引和查询。 7. *...
6. 数据库,收集,索引,用户,角色和功能:所有蒙戈对象的简单查看和管理 7. SSH隧道为蒙戈连接 8. 地图,减少操作的编辑器 9. 文件管理器工具GridFS的工作 10.用户界面mongodump和mongorestore公用事业 11....
使用Node.js,Express和Bootstrap3编写的基于Web的MongoDB管理界面 产品特点 连接到多个数据库 查看/添加/删除数据库 查看/添加/重命名/删除收藏集 查看/添加/更新/删除文档 在集合视图中内联预览音频/视频/图像...
- GridFS是MongoDB的一种存储大文件的解决方案,将大文件分割成多个小块存储,便于高效读写。在这里,它用于存储静态化的HTML页面文件。 5. **系统架构优势**: - **解耦**:RabbitMQ使得CMS和Cms Client之间无需...
随着业务的增长,原有的存储方案如MongoDB的GridFS、FastDFS、TFS等已经无法满足B站日益增长的数据存储需求,特别是对于海量的小文件存储需求。基于这样的背景,Bilibili自主研发了一套名为BFS(Bilibili File ...
2. **图像存储**:图像可能被存储在本地文件系统、云存储服务(如Amazon S3或Google Cloud Storage)或者数据库(如MongoDB的GridFS)。选择哪种存储方式取决于项目的规模、安全性和成本考虑。 3. **数据库操作**:...
其中,mybatis、mongodb和Hbase数据库用于处理结构化和非结构化数据,HDFS(Hadoop Distributed File System)用于大数据文件存储,fastDFS和GridFS则分别用于图片和模板页面的存储。 在系统功能设计方面,本平台...