基于Hadoop的海量图片存储模型 的分析和设计

jopen 10年前

     目前国内外在面对图片存储问题时,所采取的解决方案有两种,分别是图片保存至数据库和图片存储在硬盘。鉴于海量图片规模下,数据库承载太多图片会导致数据库容量和效率成为极大的瓶颈。常见的做法是图片保存至硬盘,数据库中保存图片的存储路径。分布式存储为海量图片存储提供了原始模型,一些研究成果和实践表明,图片存储架构需要从容量和负载两方面设计,且还要根据业务需求制定特定的缓存策略。容量方面,大部分的解决方案都是使用海量存储,比如专业的磁盘阵列,入门级的磁盘柜或者高级的光纤盘阵、局域网盘阵等。此外,在采用多台服务器存储的前提下,需要提供NFS的分区给前端应用使用,在前端应用的程序逻辑中加入控制图片存储在哪一台服务器的NFS分区,常用的根据用户id或者图片id,通过关键词的散列,到达同一类型图片存储在一台服务器,加快读取效率。基本上图片负载高的解决办法有两种,前端squid缓存和镜像,通过对存储设备使用镜像,可以分布到多台服务器上对外提供图片服务,然后再配合 squid实现负载的降低和提高用户访问速度。这里我们采用Hadoop作为我们设计图片存储系统的基础,一方面是因为Hadoop开源的特性,方便我们根据业务需求做一些源代码方面的改善;令一方面,Hadoop可以部署在廉价的PC上,通过软件实现高容错性,符合图片存储业务发展的特性。Hadoop 各方面都符合我们的项目需求,这使其成为我们确定的基础研究技术方向。同时我们采用Ngix+Redis做缓存策略,优化图片读取。

        存储系统架构

1、存储单元:采用Hadoop中的HDFS存储大、中、小图片,其中小图片采用打包策略存储,并且提供监控管理界面,查看各个节点存储空问运行状态。通过HDFS的冗余备份和心跳检测保证存储数据的安全性,通过设定负载均衡策略,保证各个存储节点的运行稳定。
2、图片索引:将图片名和图片元数据作为键值对<Key,Value>,放入HBase中存储,并且进行数据查询,避免图片重复存储,便于将来管理。
3、采用MapReduce进行图片业务处理的编程实现,针对大数据上传后的批量处理和存储优化制定相应策略。
4、W曲服务:采用Nginx.0.9.6做图片的web服务器,对网站的大、中、小图片进行读取,加上Nginx的Redis模块对缓存中的微型图片进行读取。
5、缓存服务器:存储网站的微型图片,签名照,小头像,表情图片,通过Nginx的Redis模块直接读取,通过调用Redis的JavaAPI程序对数据进行写入。
6、负载均衡:HAproxy采用RoundRobin负载均衡算法,分载前端用户请求的压力到每个web图片服务器上。 

7、应用服务器:对图片写入的操作全部由Java应用服务器完成。

       存储系统写流程

图片写请求由用户发起后,通过负载均衡模块的过滤,首先来到应用服务器排队等待进入HDFS存储系统,通过NameNode分配DataNode进行存储,图片写入过程中先确定写入Block,再确定Sequence File,系统将二者的ID组合命名为图片的系统内的名称。图片元数据保存在HBase,同时元数据也保存在由Redis构建的缓存系统中。

Hadoop是为解决大文件存储、大任务处理而生的分布式架构,作为图片存储业务中的图片一般大小小于Hadoop的设计要求,这里我们通过合并小文件实现基于Hadoop的海量图片存储系统的设计,并采取了优化,总结如下:
1、通过HA的架构对NameNode进行了热备份,采用heartbeat3实现心跳检测判断NameNode健康状况,解决了NameNode单点的安全隐患。
2、针对图片的大小,对大图片采取并行读取,提高了大图片存取效率,且还能通过配置文件的修改动态更改图片大小设定。通过Sequence实现对小图片的合并,并在合并过程中设定单个Sequence File的偏移量,加快图片的访问。
3、设计了图片URL,将图片存储信息设定在图片URL中,通过解析URL快速定位存储图片Block的DataNode和Fileld。将图片元数据存放在HBase中,解决海量数据扩容和快速检索的问题。
4、使用了Redis和HAProxy构建缓存区和负载均衡,使整个系统达到稳定健康状态。