手把手教你FastDFS

946 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 6 天

1. FastDFS简介

FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。

FastDFS开源地址 (https://github.com/happyfish100/libfastcommon)

  • FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡
  • FastDFS实现了软件方式的RAID,可以使用廉价的IDE硬盘进行存储
  • 支持存储服务器在线扩容
  • 支持相同内容的文件只保存一份,节约磁盘空间
  • FastDFS只能通过Client API访问,不支持POSIX访问方式
  • FastDFS特别适合大中型网站使用,用来存储资源文件(如:图片、文档、音频、视频等等)

2. FastDFS架构

如图所示,FastDFS总体架构由三个部分构成

  • 客户端(Client)
  • 访问服务器(TrackerServer)
  • 存储服务器(StorageServer)

image.png

2.1 客户端 Client

客户端指的是访问FastDFS分布式存储的客户端设备,是上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。

2.2存储服务器 StorageServer

StorageServer是数据存储服务器,文件和meta data都保存到存储服务器上。主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。

  • 可采用高可用的方式进行数据存储
  • FastDFS集群当中StorageServer按组(Group/volume)提供服务,不同组的StorageServer之间不会相互通信,同组内的StorageServer之间会相互连接进行文件同步
  • Storage server采用binlog文件记录文件上传、删除等更新操作。binlog中只记录文件名,不记录文件内容
  • 文件同步只在同组内的Storage server之间进行,采用push方式,即源头服务器同步给目标服务器

2.3访问服务器 TrackerServer

TrackerServer是访问(或者翻译为跟踪)服务器,是Client访问StorageServer的入口。

负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。

TrackerServer起到几个作用:

  • 【服务注册】 管理StorageServer存储集群,StorageServer启动时,会把自己注册到TrackerServer上,并且定期报告自身状态信息,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息
  • 【服务发现】 Client访问StorageServer之前,必须先访问TrackerServer,动态获取到StorageServer的连接信息

TrackerServer的高可用:为了保证高可用,一个FastDFS集群当中可以有多个TrackerServer节点,由集群自动选举一个leader节点。

2.4 文件存储

与大多数分布式文件系统类似,FastDFS可以将文件以及相关的描述信息(MetaData)保存到StorageServer当中。

文件存储以后将返回唯一的“文件标识”,“文件标识”由"组名"和"文件名"两部分构成

MetaData是文件的描述信息,如 width=1024,heigth=768

3. FastDFS文件上传

文件上传原理如下:

image.png

FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。

Storage Server会定期的向Tracker Server发送自己的存储信息。当Tracker Server Cluster中的Tracker Server不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。

流程如下:

  1. client询问tracker可以上传到哪一个storage,或者指定获取某个组的storage
  2. tracker返回一台可用的storage
  3. client直接和storage通讯完成文件上传
  4. storage保存文件以后给client返回组名(volume)和文件名称

4. FastDFS文件下载

文件下载原理如下:

image.png

客户端uploadfile成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。

流程如下:

  1. client询问tracker下载文件的storage,参数为文件标识(组名和文件名)
  2. tracker返回一台可用的storage
  3. client直接和storage通讯完成文件下载

由于storage有多个存储节点,存储节点间的文件同步是在后台异步进行的,所以有可能出现在读的时候,文件还没有同步到某些storage server上,为了尽量避免访问到这样的storage,tracker按照如下规则选择group内可读的storage:

  1. 该文件上传到的源storage - 由于源头的地址被编码在文件名中,只要源头storage存活,优先返回
  2. 文件创建时间戳==storage被同步到的时间戳 且(当前时间-文件创建时间戳) > 文件同步最大时间(如5分钟) - 文件创建后,认为经过最大同步时间后,肯定已经同步到其他storage了
  3. 文件创建时间戳 < storage被同步到的时间戳。 - 同步时间戳之前的文件确定已经同步了
  4. (当前时间-文件创建时间戳) > 同步延迟阈值(如一天)。 - 经过同步延迟阈值时间,认为文件肯定已经同步了

4. FastDFS文件同步

写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。

文件同步(添加/删除/修改)storage server之间进行,采用push方式,即源服务器同步给目标服务器;

每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。

storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。

源头数据才需要同步,备份数据不需要再次同步,否则就会构成环路了。

5. FastDFS服务端文件目录

5.1 TrackerServer  

|__data
|     |__storage_groups.dat:存储分组信息 
|     |__storage_servers.dat:存储服务器列表  
|__logs         
   |__trackerd.log:tracker server日志文件

5.2 StorageServer

|__data
   
|     |__.data_init_flag:当前storage server 初始化信息
   
|     |__storage_stat.dat:当前storage server统计信息
   
|     |__sync:存放数据同步相关文件
   
|     |     |__binlog.index:当前的binlog文件索引号
   
|     |     |__binlog.### :存放更新操作记录(日志)
   
|     |     |__${ip_addr}_${port}.mark:存放同步的完成情况
   
|     |
   
|     |__一级目录:256个存放数据文件的目录,如:00, 1F
   
|           |__二级目录:256个存放数据文件的目录
   
|__logs
       
   |__storaged.log:storage server日志文件

5. FastDFS的优缺点

FastDFS的优点:

- 分组存储,简单灵活;
- 对等结构,不存在单点;
- 文件`ID`由FastDFS生成,作为文件访问凭证。FastDFS不需要传统的`nameserver``metaserver`- 大、中、小文件均可以很好支持,可以存储海量小文件;
- 一台`storage`支持多块磁盘,支持单盘数据恢复;
- 提供了nginx扩展模块,可以和nginx无缝衔接;
- 支持多线程方式上传和下载文件,支持断点续传;
- 存储服务器上可以保存文件附加属性。

FastDFS的缺点:

- 直接按文件存储,可直接查看文件内容,缺乏文件安全性
- 不支持断点续传,对大文件将是噩梦
- 同步机制不支持文件正确性校验,降低了系统的可用性
- 部署难度比别的DFS更高
- 通过API下载,存在单点的性能瓶颈