共计 5133 个字符,预计需要花费 13 分钟才能阅读完成。
FastDFS 是一款类 Google FS 的开源分布式文件系统,它用纯 C 语言实现,支持 Linux、FreeBSD、AIX 等 UNIX 系统。它只能通过专有 API 对文件进行存取访问,不支持 POSIX 接口方式,不能 mount 使用。准确地讲,Google FS 以及 FastDFS、mogileFS、HDFS、TFS 等类 Google FS 都不是系统级的分布式文件系统,而是应用级的分布式文件存储服务。
FastDFS 的设计理念
FastDFS 是为互联网应用量身定做的分布式文件系统,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标。和现有的类 Google FS 分布式文件系统相比,FastDFS 的架构和设计理念有其独到之处,主要体现在轻量级、分组方式和对等结构三个方面。
轻量级
FastDFS 只有两个角色:Tracker server 和 Storage server。Tracker server 作为中心结点,其主要作用是负载均衡和调度。Tracker server 在内存中记录分组和 Storage server 的状态等信息,不记录文件索引信息,占用的内存量很少。另外,客户端(应用)和 Storage server 访问 Tracker server 时,Tracker server 扫描内存中的分组和 Storage server 信息,然后给出应答。由此可以看出 Tracker server 非常轻量化,不会成为系统瓶颈。
FastDFS 中的 Storage server 在其他文件系统中通常称作 Trunk server 或 Data server。Storage server 直接利用 OS 的文件系统存储文件。FastDFS 不会对文件进行分块存储,客户端上传的文件和 Storage server 上的文件一一对应。
众所周知,大多数网站都需要存储用户上传的文件,如图片、视频、电子文档等。出于降低带宽和存储成本的考虑,网站通常都会限制用户上传的文件大小,例如图片文件不能超过 5MB、视频文件不能超过 100MB 等。我认为,对于互联网应用,文件分块存储没有多大的必要。它既没有带来多大的好处,又增加了系统的复杂性。FastDFS 不对文件进行分块存储,与支持文件分块存储的 DFS 相比,更加简洁高效,并且完全能满足绝大多数互联网应用的实际需要。
在 FastDFS 中,客户端上传文件时,文件 ID 不是由客户端指定,而是由 Storage server 生成后返回给客户端的。文件 ID 中包含了组名、文件相对路径和文件名,Storage server 可以根据文件 ID 直接定位到文件。因此 FastDFS 集群中根本不需要存储文件索引信息,这是 FastDFS 比较轻量级的一个例证。而其他文件系统则需要存储文件索引信息,这样的角色通常称作 NameServer。其中 mogileFS 采用 MySQL 数据库来存储文件索引以及系统相关的信息,其局限性显而易见,MySQL 将成为整个系统的瓶颈。
FastDFS 轻量级的另外一个体现是代码量较小。最新的 V2.0 包括了 C 客户端 API、FastDHT 客户端 API 和 PHP extension 等,代码行数不到 5.2 万行。
分组方式
类 Google FS 都支持文件冗余备份,例如 Google FS、TFS 的备份数是 3。一个文件存储到哪几个存储结点,通常采用动态分配的方式。采用这种方式,一个文件存储到的结点是不确定的。举例说明,文件备份数是 3,集群中有 A、B、C、D 四个存储结点。文件 1 可能存储在 A、B、C 三个结点,文件 2 可能存储在 B、C、D 三个结点,文件 3 可能存储在 A、B、D 三个结点。
FastDFS 采用了分组存储方式。集群由一个或多个组构成,集群存储总容量为集群中所有组的存储容量之和。一个组由一台或多台存储服务器组成,同组内的多台 Storage server 之间是互备关系,同组存储服务器上的文件是完全一致的。文件上传、下载、删除等操作可以在组内任意一台 Storage server 上进行。类似木桶短板效应,一个组的存储容量为该组内存储服务器容量最小的那个,由此可见组内存储服务器的软硬件配置最好是一致的。
采用分组存储方式的好处是灵活、可控性较强。比如上传文件时,可以由客户端直接指定上传到的组。一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务能力(纵向扩容)。当系统容量不足时,可以增加组来扩充存储容量(横向扩容)。采用这样的分组存储方式,可以使用 FastDFS 对文件进行管理,使用主流的 Web server 如 Apache、nginx 等进行文件下载。
对等结构
FastDFS 集群中的 Tracker server 也可以有多台,Tracker server 和 Storage server 均不存在单点问题。Tracker server 之间是对等关系,组内的 Storage server 之间也是对等关系。传统的 Master-Slave 结构中的 Master 是单点,写操作仅针对 Master。如果 Master 失效,需要将 Slave 提升为 Master,实现逻辑会比较复杂。和 Master-Slave 结构相比,对等结构中所有结点的地位是相同的,每个结点都是 Master,不存在单点问题。
FastDFS 的架构
图 1 展示的是 FastDFS 的系统架构。
从图 1 可以看出,Tracker server 之间相互独立,不存在直接联系。
客户端和 Storage server 主动连接 Tracker server。Storage server 主动向 Tracker server 报告其状态信息,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。Storage server 会连接集群中所有的 Tracker server,向他们报告自己的状态。Storage server 启动一个单独的线程来完成对一台 Tracker server 的连接和定时报告。需要说明的是,一个组包含的 Storage server 不是通过配置文件设定的,而是通过 Tracker server 获取到的。
不同组的 Storage server 之间不会相互通信,同组内的 Storage server 之间会相互连接进行文件同步。
Storage server 采用 binlog 文件记录文件上传、删除等更新操作。binlog 中只记录文件名,不记录文件内容。
文件同步只在同组内的 Storage server 之间进行,采用 push 方式,即源头服务器同步给目标服务器。只有源头数据才需要同步,备份数据并不需要再次同步,否则就构成环路了。有个例外,就是新增加一台 Storage server 时,由已有的一台 Storage server 将已有的所有数据(包括源头数据和备份数据)同步给该新增服务器。
Storage server 中由专门的线程根据 binlog 进行文件同步。为了最大程度地避免相互影响以及出于系统简洁性考虑,Storage server 对组内除自己以外的每台服务器都会启动一个线程来进行文件同步。
文件同步采用增量同步方式,系统记录已同步的位置(binlog 文件偏移量)到标识文件中。标识文件名格式:{dest storage IP}_{port}.mark,例如:192.168.1.14_23000.mark。
文件上传和下载的交互过程
接下来我们一起看一下文件上传和下载的交互过程。文件上传和下载流程分别如图 2、图 3 所示。文件上传流程的步骤如下:
文件上传
文件下载
1. Client 询问 Tracker server 上传到的 Storage server;
2. Tracker server 返回一台可用的 Storage server,返回的数据为该 Storage server 的 IP 地址和端口;
3. Client 直接和该 Storage server 建立连接,进行文件上传,Storage server 返回新生成的文件 ID,文件上传结束。
文件下载流程的步骤如下:
1. Client 询问 Tracker server 可以下载指定文件的 Storage server,参数为文件 ID(包含组名和文件名);
2. Tracker server 返回一台可用的 Storage server;
3. Client 直接和该 Storage server 建立连接,完成文件下载。
文件同步延迟问题的提出
客户端将一个文件上传到一台 Storage server 后,文件上传工作就结束了。由该 Storage server 根据 binlog 中的上传记录将这个文件同步到同组的其他 Storage server。这样的文件同步方式是异步方式,异步方式带来了文件同步延迟的问题。新上传文件后,在尚未被同步过去的 Storage server 上访问该文件,会出现找不到文件的现象。FastDFS 是如何解决文件同步延迟这个问题的呢?
文件的访问分为两种情况:文件更新和文件下载。文件更新包括设置文件附加属性和删除文件。文件的附加属性包括文件大小、图片宽度、图片高度等。FastDFS 中,文件更新操作都会优先选择源 Storage server,也就是该文件被上传到的那台 Storage server。这样的做法不仅避免了文件同步延迟的问题,而且有效地避免了在多台 Storage server 上更新同一文件可能引起的时序错乱的问题。
那么文件下载是如何解决文件同步延迟这个问题的呢?
要回答这个问题,需要先了解文件名中包含了什么样的信息。Storage server 生成的文件名中,包含了源 Storage server 的 IP 地址和文件创建时间等字段。文件创建时间为 UNIX 时间戳,后面称为文件时间戳。从文件名或文件 ID 中,可以反解出这两个字段。
然后我们再来看一下,Tracker server 是如何准确地知道一个文件已被同步到一台 Storage server 上的。前面已经讲过,文件同步采用主动推送的方式。另外,每台 storage server 都会定时向 tracker server 报告它向同组的其他 storage server 同步到的文件时间戳。当 tracker server 收到一台 storage server 的文件同步报告后,它会依次找出该组内各个 storage server(后称作为 S)被同步到的文件时间戳最小值,作为 S 的一个属性记录到内存中。
FastDFS 对文件同步延迟问题的解决方案
下面我们来看一下 FastDFS 采取的解决方法。
一个最简单的解决办法,和文件更新一样,优先选择源 Storage server 下载文件即可。这可以在 Tracker server 的配置文件中设置,对应的参数名为 download_server。
另外一种选择 Storage server 的方法是轮流选择(round-robin)。当 Client 询问 Tracker server 有哪些 Storage server 可以下载指定文件时,Tracker server 返回满足如下四个条件之一的 Storage server:
该文件上传到的源 Storage server,文件直接上传到该服务器上的;
文件创建时间戳 < Storage server 被同步到的文件时间戳,这意味着当前文件已经被同步过来了;
文件创建时间戳 =Storage server 被同步到的文件时间戳,且(当前时间—文件创建时间戳)> 一个文件同步完成需要的最大时间(如 5 分钟);
(当前时间—文件创建时间戳)> 文件同步延迟阈值,比如我们把阈值设置为 1 天,表示文件同步在一天内肯定可以完成。
CentOS 6.2 下 fastDFS 的完整安装和配置步骤 http://www.linuxidc.com/Linux/2012-12/75989.htm
FastDFS 在 Ubuntu 下的安装,PHP 客户端 http://www.linuxidc.com/Linux/2012-09/71459.htm
FastDFS 分布式文件服务器安装,及配置,测试 http://www.linuxidc.com/Linux/2012-09/71458.htm
FastDFS 整合 Nginx 问题整理 http://www.linuxidc.com/Linux/2012-09/71232.htm
CentOS 下搭建 FastDFS http://www.linuxidc.com/Linux/2012-09/70995.htm
Ubuntu 安装 FastDFS 全程记录 http://www.linuxidc.com/Linux/2012-03/56377.htm
FastDFS 的详细介绍 :请点这里
FastDFS 的下载地址 :请点这里