图片存储

在前一步,我们接收了上传来的文件,现在要把文件存储起来。

业务层通过“FileStorage接口”write文件、read文件。

业务层只对接口操作,不用关心:存储在哪里、存储空间如何扩展、如何做分布式、目录结构、IO性能等问题,这此问题都交由下层的具体实现类来关心。

海量小文件存储服务设计

什么是“小文件”:网站中用户上传的图片(原图70K,缩略图5~15K)、生成的静态化页面,平均大小 50K。

一个“文件存储服务接口”有多种不同的实现,每个实现适用的场景不同、成本不同。

文件存储服务是一个基础服务,以接口形式提供。为用户上传上来的图片、PDF、Excel等文件提供存储。

本“服务”有以下特点:

  1. 提供多种存储方式的实现:LocalFileSystem本地文件夹、FTP远程存储、阿里云OSS存储、FastDFS、 FileStorageMongoDB 等实现方案。
  2. 业务层调用接口,可实现给文件的保存、修改、删除。
  3. 业务层不用关心,存储空间扩展、目录结构、IO性能等问题,这此问题都交由下层的具体实现类来关心。
  4. 设计“流”式的传输方式,适合传输大文件,也适合小文件。

类图

文件存储服务接口FileStorage

com.sicheng.common.fileStorage


本地文件系统的实现方案LocalFileSystem

适用场景:用于存储网站的图片和生成的静态化页面,适用于小型网站,只有几个java类就实现了,内嵌在网站程序中,是低技术成本的存储方案。无意与FastDFS、TFS、OSS、Ceph等等分布式文件系统竞争。

目录结构:20/99/99/5709f0ba31e342bda28d03485b257c94.jpg

3层目录结构:一层目录00-19,二层目录00-99,三层目录00-99,

一层目录00-19,要控在较少的数量,方便运维人员使用NFS把某个目录放在远程服务器。若是有256个一级目录太多了,运维人员做NFS时工作量太大。

二三层目录00-99,我以前用过FastDFS,它使用00~FF的256个目录,我常常查bug时要找某个文件,字母的文件名并不方便我人工查找。还是有序的数字方便。

单目录下最大文件数量:第三层目录每个目录下计划最多放1000个文件,超过这个数量由于操作系统的文件的原理,IO性能会下降。

文件名:使用UUID,有点长,还可忍受。主要生成方便技术成本低。

可存储的文件数量:20个目录*100个目录*100个目录*1000个文件=2亿个文件,理论上可存储2亿个文件,这对于“小型网站”来说太够用了。

总大小:按一个文件平均 70K,2亿个文件,总体积是13TB。 “小型网站”也达不到这个体积。

扩容与分布式的解决方案:使用NFS,最多可把20个目录 用NFS存储到远程服务器,最多可使用20块硬盘,扩展了存储容量,实现了人工的低水平的低成本的分布式,由于磁盘数量多了提高了总体的IO性能。例如 1.5万转的快盘小文件随机iops一般在150左右,磁盘是瓶颈,NFS网络传输不会成本瓶颈。

文件的备份方案:依靠linux操作系统的文件同步技术来实现备份,如 rsync。本存储服务不解决备份问题。我以前做过由Java程序来负责同步备份的同类程序,效果不好,因复杂的网络原因、源与备件之间文件数量对不上,备份的可靠性低。把事情做简单,以至于明显没有bug。

本实现方案的特点:本方案各方面做的都很“均衡”。定位目标低、追求简单实用,开发成本低、学习成本低、运维成本低、可满足业务系统对小文件存储的要求。有一定的扩展能力,在使用NFS后单盘容量、单盘IO、网络吞吐量等方面指标都很“均衡”。

性能:考量小文件存储的主要性能指标是IOPS,瓶颈在于磁盘, 1.5万转的SAS盘小文件随机iops一般在150左右,1万转的盘小文件随机iops一般在100左右,7200转的STAT盘小文件随机iops一般在70左右。这是硬件在这种应用场景下自身的性能,无法超越。本程序性能不是瓶颈,NFS网络传输性能不是瓶颈。如果你采用一块1.5万转的SAS盘,每秒可读150次。如果你采用10块1.5万转的SAS盘,每秒可读1500次。本程序不提供缓存能力,这里不考虑缓存对性能的提升。

阿里云OSS实现

适用场景:大型系统

若程序部署在阿里云上,可使用本实现。把一切问题交给OSS来解决吧。

远程FTP实现

适用场景:小型系统

FileStorageMongoDB 实现

请移步到: filestore分布式文件存储系统--介绍