本文共 6084 字,大约阅读时间需要 20 分钟。
概述
FastDFS是一个开源的轻量级分布式文件系统,用纯C语言实现,支持Linux、FreeBSD、AIX等UNIX系统。Fast只能通过专有API对文件进行存取访问,不支持POSIX接口方式,不能mount使用,不是系统级的分布式文件系统,而是应用级分布式文件系统。
FastDFS系统架构图
FastDFS主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。
FastDFS实现了软件方式的RAID,可以使用廉价的IDE硬盘进行存储,支持存储服务器在线扩容。
FastDFS特别适合大中型网站使用,用来存储资源文件(如:图片、文档、音频、视频等等。
存储节点采用了分组(group)的方式。存储系统由一个或多个group组成,group与group之间的文件是相互独立的,所有group的文件容量累加就是整个存储系统中的文件容量。一个group可以由一台或多台存储服务器组成,一个group下的存储服务器中的文件都是相同的,group中的多台存储服务器起到了冗余备份和负载均衡的作用(一个组的存储容量为该组内存储服务器容量最小的那个,不同组的Storageserver之间不会相互通信,同组内的Storageserver之间会相互连接进行文件同步)。
在group中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。
当存储空间不足或即将耗尽时,可以动态添加group。只需要增加一台或多台服务器,并将它们配置为一个新的group,这样就扩大了存储系统的容量。
FastDFS中的Storageserver在其他文件系统中通常称作Trunkserver或Dataserver。Storageserver直接利用OS的文件系统存储文件。FastDFS不会对文件进行分块存储,客户端上传的文件和Storageserver上的文件一一对应(FastDFS中的文件标识分为两个部分:组名和文件名,二者缺一不可)。
小文件的性能瓶颈主要来自于对元数据服务器(如FastDFS中的TrackerServer或TFS中的NameServer)的访问,因为当文件本身大小很小时,元数据存储所占空间与文件内容存储所占空间的比例就变得较大,访问元数据所消耗资源与访问文件内容所消耗资源的比例也变得较大。因此,通常对小文件存储的优化方法主要有两大类思路:一是减少访问元数据的次数,比如Cache预取;二是减少元数据所占的存储空间,比如FastDFS使用的文件名策略。
FastDFS中的文件名是在向StorageServer存储文件时由系统指定的,文件名中包含了VolumeID和FileID。也就是说,当客户要读取某个文件时,通过在客户端对文件名进行解析,就可以知道该文件存储在哪个Volume上和它在StorageServer中的FileID。但是此时用户还不能读取文件,因为他不知道Volume内各个StorageServer的ip地址,也不知道应该从Volume内的哪个StorageServer中读取。所以用户需手持欲访问的文件的VolumeID向TrackerServer询问,TrackerServer会均衡当前各StorageServer的IO负载状况,返回一个最佳的StorageServer的ip地址。最后用户与该StorageServer连接,出示欲访问文件的FileID,StorageServer上会维持一个FileID对应偏移量的表,从而得到欲访问文件的偏移量。
可见,FastDFS的文件名策略将文件存储位置信息隐含在文件名中,从而减少了元数据量,达到了优化小文件存储性能的作用。
Client询问TS上传到的SS;TS返回一台可用的SS;Client直接和SS建立连接,完成上传,并返回文件ID,文件上传结束。
Client向TS询问可以下载指定文件ID的SS;TS返回一可可用SS的信息;Client直接和SS建立连接,完成下载。
轻量级:
ü不需要记录文件索引信息,占用内存量少
ü直接利用OS的文件系统存储文件,不对文件进行分块存储
ü代码量较小
分组备份
ü集群由一个或多个组组成,集群存储总容量是所有组存储容量之和。一个组由一台或多台存储服务器组成,同组多台Storage sever之间是互相备份关系,所以同组ss上的文件是完全一致的。
对等结构
üTracker与之间是对等关系。
Tracker Server之间相互独立,Client和SS主动向TS发起连接,SS会连接集群中所有的TS,启动一个单独的线程一台TS发起连接和定时报告,SS向TS报告剩余空间,上传下载次数和同步信息等情况。
不同组的SS之间不相互通信,同组内的SS相互连接并进行文件同步。
SS采用binlog文件记录上传,删除等更新操作。Binlog中只记载文件名,不记载文件内容。文件同步采用push方式,即源头服务器同步给目标服务器。为避免相互影响和出于系统简洁性考虑,SS对组内除自己以你的服务器单独启动一个进程完成同步。
同步采用增量方式,系统记录已同步的位置(binlog文件偏移量)到标识文件中。标识文件名格式{dest storage IP}_{port}.mark
在FastDFS的服务器端配置文件中,bind_addr这个参数用于需要绑定本机IP地址的场合。只有这个参数和主机特征相关,其余参数都是可以统一配置的。在不需要绑定本机的情况下,为了便于管理和维护,建议所有trackerserver的配置文件相同,同组内的所有storageserver的配置文件相同。
tracker server的配置文件中没有出现storageserver,而storageserver的配置文件中会列举出所有的trackerserver。这就决定了storageserver和trackerserver之间的连接由storageserver主动发起,storageserver为每个trackerserver启动一个线程进行连接和通讯,这部分的通信协议请参阅《FastDFSHOWTO -- Protocol》中的“2. storage server to tracker servercommand”。
trackerserver会在内存中保存storage分组及各个组下的storageserver,并将连接过自己的storageserver及其分组保存到文件中,以便下次重启服务时能直接从本地磁盘中获得storage相关信息。storageserver会在内存中记录本组的所有服务器,并将服务器信息记录到文件中。trackerserver和storageserver之间相互同步storageserver列表:
1. 如果一个组内增加了新的storageserver或者storageserver的状态发生了改变,trackerserver都会将storageserver列表同步给该组内的所有storageserver。以新增storageserver为例,因为新加入的storageserver主动连接trackerserver,trackerserver发现有新的storageserver加入,就会将该组内所有的storageserver返回给新加入的storageserver,并重新将该组的storageserver列表返回给该组内的其他storageserver;
2. 如果新增加一台trackerserver,storageserver连接该trackerserver,发现该trackerserver返回的本组storageserver列表比本机记录的要少,就会将该trackerserver上没有的storageserver同步给该trackerserver。
同一组内的storageserver之间是对等的,文件上传、删除等操作可以在任意一台storageserver上进行。文件同步只在同组内的storageserver之间进行,采用push方式,即源服务器同步给目标服务器。以文件上传为例,假设一个组内有3台storageserver A、B和C,文件F上传到服务器B,由B将文件F同步到其余的两台服务器A和C。我们不妨把文件F上传到服务器B的操作为源头操作,在服务器B上的F文件为源头数据;文件F被同步到服务器A和C的操作为备份操作,在A和C上的F文件为备份数据。同步规则总结如下:
1. 只在本组内的storageserver之间进行同步;
2. 源头数据才需要同步,备份数据不需要再次同步,否则就构成环路了;
3. 上述第二条规则有个例外,就是新增加一台storageserver时,由已有的一台storageserver将已有的所有数据(包括源头数据和备份数据)同步给该新增服务器。
storageserver有7个状态,如下:
FDFS_STORAGE_STATUS_INIT:初始化,尚未得到同步已有数据的源服务器
FDFS_STORAGE_STATUS_WAIT_SYNC:等待同步,已得到同步已有数据的源服务器
FDFS_STORAGE_STATUS_SYNCING:同步中
FDFS_STORAGE_STATUS_DELETED:已删除,该服务器从本组中摘除(注:本状态的功能尚未实现)
FDFS_STORAGE_STATUS_OFFLINE:离线
FDFS_STORAGE_STATUS_ONLINE:在线,尚不能提供服务
FDFS_STORAGE_STATUS_ACTIVE:在线,可以提供服务
当storageserver的状态为FDFS_STORAGE_STATUS_ONLINE时,当该storageserver向trackerserver发起一次heartbeat时,trackerserver将其状态更改为FDFS_STORAGE_STATUS_ACTIVE。
组内新增加一台storageserver A时,由系统自动完成已有数据同步,处理逻辑如下:
1.storage server A连接trackerserver,trackerserver将storageserver A的状态设置为FDFS_STORAGE_STATUS_INIT。storageserver A询问追加同步的源服务器和追加同步截至时间点,如果该组内只有storageserver A或该组内已成功上传的文件数为0,则没有数据需要同步,storageserver A就可以提供在线服务,此时tracker将其状态设置为FDFS_STORAGE_STATUS_ONLINE,否则trackerserver将其状态设置为FDFS_STORAGE_STATUS_WAIT_SYNC,进入第二步的处理;
2. 假设trackerserver分配向storageserver A同步已有数据的源storageserver为B。同组的storageserver和trackerserver通讯得知新增了storageserver A,将启动同步线程,并向trackerserver询问向storageserver A追加同步的源服务器和截至时间点。storageserver B将把截至时间点之前的所有数据同步给storageserver A;而其余的storageserver从截至时间点之后进行正常同步,只把源头数据同步给storageserver A。到了截至时间点之后,storageserver B对storageserver A的同步将由追加同步切换为正常同步,只同步源头数据;
3.storage server B向storageserver A同步完所有数据,暂时没有数据要同步时,storageserver B请求trackerserver将storageserver A的状态设置为FDFS_STORAGE_STATUS_ONLINE;
4 当storageserver A向trackerserver发起heartbeat时,trackerserver将其状态更改为FDFS_STORAGE_STATUS_ACTIVE。
FastDFS的负载均衡一般不需要客户端另外开发。FastDFS的负载均衡实现原理与章文嵩博士提出的LVS原理相似。LVS共分三层,分别为负载均衡层,服务器集群层和数据共享层,分别对应FastDFS的tracker,WebServer和Storage。
LVS的包转发策略有三种:
NAT (NetworkAddress Translation)模式。LB收到用户请求包后,LB将请求包中虚拟服务器的IP地址转换为某个选定RS的IP地址,转发给RS;RS将应答包发给LB,LB将应答包中RS的IP转为虚拟服务器的IP地址,回送给用户。
IP隧道 (IPTunneling)模式。LB收到用户请求包后,根据IP隧道协议封装该包,然后传给某个选定的RS;RS解出请求信息,直接将应答内容传给用户。此时要求RS和LB都要支持IP隧道协议。
DR(DirectRouting)模式。LB收到请求包后,将请求包中目标MAC地址转换为某个选定RS的MAC地址后将包转发出去,RS收到请求包后 ,可直接将应答内容传给用户。此时要求LB和所有RS都必须在一个物理段内,且LB与RS群共享一个虚拟IP。
LVS的负载均衡算法有8种,QQ群中有同志建议使用FastDFS时在前端结合LVS。目前FastDFS对tracker应答仅支持简单轮询,对storage支持指定组,最小容量优先和简单轮询三种方式。余庆在论坛在回答客户端超过10k,希望结合LVS进行负载均衡的问题时,认为通常采用简单轮询就足够了,目前大多数应用使用FastDFS不需要另外结合负载均衡。
FastDFS本身的负载均衡机制已经是使其成为同类应用中佼佼者的重要特点之一,所以我认为OA系统也没有必要另外进行负载均衡。
目前网上可查到的资料没有对FastDFS的负载均衡做详述,以上内容是我的理解。详情请点击:
后记:最近一段时间部门在做集团公司OA系统,使用的文件系统是DFS。经过一段时间的预研,成功搭建并测试上传下载功能。本文共分三部分:1.FastDFS概述;2.FastDFS环境搭建及测试;3.配置文件详解及常见问题解决。
参考资料:
本文转自 gaochaojs 51CTO博客,原文链接:http://blog.51cto.com/jncumter/1308173,如需转载请自行联系原作者