[TOC]

0x00 前言简述

1.概述

描述: FastDFS 是用 C 语言编写的一款开源的分布式文件系统,它对文件进行管理。功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,适合中小文件(4KB < file_size <500MB)存储,解决了大容量文件存储负载均衡的问题。充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标

应用场景:

  • 1.特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
  • 2.​ 适合用来存储用户图片、视频、文档等文件。

Tips: 支持Linux、FreeBSD等UNIX系统类 google FS,但不是通用的文件系统;


2.特性

简单描述:

  • (1) 支持在线扩容以及主从搭建文件
  • (2) 文件不分块存储,上传的文件和 OS 文件系统中的文件一一对应
  • (3) 支持相同内容的文件只保存一份,节约磁盘空间
  • (4) 下载文件支持 HTTP 协议,可以使用内置 Web Server,也可以和其他 Web Server 配合使用
  • (5) 存储服务器上可以保存文件属性(meta-data)
  • (6) V2.0网络通信采用 libevent,支持大并发访问,整体性能更好

优点:

  • 1.适合中小文件存储(建议范围:4KB < file_size < 500MB
  • 2.主备Tracker服务,增强系统的可用性
  • 3.系统不需要支持POSIX,这样的话就降低了系统的复杂度,使得处理的速度会更高
  • 4.支持主从文件,支持自定义扩展名
  • 5.支持在线扩容机制,增强了系统的可扩展性
  • 6.实现了软RAID,增强了系统的并发处理能力和数据容错恢复能力


缺点:

  • 1.直接按文件存储,可直接读取文件内容,缺乏文件安全性
  • 2.通过API下载,存在单点的性能瓶颈
  • 3.不支持断点续传,对大文件将是噩梦
  • 4.同步机制不支持文件正确性校验,降低了系统的可用性
  • 5.不支持POSIX通用接口访问,通用性比较的低
  • 6.对跨公网的文件同步,存在着比较大的延迟,需要应用做相应的容错策略

Tips : ​出于简洁考虑 FastDFS 没有对文件做分块存储,因此不太适合分布式计算场景。


3.架构

描述: FastDFS 文件系统主要由 Tracker serverStorage server 组成。其中 Storage 负责存储文件,Tracker 负责存储文件所在地址,主要作用是负载均衡和资源调度。


原理流程: 客户端请求 Tracker server 进行文件上传、下载、删除文件, Tracker server 将客户端的请求调度到 Storage server 完成文件的上传和下载。

从框架图中我们可以看到FastDFS服务端有三个角色, 跟踪服务器(tracker server)存储服务器(storage server)客户端(client)。Tracker、Storage 都可以实现集群部署,Tracker的每个节点地位平等,而Storage可以分为多个组,每个组之间保存的文件是不同的,组内部分为多个成员且地位一致,每个成员保存的内容是一样,没有主从概念。

WeiyiGeek.FastDFS架构

WeiyiGeek.FastDFS架构

Tips : 使用FastDFS存储文件优点,可以应对互联网的海量文件存储,一旦文件较多,可以随时横向扩展,且集群的实现也使系统不存在单点故障问题,用户不会因为服务器宕机而无法访问文件资源。


Tracker Server

描述: 跟踪服务器作为集群的中心节点,负责对客户端的请求进行负载均衡和调度工作,以及负责管理所有的 storage server 和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。tracker 根据 storage 的心跳信息,建立 group==>[storage serverlist] 的映射表。

重点: Tracker 管理的元数据信息较少并且会全部存储在内存中,另外 tracker 上的元信息都是由 storage 汇报的信息生成的,本身不需要持久化任何数据,使得 tracker 非常容易扩展,直接增加 tracker 机器即可扩展为 tracker cluster 来服务,cluster 里每个 tracker 之间是完全对等的,所有的 tracker 都接受 stroage 的心跳信息,生成元数据信息来提供读写服务。


Storage Server

描述: 存储服务器(又称:存储节点或数据服务器)主要提供容量和备份服务。

它以 group 为单位每个 group 内可以有多台 storage server 数据互为备份;

它有如下优缺点:

  • 优点: 是将不同应用数据存到不同的Group就能隔离应用数据,同时还可根据应用的访问特性来将应用分配到不同的Group来做负载均衡。
  • 缺点: 是Group的容量受单机存储容量的限制,同时当Group内有机器坏掉时,数据恢复只能依赖group内的其他机器,使得恢复时间会很长。

以 group 为单位每个 group 内可以有多台 storage server 数据互为备份; 以 group 为单位组织存储能方便的进行应用隔离、负载均衡、副本数定制(group内storage server数量即为该group的副本数);

Tips : group 组也可称为卷。同组内服务器上的文件是完全相同的,同一组内的storage server之间是对等的, 文件上传、 删除等操作可以在任意一台storage server上进行 。

重点: group内每个storage的存储依赖于本地文件系统,storage可配置多个数据存储目录,比如有10块磁盘分别挂载在/data/disk1-/data/disk10,则可将这10个目录都配置为storage的数据存储目录。storage接受到写文件请求时,会根据配置好的规则选择其中一个存储目录来存储文件。为了避免单个目录下的文件数太多,在storage第一次启动时,会在每个数据存储目录里创建2级子目录,每级256个,总共256^2=65536个文件,新写的文件会以hash的方式被路由到其中某个子目录下,然后将文件数据(文件和文件属性(meta data)键值对(Key Value Pair)方式,如:width=1024,heigth=768)作为本地文件存储到该目录中, 即Storage server直接利用OS的文件系统调用管理文件。


Client

描述: client(客户端) 作为业务请求的发起方,通过专有接口,使用TCP/IP协议与跟踪器服务器或存储节点进行数据交互。FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。


4.存储策略

描述: 为了支持大容量存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份负载均衡的作用。

Tips : 在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。

Tips : 当存储空间不足或即将耗尽时,可以动态添加卷, 只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。


5.过程剖析

文件上传 - upload

描述: 通过前面架构介绍我们知道向使用者提供基本文件访问接口,比如 upload、download、append、delete 等,以客户端库的方式提供给用户使用。

简单流程:
描述: Storage Server 会定期的向 Tracker Server 发送自己的存储信息。当 Tracker Server Cluster 中的 Tracker Server 不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。 当Tracker收到客户端上传文件的请求时,会为该文件分配一个可用的 group (Storage Server其中的组)来进行存储文件的,当选定了group后就要决定给客户端分配group中的哪一个storage server。当分配好storage server后客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录,然后为文件分配一个fileid(路径信息和文件名),最后根据以上的信息生成文件名并存储文件。

WeiyiGeek.fdfs文件上传

WeiyiGeek.fdfs文件上传


内部机制

  • 1) 选择 tracker server
    描述: 当集群中不止一个tracker server时,由于tracker之间是完全对等的关系,客户端在upload文件时可以任意选择一个trakcer。 选择存储 Storage 的 group 当 tracker 接收到upload file的请求时,会为该文件分配一个可以存储该文件的group,支持如下选择group的规则:

    • 1、Round robin,所有的group间轮询
    • 2、Specified group,指定某一个确定的group
    • 3、Load balance,剩余存储空间多多group优先
  • 2) 选择 storage server
    描述: 当选定group后,tracker会在group内选择一个storage server给客户端,支持如下选择storage的规则:

    • 1、Round robin,在group内的所有storage间轮询
    • 2、First server ordered by ip,按ip排序
    • 3、First server ordered by priority,按优先级排序(优先级在storage上配置)
  • 3) 选择 storage path
    描述: 当分配好storage server后,客户端将向storage发送写文件请求,storage将会为文件分配一个数据存储目录,支持如下规则:

    • 1、Round robin,多个存储目录间轮询
    • 2、剩余存储空间最多的优先
  • 4) 生成 fileid
    描述: 选定存储目录之后storage会为文件生一个Fileid,由storage server ip、文件创建时间、文件大小、文件crc32和一个随机数拼接而成,然后将这个二进制串进行base64编码,转换为可打印的字符串。选择两级目录当选定存储目录之后,storage会为文件分配一个fileid,每个存储目录下有两级256*256的子目录,storage会按文件fileid进行两次hash(猜测),路由到其中一个子目录,然后将文件以fileid为文件名存储到该子目录下。

  • 5) 生成文件名
    描述: 当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名,文件名由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。

    1
    2
    3
    # fdfs_upload_file /etc/fdfs/storage.conf logo.jpg
    组名/磁盘/一级目录(2*Hex)/二级目录(2*Hex)/文件名称
    group1/M00/00/00/wKgMMmB2bmyAP9SWAAA_wvXjApM631.jpg
    WeiyiGeek.fdfs文件名称说明

    WeiyiGeek.fdfs文件名称说明


