前言
fastdfs是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(上传、下载)等,解决了大容量存储和负载均衡的问题。
fastds为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩展等机制,并注重高可用、高性能等指标,使用fastdfs很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
fastdfs原理
Fast DFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(storage server)和客户端(Client)。client 请求 Tracker server 进行文件上传、下载,通过 Tracker server 调度最终由storage server 完成文件上传和下载,在底层存储上通过逻辑的分组概念,使得通过在同组内配置多个storage,从而实现软 RAID10。
fastdfs架构
tracker server
跟踪服务器,主要做调度工作,起到均衡的作用;负贵管理所有的storage server 和group,每个storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。tracker 上的元信息都是由 storage 汇报的信息生成的,本身不需要持久化任何数据,这样使得 tracker 非常容易扩展,直接增加 tracker 机器即可扩展为tracker cluster 来服务,cluster 里每个 tracker 之间是完全对等的,所有的 tracker 都接受 stroage 的心跳信息,生成元数据信息来提供读写服务,tracker 根据storage 的心跳信息,建立 group==>[storage server list]的映射表。
storage server
存储服务器,主要提供容量和备份服务;以group为单位,每个group内部可以有多台 storageserver,数据互为备份。客户端上传的文件最终存储在 storage服务器上,storage server 没有实现自己的文件系统,而是利用操作系统的文件系统来管理文件,可以将 storage 称为存储服务器。storage
可配置多个数据存储目录,比如有 10 块磁盘,分别挂载在/data/disk1-/data/disk10,则可将这 10个目录都配置为storage 的数据存储目录。
client
客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。FastDFS 向使用者提供基本文件访问接口,比如 upload、download、append、delete 等,以客户端库的方式提供给用户使用。
跟踪服务器和存储节点都可以由一台或多台服务器构成,跟踪服务器和存储节点均可以随时增加或者下线不会影响线上服务,其中跟踪服务器中所有服务器是对 等,可以根据服务器压力情况随时增加或减么
文件的上传
storage server 会连接集群中所有的Tracker server,定时向他们报告自己的状态,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。
上传的内部机制如下:
(1)选择tracker server
当集群中不止一个 tracker server 时,由于 tracker 之间是完全对等的关系,客户端在 upload文件时可以任意选择一个 trakcer。 当tracker 接收到upload file 的请求时,会为该文件分配一个可以存储该文件的 group,支持如下选择 group 的规则:
Round robin,所有的group 间轮询
Specified group,指定某一个确定的 group
Load balance,剩余存储空间多 group 优先
(2)选择storage server
当选定group后,tracker会在group内选择一个storage server给客户端,支持如下选择storage
的规则:
Round robin,在group 内的所有storage 间轮询
First server ordered by ip,按ip 排序
>First server ordered by priority,按优先级排序(优先级在 storage 上配置)
(3)选择storage path
当分配好 storage server 后,客户端将向 storage 发送写文件请求,storage 将会为文件分配一个数据存储目录,支持如下规则:
Round robin,多个存储目录间轮询
剩余存储空间最多的优先
(4)生成Fileid(文件标识)
选定存储目录之后,storage 会为文件生一个Fileid,由storage server ip、文件创建时间、文件大小、文件 crc32 和一个随机数拼接而成,然后将这个二进制串进行 base64 编码,转换为可打印的字符串。 选择两级目录 当选定存储目录之后,storage 会为文件分配一个 fileid,每个存储目录下有两级 256*256 的子目录,storage 会按文件 fileid 进行两次 hash(猜测),路由到其中一个子目录,然后将文件以 fileid 为文件名存储到该子目录下。
(5)生成文件名当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名,文件名由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。
文件的下载
跟 upload file 一样,在 download file 时客户端可以选择任意 tracker server。tracker 发送download 请求给某个tracker,必须带上文件名信息,tracke 从文件名中解析出文件的 group、大小、创建时间等信息,然后为该请求选择一个storage 服务器用来读请求。
(1)定位文件
客户端上传文件后存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。
文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。
组名:文件上传后所在的 storage 组名称,在文件上传成功后有 storage 服务器返回,需要客户端自行保存。
虚拟磁盘路径:storage配置的虚拟路径,与盘选项store_path*对应。如果配置了
store_path0 则是 M00,如果配置了 store_path1 则是 M01,以此类推。
数据两级目录:storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。
知道 FastDFS FID的组成后,我们来看看 FastDFs 是如何通过这个精巧的 FID 定位到需要访问的文
件:
(2)定位文件所在的 group
通过组名 tracker 能够很快的定位到客户端需要访问的存储服务器组,并将选择合适的存储服务器提供客户端访问
(3)定位文件位置
存储服务器根据“文件存储虚拟磁盘路径”和“数据文件两级目录”可以很快定位到文件所在目录,并根据文件名找到客户端需要访问的文件
同步时间管理
当一个文件上传成功后,客户端马上发起对该文件下载请求(或删除请求)时,tracker 是如何选定一个适用的存储服务器呢? 其实每个存储服务器都需要定时将自身的信息上报给tracker,这些信息就包括了本地同步时间(即,同步到的最新文件的时间戳)。而 tracker 根据各个存储服务器的上报情况,就能够知道刚刚上传的文件,在该存储组中是否已完成了同步。同步信息上报如下图:
写文件时,客户端将文件写至 group 内一个 storage server 即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。
每个 storage 写文件后,同时会写一份 binlog,binlog 里不包含文件数据,只包含文件名等元信息,这份 bin1og用于后台同步,storage 会记录向 group 内其他 storage 同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server 的时钟保持同步。
storage 的同步进度会作为元数据的一部分汇报到 tracker 上,tracke 在选择读 storage 的时候会以同步进度作为参考。比如一个group 内有A、B、C三个storage server,A向C同步到进度为 T1(T1以前写的文件都已经同步到B上了),B向C同步到时间戳为T2(T2>T1),tracker 接收到这些同步进度信息时,就会进行整理,将最小的那个做为C的同步时间戳,本例中 T1 即为C的同步时间戳为 T1(即所有 T1 以前写的数据都已经同步到C上了):同理,根据上述规则,tracker 会为 A、B 生成一个同步时间戳。
集成nginx
FastDFs 通过 Tracker 服务器,将文件放在 storage 服务器存储,但是同组存储服务器之间需要进入文件复制,有同步延迟的问题。
假设 Tracker 服务器将文件上传到了 192.168.4.125,上传成功后文件 ID 已经返回给客户端。此时FastDFs 存储集群机制会将这个文件同步到同组存储 192.168,4.126,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 192.168.4.126上取文件,就会出现文件无法访问的错误。
而 fastdfs-nginx-module可以重定向文件连接到文件上传时的源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误,
另外,使用 nginx 反向代理后,后端可以以HTTP 请求的方式来访问文件资源。访问 nginx 反向代理+上传文件时的ID