作者 | fosterli(李勤德)
导读
近年来,随着CPU、内存等硬件技术的快速发展,存储设备价格不断降低,加上信息的载体由2G时代的文本转变为3G时代的图片、4G时代的视频,信息、数据的爆炸式增长使得人们对存储的渴望进一步极大,无论是个人,还是企业,都可以自行组建存储系统,以满足日常生活中普遍的存储需求。
一.什么是分布式文件存储
在介绍分布式文件存储之前,先要了解什么是集中式存储,什么是分布式存储。集中式存储,顾名思义就是采用集中的存储服务器存放所有数据,存储服务器容易成为性能瓶颈,不能满足大规模存储需求。分布式存储简单来说就是将大量的普通服务器,通过网络互联,对外作为一个整体提供存储服务。分布式存储采用可扩展的系统结构,利用多台存储服务器分担存储负荷,它不但提高了系统的可靠性、可用性和存取效率,还易于扩展。分布式存储包括分布式块存储、分布式文件存储和分布式对象存储。
分布式文件系统最为著名的莫过于Gooogle File System(GFS),它构建在大量的普通服务器之上,具备线性扩容、副本管理、自动容错等分布式系统常见的功能,GFS并未开源,但是关于GFS的学术论文早于公之于众,其他分布式文件系统TFS、HDFS、FastDFS、GlusterFS、MooseFS等,或多或少借鉴了GFS的设计和架构,大体上都比较相近。
各类分布式文件存储系统对比
TFS | MogileFS | FastDFS | GlusterFS | MooseFS | |
---|---|---|---|---|---|
开发语言 | C++ | Perl | C | C | C |
数据存储方式 | 块 | 文件 | 文件/Trunk | 文件/块 | 文件 |
元数据服务器 | NS | DB | 无 | 无 | MFS |
在线扩容 | 支持 | 支持 | 支持 | 支持 | 支持 |
冗余备份 | 支持 | 支持 | 支持 | 支持 | 支持 |
单点故障 | 存在 | 存在 | 不存在 | 不存在 | 存在 |
系统复杂度 | 高 | 高 | 低 | 低 | 高 |
适用场景 | 跨集群小文件 | 单集群小文件 | 单集群中小文件 | 跨集群云存储 | 单集群大中文件 |
FastDFS由于没有元数据服务器,在架构上更为简洁,并且直接使用Socket通讯,可以支持高并发和高负载,适合存储互联网常见的中小文件(文件容量在500MB以下),本文着重介绍FastDFS。
二.什么是分布式文件存储FastDFS
FastDFS架构上同样类似GFS,唯一不同的是FastDFS不存储文件大小、文件索引、创建时间等元数据,并且是一个最终一致性的存储系统,整体架构分为三部分:Client、Tracker和Storage,Client主要作用是发起上传、下载请求,Tracker主要作用是分发读写请求、负载均衡、管理Storage状态信息,Storage主要作用是数据存储。
1. RAID
衡量硬盘性能有两个重要参数,一个是IOPS,指的是每秒能进行多少次I/O操作,IOPS直接对应的是完成一次I/O所需时间,对于硬盘来说主要包括三部分:磁头寻道时间、盘片旋转时间和数据传输时间。另一个是吞吐量,指的是磁盘每秒I/O流量,即磁盘写入加上读出的数据大小。在不论功耗的情况下,这两个参数指标越高,磁盘性能越好。
对于个人用户来说,数TB的存储空间,即可满足大部分的存储场景,然而对于企业用户来说,存储量达到PB甚至EB也是非常容易的,为获得更大的存储空间以及更快的读写速度,磁盘阵列被发明出来。
磁盘阵列(Redundant Arrays of Independent Disks,RAID),是一种把多块独立的硬盘(物理硬盘)按不同的方式组合起来形成一个硬盘组(逻辑硬盘),从而提供比单个硬盘更高的存储性能与数据备份能力的技术。利用这项技术,将数据切割成许多区段,分别存放在各个硬盘上。RAID有如下优点:
大容量,一般来说, RAID的可用容量要小于所有成员磁盘的总容量。不同等级的RAID算法需要一定的冗余开销,具体容量开销与RAID等级有关。业界比较流行的RAID5,是RAID0和RAID1的折中方案,在速度和安全有一个比较好的平衡,可用容量为总容量的80%以上。
高性能,RAID对外提供读写服务时,会横跨所有的组成RAID的硬盘,对于RAID而言,IOPS和吞吐量要远比单盘大得多。
可靠性,大多数RAID等级具有完备的数据校验、纠正措施,从而提高系统的容错性,甚至镜像方式,大大增强系统的可靠性。
目前集团的存储服务器有40个硬盘插槽,其中32个硬盘插槽均插上8T单盘,其中30块8T单盘用RAID卡做成3组RAID5,除去部分系统损耗之外,每组RAID5的可用容量66T左右。为了防止硬盘出现故障,需剩余2块8T单盘做热备。
2. 系统调用
文件的读写过程,从用户空间到内核空间,再到最后的存储设备,会经历以下五个阶段:
虚拟文件系统接收I/O请求,这里的虚拟文件系统是为了屏蔽EXT2/EXT3/EXT4等真实文件系统的操作差异,为上层提供统一接口
如果应用程序没有指定使用Direct I/O,数据会先写到Page Cache,Page Cache在这个过程扮演了磁盘缓存的角色,内核会定时将Page Cache的数据刷入硬盘。
真实文件系统负责定位写请求的位置并将其转换成块设备所需要的块,然后把这个请求发送到设备上。
通用块层维护I/O请求在上层真实文件系统与底层物理硬盘之间的关系,将文件访问映射为设备访问。
I/O调用层使用I/O调度算法对I/O请求进行合并、排序等预操作,对连续扇区操作的多个请求进行合并以提高效率。
FastDFS使用sendfile来传输数据,sendfile在两个文件描述符之间直接传递数据(完全在内核中操作),从而避免了内核缓冲区和用户缓冲区之间的数据拷贝,效率很高。对比传统的read/write,sendfile不但能减少切换次数而且还能减少拷贝次数,是一个非常高效的数据拷贝函数,尤其在传输大文件时,sendfile的高性能体现的更为明显。
3. Client
发起上传、下载、追加、删除等请求的客户端,Client通常将上传、下载、追加、删除等操作封装为HTTP接口,以供业务方使用。
4. Tracker
Tracker主要做调度工作,起负载均衡的作用,是Client与Storage的交互枢纽。Tracker在内存中记录存储分组、分组与Storage的映射关系、Storage状态等信息,占用的内存很少,不会成为系统瓶颈。在生产环境,通常需要部署两台以上Tracker组成集群。
5. Storage
FastDFS是以分组来组织存储的,Storage是真正存储文件的地方,为解决容灾问题,每个分组需要部署两台以上Storage,同组Storage互为备份,无主从之分,地位对等。不同于GFS强一致性文件系统,FastDFS上传只需要写入一台Storage后即可返回成功,备份线程再将文件同步到组内其他Storage。Storage每隔30秒上报一次状态信息给Tracker,由Tracker统一调度、分配。
FastDFS上传过程可分为以下三个步骤:
Client发起上传请求,和Tracker建立链接,根据上传请求的分组参数,取得可用的Storage。
Client直接发起请求,将文件内容以及元数据上传到Storage,Storage生成FileId后,返回给Client。
Client保存文件名,同时Storage将文件同步到组内其他Storage。
FastDFS下载过程可分为以下三个步骤:
Nginx接收到Client发起下载请求,根据FileId找到一组Storage。
Nginx将请求转发到Storage,Storage下载文件返回给Nginx响应客户端。
因为FastDFS备份文件是异步进行的,因此Nginx第一次路由到的Storage可能还没有该文件,此时Storage需要将下载请求依次转发到分组内其他Storage,直到找到该FileId对应的文件。
三.最佳实践
1. 适当增大读写线程数
Storage会定期向Tracker上报状态信息,其中包含Storage剩余可用容量,适当减少Storage剩余容量,能提高磁盘利用率。将Storage剩余容量设置为1%,即磁盘利用率能达到99%。
2. 合并存储
存储海量小文件,会使文件系统处理性能会受到显著的影响,在读写次数与吞吐量这两个指标上会有不少的下降。海量小文件会大量消耗Inode,极端情况下甚至会导致Inode消耗完毕而还剩余大量磁盘空间的情况,此时存储系统不能再写入任何文件。因此,合并存储是优化小文件存储的常用手段。FastDFS支持合并存储,默认情况下关闭,需手动打开,并设置Trunk大小即可,FastDFS会将一定数量的小文件合并,直到Trunk达到指定的数值,然后写入磁盘。
3. 适当增大读写线程数
磁盘做RAID的情况下,适当增加读写线程数,这样才能最大程度地发挥磁盘性能,一般线程数不超过做RAID的磁盘个数。
四.总结
分布式存储,通过网络互联,将大量的普通服务器作为一个整体,对外提供存储服务。
分布式文件存储是分布式存储领域很小的一部分,几乎所有分布式文件存储的设计思路都来自GFS。
FastDFS在FileId做了取巧,不需要额外的元数据服务器来记录文件位置,架构比较简洁。
FastDFS直接使用Socket通信方式,对比一般的分布式文件系统使用的HTTP方式,效率更高。
FastDFS使用sendfile传输文件,对比传统的read/write,实现内存零拷贝,系统开销更小,文件传输效率更高。
end

