商品图片,平均200-500K,说大不大,说小不小,但量大且细碎,通常通过页面上传,全部保存在文件里,管理和索引都很慢,几乎无法备份,读取也很慢。
传统的基于磁盘存储的缺陷:
1、 图片存储和应用程序在一个服务器上,图片的读取占用大量的磁盘IO,在访问量高的时候,图片读取和应用程序相互影响。特别互联网环境下的文件多以几K,几十K的小文件为主,磁盘寻址和读取,缓存命中率都比较低。
2、 当规模大到一定程度,应用服务器将扩展到多服务器集群环境中,传统的磁盘存储在集群环境下面临集中存储的挑战。
3、 基于磁盘的存储,在面临未来扩容的情况下,也显的能力不足,通过增加磁盘的容量很快将达到极限,最好的方法还是多服务器集群的存储。所以在存储和读取上的难度将陡然增加。
所以鉴于此,放弃简单的磁盘存储,而且各大互联网公司都有自己的文件系统,google的GFS,淘宝的TFS,其他中小型的网站,会采用类似于mogileFS这样开源的文件系统。所以利用开源的文件系统来搭建我们自己的文件系统、文件服务器以及文件的存取服务。
在众多开源的文件系统中,我们选用MongoDB的GridFS作为文件存储服务。
MongoDB特性 MongoDB是一个可扩展、高性能的下一代数据库,由C++语言编写,旨在为web应用提供可扩展的高性能数据存储解决方案。它的特点是高性能、易部署、易使用,存储数据非常方便,主要特性有:
1. 模式自由,支持动态查询、完全索引,可轻易查询文档中内嵌的对象及数组。
2. 面向集合存储,易存储对象类型的数据, 包括文档内嵌对象及数组 。
3. 高效的数据存储,支持二进制数据及大型对象(如照片和视频) 。
4. 支持复制和故障恢复;提供了主-从、主-主模式的数据复制及服务器之间的数据复制。
5. 自动分片以支持云级别的伸缩性,支持水平的数据库集群,可动态添加额外的服务器 。
在OECP社区(http://www.oecp.cn)中,我们也初步使用了mongodb,实践证明mongodb从效率和稳定性上都是有保障的。
GridFS和传统的MogileFS不同, gridfs可以和其它的meta数据部署在同一个 db中,默认的会为gridfs的collection分别创建fs.files和fs.chunks. 当存储一个文件时,可以附加存入任意的附加信息,因为这些信息实际上也是一个普通的collection. GridFS的一个优点是可以存储上百万的文件而无需担心扩容性. 通过同步复制,可以解决分布式文件的备份问题. 目前,mongo支持主-从和Replica Pairs以及受限的Master-Master Replication. 比较实用的还是前2种.
选择了存储的方案后,我们需要对电子商务网站的图片的存储和读取进行整体的架构设计,设计思路:
? 决不允许重复图片存在,利用MD5进行判断
? 文件只有原始的需要保留,其他各尺寸和效果都可以由原图生成
? 图片URL总是固定的,不管它出现在哪里 ? 缩略图生成规则也简单的体现在URL里
? 第一次请求,由图片处理程序生成静态文件,以后请求即直接定位到静态文件
所用到的技术组件:
1、 MongDB,第一阶段采用单服务器,后期演变到M-S架构
2、 Nginx: 解析URL并定位到静态文件,如果未生成则转向程序去生成图片
3、 JMagick:用于生成高清的缩略图
4、 spring-data:用于对MongoDB的操作
下一步的工作主要是:
1、 对MongoDB的封装
2、 对文件系统的存储实现和应用程序的读取
3、 将文件系统作为OECP平台的系统组件进行包装
延伸:基于MongoDB的日志服务和用户行为分析的架构设计及实现策略的考察和尝试
案例: 视觉中国的NoSQL之路:从MySQL到MongoDB : http://blog.nosqlfan.com/html/1155.html 视觉中国MongoDB开发应用实践 : http://www.infoq.com/cn/presentations/pf-mongodb-develop