当前位置: 首页 > 科技观察

分布式文件系统FastDFS架构分析

时间:2023-03-18 10:08:37 科技观察

FastDFS是与GoogleFS一样的开源分布式文件系统,采用纯C语言实现,支持Linux、FreeBSD、AIX等UNIX系统。只能通过专有API访问文件,不支持POSIX接口方式,不能用于挂载。准确地说,GoogleFS、FastDFS、mogileFS、HDFS、TFS等类型的GoogleFS并不是系统级的分布式文件系统,而是应用级的分布式文件存储服务。FastDFS的设计理念FastDFS是为互联网应用量身定做的分布式文件系统。充分考虑冗余备份、负载均衡、线性扩展等机制,注重高可用和高性能。与现有的类GoogleFS分布式文件系统相比,FastDFS的架构和设计理念有其独特之处,主要体现在轻量级、分组化和对等结构三个方面。#p#轻量级的FastDFS只有两个角色:Trackerserver和Storageserver。Trackerserver作为中心节点,主要用于负载均衡和调度。Trackerserver在内存中记录分组、Storageserver状态等信息,不记录文件索引信息,占用内存小。另外,当客户端(应用程序)和Storageserver访问Trackerserver时,Trackerserver会扫描内存中的group和Storageserver信息,然后给出响应。可见Trackerserver非常轻量级,不会成为系统瓶颈。FastDFS中的Storageserver在其他文件系统中通常称为Trunkserver或Dataserver。StorageServer直接利用操作系统的文件系统来存储文件。FastDFS不以块存储文件,客户端上传的文件与Storage服务器上的文件一一对应。众所周知,大多数网站都需要存储用户上传的文件,例如图片、视频、电子文档等,为了降低带宽和存储成本,网站通常会限制用户上传文件的大小,例如图片文件不能超过5MB,视频文件不能超过100MB,等等。在我看来,对于互联网应用来说,文件块存储是没有必要的。它并没有带来太大的好处,还增加了系统的复杂度。FastDFS不以块的形式存储文件。与支持文件块存储的DFS相比,更加简洁高效,完全可以满足大部分互联网应用的实际需求。在FastDFS中,客户端上传文件时,文件ID不是由客户端指定的,而是由Storageserver生成返回给客户端的。文件ID包括组名、文件的相对路径、文件名,Storageserver可以根据文件ID直接定位文件。因此FastDFS集群中不需要存储文件索引信息,是相对轻量级的FastDFS的一个例子。而其他文件系统需要存储文件索引信息,这样的角色通常被称为NameServer。其中,mogileFS使用MySQL数据库存储文件索引和系统相关信息。它的局限性很明显,MySQL会成为整个系统的瓶颈。FastDFS轻量级的另一个体现是代码量小。最新的V2.0包括C客户端API、FastDHT客户端API和PHPextension等,代码不到52000行。#p#GoogleFS分组方式支持文件冗余备份,例如GoogleFS和TFS的备份个数为3个。一个文件存储到的存储节点通常是动态分配的。这样,文件存放的节点是不确定的。例如文件备份数为3,集群中有A、B、C、D四个存储节点。文件1可能存储在A、B、C三个节点,文件2可能存储在B、C、D三个节点,文件3可能存储在A、B、D三个节点。FastDFS采用组存储.一个集群由一个或多个组组成,集群的总存储容量是集群中所有组的存储容量之和。一个组由一台或多台存储服务器组成,同一组内的多台存储服务器之间存在备份关系,同一组内的存储服务器上的文件完全一致。可以在组内任意一台Storageserver上进行文件上传、下载、删除等操作。类似于木桶短板效应,一个组的存储容量是组内存储服务器容量最小的那一个,可见组内存储服务器的软硬件配置是绝对一致的.采用分组存储方式的优点是灵活、可控性强。比如上传文件时,客户端可以直接指定上传到的群组。当组内存储服务器访问压力较大时,可以通过向组内添加存储服务器来扩展服务能力(垂直扩展)。当系统容量不足时,可以通过添加组来扩展存储容量(横向扩展)。通过这样的分组存储方式,可以使用FastDFS来管理文件,使用Apache、nginx等主流Web服务器来下载文件。#p#点对点结构FastDFS集群中也可以有多个Trackerserver,Trackerserver和Storageserver都不存在单点问题。Trackerservers之间是点对点的关系,组内Storageservers之间也是点对点的关系。传统Master-Slave结构中的Master是单点的,写操作只针对Master。如果Master失效,需要将Slave提升为Master,实现逻辑会比较复杂。与Master-Slave结构相比,对等结构中所有节点的状态都是一样的,每个节点都是Master,不存在单点问题。#p#FastDFS体系结构图1显示了FastDFS的系统体系结构。图1FastDFS系统架构从图1可以看出,Trackerservers之间相互独立,没有直接联系。Client和Storageserver主动连接到Trackerserver。Storageserver主动向Trackerserver上报自己的状态信息,包括磁盘剩余空间、文件同步状态、文件上传下载次数等统计信息。Storageserver将连接到集群中的所有Trackerservers并向它们报告其状态。Storageserver启动一个单独的线程来完成连接和定时报告给一个Trackerserver。需要注意的是,一个组中包含的Storageserver并不是通过配置文件设置的,而是通过Trackerserver获取的。不同组内的Storageserver之间不会互通,同一组内的Storageserver之间会相互连接进行文件同步。Storageserver使用binlog文件记录文件上传、删除等更新操作。binlog中只记录文件名,不记录文件内容。文件同步只在同组的Storageserver之间进行,采用push的方式,即源服务器同步到目标服务器。只需要同步源数据,备份数据不需要再次同步,否则会形成循环。有一个例外,即当添加新的Storageserver时,现有的Storageserver会将所有现有数据(包括源数据和备份数据)同步到新服务器。在Storageserver中,有一个专门的线程根据binlog进行文件同步。为了最大程度避免相互影响,为了系统的简洁,Storageserver会为组内除自身以外的每台服务器启动一个线程来进行文件同步。文件同步采用增量同步方式,系统将同步位置(binlog文件偏移)记录到标识文件中。标识文件名格式:{deststorageIP}_{port}.mark,例如:192.168.1.14_23000.mark。#p#文件上传下载的交互过程接下来我们看一下文件上传下载的交互过程。文件上传和下载过程分别如图2和图3所示。文件上传过程的步骤如下:图2文件上传流程图3文件下载过程1.Client向Trackerserver上传的Storageserver请求;2.Trackerserver返回一个可用的Storageserver,返回数据为Storageserver的IP地址和端口;3.Client直接与Storageserver建立连接上传文件,Storageserver返回新生成的文件ID,文件上传结束。#p#文件下载过程的步骤如下:1.Client向Trackerserver请求可以下载指定文件的Storageserver,参数为文件ID(包括组名和文件名);2.Trackerserver返回一个可用的Storageserver;3.Client直接与指定文件通信Storageserver建立连接,完成文件下载。#p#提出文件同步延迟问题客户端上传文件到Storageserver后,文件上传工作就结束了。Storageserver会根据binlog中的上传记录,将这个文件同步到同组的其他Storageserver。这样的文件同步方式是一种异步方式,异步方式带来了文件同步延迟的问题。上传新文件后,如果在未同步的Storageserver上访问该文件,将找不到该文件。FastDFS是如何解决文件同步延迟问题的?文件访问分为文件更新和文件下载两种情况。文件更新包括设置附加文件属性和删除文件。文件的附加属性包括文件大小、图片宽度、图片高度等。在FastDFS中,文件更新操作会优先选择源Storageserver,即文件上传到的Storageserver。这种方式不仅避免了文件同步延迟的问题,也有效避免了在多个Storageserver上更新同一个文件可能带来的时序错乱问题。那么文件下载如何解决文件同步延迟的问题呢?要回答这个问题,您需要了解文件名中包含哪些信息。Storageserver生成的文件名包括源Storageserver的IP地址、文件创建时间等字段。文件创建时间就是UNIX时间戳,后面就叫文件时间戳。从文件名或文件ID,可以破译这两个字段。那么我们来看看Trackerserver是如何准确知道一个文件已经同步到Storageserver的。前面提到,文件同步采用主动推送的方式。此外,每台存储服务器会定期向跟踪器服务器报告其已同步到同一组中其他存储服务器的文件的时间戳。当trackerserver收到一个storageserver的文件同步报告后,会依次找出组内每个storageserver(以下简称S)同步到的文件时间戳的最小值,作为属性记录在内存中S.#p#FastDFS对文件同步延迟问题的解决方案我们来看看FastDFS采用的解决方案。最简单的解决方案之一,就像文件更新一样,是先选择源存储服务器来下载文件。这个可以在Trackerserver的配置文件中设置,对应的参数名为download_server。另一种选择Storageserver的方法是循环法。当Client询问Trackerserver有哪些Storageservers可以下载指定的文件时,Trackerserver返回满足以下四种情况之一的Storageserver:文件上传到的源Storageserver,文件是直接上传到服务器的;thefilecreationtimestamp文件同步完成所需的**时间(如5分钟);(当前时间-文件创建时间戳)>文件同步延迟阈值,比如我们设置阈值为1天,就表示文件同步肯定能在1天内完成。#p#结语看了上面的介绍,是不是觉得FastDFS更加简洁高效呢?一位前雅虎同事,资深系统架构师,在听了FastDFS的介绍后做出了这样的评价:“FastDFSisapoorman'ssolution”。他的意思是FastDFS做到了最好的简洁和高效,非常节省资源,对于中小型网站来说完全可以负担??得起。这是对FastDFS的极大认可和赞扬。自2008年7月发布以来,FastDFS已经推出了31个版本,后续的改进和优化工作正在进行中。目前已经有很多公司在生产环境中使用了FastDFS。相信通过我们的不懈努力,FastDFS一定会越来越好!作者简介:余青,现淘宝Java中间件团队,从事Java基础平台的研发工作。他在Internet开发和架构方面拥有10年的经验。曾任新浪网开发工程师,雅虎中国架构师。开源分布式文件系统FastDFS和分布式哈希系统FastDHT的作者对分布式数据存储架构有深入研究。