文件下载 - Download

描述: 跟upload file一样在download file时客户端可以选择任意 tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。由于group内的文件同步时在后台异步进行的,所以有可能出现在读到时候,文件还没有同步到某些 storage server上,为了尽量避免访问到这样的storage,tracker 按照如下规则选择 group 内可读的 storage:

  • 1.该文件上传到的源头 storage, 只要源头 storage存活着就肯定包含这个文件,源头的地址被编码在文件名中。
  • 2.文件创建时间戳 == storage 被同步到的时间戳且(当前时间-文件创建时间戳) > 文件同步最大时间(如5分钟) - 文件创建后认为经过最大同步时间后,肯定已经同步到其他storage了。
  • 3.文件创建时间戳 < storage被同步到的时间戳。 - 同步时间戳之前的文件确定已经同步了
  • 4.(当前时间-文件创建时间戳) > 同步延迟阀值(如一天)。 - 经过同步延迟阈值时间,认为文件肯定已经同步了。
WeiyiGeek.fdfs文件下载

WeiyiGeek.fdfs文件下载


6.功能比对

单机文件系统的对比

文件系统 高可用 扩展 部署复杂程度 性能
单机文件系统 低,依赖于单机服务器,只要服务器崩溃,完全不可用。 低,要扩容只能停机增加硬盘。 当文件数量多到一定的程度,磁盘IO寻址操作将会成为瓶颈
分布式文件系统 高,一个group内的服务器崩溃后,group内的其他storage将接管服务。 高,可以不停机增加group机器。 高,部署较复杂 高,通过集群或者分布式的方式分担服务器的压力。


其他文件系统的对比

指标 适合类型 文件分布 系统性能 复杂度 FUSE POSIX 备份机制 通讯协议接口 社区支持 开发语言
FastDFS 4KB~500MB 小文件合并存储不分片处理 很高 简单 不支持 不支持 组内冗余备份 Api HTTP 国内用户群 C语言
TFS 所有文件 小文件合并,以block组织分片 复杂 不支持 Block存储多份,主辅灾备 API http C++
MFS 大于64K 分片存储 Master占内存多 支持 支持 多点备份动态冗余 使用fuse挂在 较多 Perl
HDFS 大文件 大文件分片分块存储 简单 支持 支持 多副本 原生api 较多 Java
Ceph 对象文件块 OSD一主多从 复杂 支持 支持 多副本 原生api 较少 C++
MogileFS 海量小图片 复杂 可以支持 不支持 动态冗余 原生api 文档少 Perl
ClusterFS 大文件 简单 支持 支持 C


7.参考来源

官方网站:https://github.com/happyfish100/
配置文档:https://github.com/happyfish100/fastdfs/wiki/
参考资料:https://www.oschina.net/question/tag/fastdfs
Java客户端:https://github.com/happyfish100/fastdfs-client-java