FastDFS介绍
1、背景
FastDFS是一款开源的、分布式文件系统(Distributed File System),由淘宝开发平台部资深架构师余庆开发。该开源项目的主页是 http://code.google.com/p/fastdfs 。可以通过fastdfs.sourceforge.NET 下载。FastDFS论坛是 http://www.csource.org ,目前是指向 ChinaUnix 开源项目孵化平台的一个板块 FastDFS,网址为 bbs.chinaunix.Net/forum-240-1.html 。
2、FastDFS概述
FastDFS是一款开源的轻量级分布式文件系统
–纯C实现,支持Linux、FreeBSD等UNIX系统
–类google FS,不是通用的文件系统,只能通过专有API访问,目前提供了C、Java和PHP API
–为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性
–FastDFS可以看做是基于文件的key value pair存储系统,称作分布式文件存储服务更为合适
3、FastDFS提供的功能
- .upload:上传普通文件,包括主文件
- .upload_appender:上传appender文件,后续可以对其进行append操作
- .upload_slave:上传从文件
- .download:下载文件
- .delete:删除文件
- .append:从已有文件中追加内容
- .set_metadata:设置文件附加属性
- .get_metadata:获取文件附加属性
3、FastDFS的特点
- 分组存储,灵活简洁
- 对等结构,不存在单点
- 文件ID由FastDFS生成,作为文件访问凭证。FastDFS不需要传统的name server
- 和流行的web server无缝衔接,FastDFS已提供apache和nginx扩展模块
- 大、中、小文件均可以很好支持,支持海量小文件存储
- 支持多块磁盘,支持单盘数据恢复
- 支持相同文件内容只保存一份,节省存储空间
- 存储服务器上可以保存文件附加属性
- 下载文件支持多线程方式,支持断点续传
4、FastDFS架构
首先客户端 client 发起对 FastDFS 的文件传输动作,是通过连接到某一台 Tracker Server 的指定端口来实现的,Tracker Server 根据目前已掌握的信息,来决定选择哪一台 Storage Server ,然后将这个Storage Server 的地址等信息返回给 client,然后 client 再通过这些信息连接到这台 Storage Server,将要上传的文件传送到给 Storage Server上。
- 只有两个角色,tracker server和storage server,不需要存储文件索引信息
- 所有服务器都是对等的,不存在Master-Slave关系
- 存储服务器采用分组方式,同组内存储服务器上的文件完全相同
- 不同组的storage server之间不会相互通信
- 由storage server主动向tracker server报告状态信息,tracker server之间通常不会相互通信
- client询问tracker上传到storage
- tracker返回一台可用的storage
- client直接和storage通信完成文件上传,storage返回文件ID
- client询问tracker可以下载指定文件的storage,参数为文件ID(组名和文件名)
- tracker返回一台可用的storage
- client直接和storage通信完成文件下载
5、FastDFS如何做到无索引服务器
- 上传文件时,文件ID由storage server生成返回给client
- 文件ID包含了组名和文件名,storage server可以根据该ID定位到文件
- 文件ID示例:
- 文件名采用Base64编码,字段包括
- 源storage server IP地址
- 文件创建时间
- 文件大小
- 文件CRC32校验码
- 随机数
- 文件名后面多的16个字节,包含了信息存放到的trunk file ID、文件偏移量、占用的空间大小
6、FastDFS同步机制
- 采用binlog文件记录文件上传、删除等操作,根据binlog进行文件同步
- binlog中只记录文件名,不记录文件内容
- 增量同步方式,记录已同步的位置到.mark文件中
- 同组内的storage server之间是对等的,文件上传、删除等操作可以在任意一台storage server上进行
- 文件同步只在同组内的storage server之间进行,采用push方式,即源头服务器同步给目标服务器
6、FastDFS如何解决同步延迟问题
- storage生成的文件名中,包含源头storage IP地址和文件创建时间戳
- 源头storage定时向tracker报告同步情况,包括向目标服务器同步到的文件时间戳
- tracker收到storage的同步报告后,找出该组内每台storage被同步到的时间戳(取最小值),作为storage属性保存到内存中
7、下载文件选择storage的方法
client询问tracker有哪些storage可以下载指定文件时,tracker返回满足如下四个条件之一的storage:
- (当前时间 -文件创建时间戳) > 同步延迟阀值(如一天)
- 文件创建时间戳 < Storage被同步到的时间戳
- 文件创建时间戳 == Storage被同步到的时间戳 且(当前时间 -文件创建时间戳) > 文件同步最大时间(如5分钟)
- 该文件上传到的源头storage
8、以HTTP方式下载文件
- FastDFS分组存储方式,为HTTP方式下载提供了便利
- FastDFS支持HTTP方式下载文件,不建议使用内置web server,推荐使用外部web server,如果apache或nginx
- 因为需要解决文件同步延迟的问题,因此在apache和nginx上需要使用FastDFS扩展模块。尤其是V3.x引入小文件合并存储后,必须使用扩展模块来读取文件
8、FastDFS扩展模块作用
- 使用扩展模块来解决文件同步延迟问题
- 在每台storage server上部署web server,直接对外提供HTTP服务
- tracker server上不需要部署web server
- 如果请求文件在当前storage上不存在,通过文件ID反解出院storage,直接请求源storage
- 目前已提供apache和nginx扩展模块
- FastDFS扩展模块不依赖于FastDFS server,可以独立存在
8、FastDFS扩展模块特性
- 仅支持HTTP HEAD和GET
- 支持token方式的防盗链(缺省是关闭的)ts:生成token的时间(unix时间戳);token:32位token字符串(md5签名)
- 支持指定保存的缺省文件名,URL参数名为filename
- 支持断点续传
9、FastDFS推荐的部署方案
- 文件上传和删除等操作:使用FastDFS client API,目前提供了C、PHP extension和Java的client API
- 文件下载采用HTTP方式:使用nginx或者apache扩展模块,不推荐使用FastDFS内置的web server
- 不要做RAID,直接挂载单盘,每个硬盘作为一个mount point
10、最大并发连接数设置
- 参数名:max_connections
- 缺省值:256
- 说明:FastDFS采用预先分配好buffer队列的做法,分配的内存大小为:max_connections*buff_size,因此不建议配置的过大,避免无谓内存开销
11、工作线程数设置
- 参数名: work_threads
- 缺省值:4
- 说明:为了避免CPU上下文切换的开销,以及不必要的资源消耗,不建议将本参数设置得过大。为了发挥出多个CPU的效能,系统中的线程数总和,应等于CPU总数。
- 对于tracker server,公式为:work_threads + 1 = CPU数
- 对于storage,公式为:work_threads + 1 + (disk_reader_threads + disk_writer_threads) * store_path_count = CPU数
11、storage目录数设置
- 参数名:subdir_count_per_path
- 缺省值:256
- 说明:FastDFS采用二级目录的做法,目录会在FastDFS初始化时自动创建。存储海量小文件,打开了trunk存储方式的情况下,建议将本参数适当改小,比如设置为32,此时存放文件的目录数为32*32=1024。加入trunk文件大小采用缺省值64MB,磁盘空间为2TB,name每个目录下存放2TB/1024大小文件。每个目录下存放trunk文件数均值再除以64MB
12、storage磁盘读写线程设置
- disk_rw_separated:磁盘读写是否分离
- disk_reader_threads:单个磁盘读线程数
- disk_writer_threads:单个磁盘写线程数
- 如果磁盘读写混合,单个磁盘读写线程数为读线程数和写线程数之和
- 对于单盘挂载方式,磁盘读写线程分别设置为1即可
- 如果磁盘做了RAID,那么需要酌情加大读写线程数,这样才能最大程度地发挥磁盘性能
12、storage同步延迟相关设置
- sync_binlog_buff_interval:将binlog buffer写入磁盘的时间间隔,取值大于0,缺省值为60s
- sync_wait_msec:如果没有需要同步的文件,对binlog进行轮询的时间间隔,取值大于0,缺省值为100ms
- sync_interval:同步完一个文件后,休眠的毫秒数,缺省值为0
- 为了缩短文件同步时间,可以将上述3个参数适当调小即可
FastDFS 是包括一组 Tracker Server 和 Storage Server 的。Tracker Server 与 Storage Server 之间不直接通信,其基本的信息由配置文件在系统启动加载时获知。多台 Tracker Server 之间保证了 Tracker 的分布式,Tracker Server 之间是对等的,防止了单点故障。 Storage Server 是分成多个 Group,每个 Group 中的Storage 都是互相备份的,也就是说,如果 Group1 有 Storage1、Storage2、Storage3,其容量分别是100GB、100GB、100GB,那么 Group1 的存储能力是 100GB,而不是 300GB,这就是互相备份的意思。进一步说,整个 Group 的存储能力由该组中该储能力最小的 Storage 决定。多个 Group 之间的存储方式,可以采用 round robin(轮训)、load balanced(负载均衡)或指定 Group 的方式。另一点相对于MS(Master-Slave)模式的优势,就是 Tracker Server 与 Master 是决然不同的,不仅 master 有上面可能提到的单点故障问题,而且 client 与 master 之间可能会出现瓶颈。但 FastDFS 架构中,Tracker Server 不会称为系统瓶颈,数据最终是与一个 available 的 Storage Server 进行传输的。