一.FastDFS原理
FastDFS是一个开源的轻量级分布式文件系统,纯C实现,目前提供了C、Java和PHP API。功能包括:文件存储,文件同步,文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。
Fast DFS系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。client请求Tracker server 进行文件上传、下载,通过Tracker server调度最终由Storage server完成文件上传和下载,在底层存储上通过逻辑的分组概念,使得通过在同组内配置多个Storage,从而实现软RAID10。
1.FastDFS架构
(1)Tracker server
跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的Storage server和group,每个storage在启动后会连接Tracker,告知自己所属group等信息,并保持周期性心跳。tracker上的元信息都是由storage汇报的信息生成的,本身不需要持久化任何数据,这样使得tracker非常容易扩展,直接增加tracker机器即可扩展为tracker cluster来服务,cluster里每个tracker之间是完全对等的,所有的tracker都接受stroage的心跳信息,生成元数据信息来提供读写服务,tracker根据storage的心跳信息,建立group==>[storage server list]的映射表。
(2)storage server
存储服务器,主要提供容量和备份服务;以group为单位,每个group内部可以有多台storage server,数据互为备份。客户端上传的文件最终存储在storage服务器上,Storage server没有实现自己的文件系统,而是利用操作系统的文件系统来管理文件,可以将storage称为存储服务器。storage可配置多个数据存储目录,比如有10块磁盘,分别挂载在/data/disk1-/data/disk10,则可将这10个目录都配置为storage的数据存储目录。
(3)Client
客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。
跟踪服务器和存储节点都可以由一台或多台服务器构成,跟踪服务器和存储节点均可以随时增加或者下线不会影响线上服务,其中跟踪服务器中所有服务器是对 等,可以根据服务器压力情况随时增加或减少。
2.文件上传
Storage server会连接集群中所有的Tracker server,定时向他们报告自己的状态,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。上传的内部机制如下:
(1)选择tracker server
当集群中不止一个tracker server时,由于tracker之间是完全对等无状态的关系,当集群中不止一个tracker server时,由于tracker之间是完全对等的关系,客户端在upload文件时可以任意选择一个trakcer。 选择存储的group 当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、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。
3.文件的下载
跟upload file一样,在download file时客户端可以选择任意tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。
定位文件
客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。
(1)组名:文件上传后所在的storage组名称,在文件上传成功后有storage服务器返回,需要客户端自行保存。
(2)虚拟磁盘路径:storage配置的虚拟路径,与磁盘选项store_path*对应。如果配置了store_path0则是M00,如果配置了store_path1则是M01,以此类推。
(3)数据两级目录:storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
(4)文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。
知道FastDFS FID的组成后,我们来看看FastDFS是如何通过这个精巧的FID定位到需要访问的文件:
- 通过组名tracker能够很快的定位到客户端需要访问的存储服务器组,并将选择合适的存储服务器提供客户端访问
- 存储服务器根据“文件存储虚拟磁盘路径”和“数据文件两级目录”可以很快定位到文件所在目录,并根据文件名找到客户端需要访问的文件
4.同步时间管理
当一个文件上传成功后,客户端马上发起对该文件下载请求(或删除请求)时,tracker是如何选定一个适用的存储服务器呢? 其实每个存储服务器都需要定时将自身的信息上报给tracker,这些信息就包括了本地同步时间(即,同步到的最新文件的时间戳)。而tracker根据各个存储服务器的上报情况,就能够知道刚刚上传的文件,在该存储组中是否已完成了同步。同步信息上报如下图:
写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。
每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,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生成一个同步时间戳。
5.集成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
二.FastDFS部署
1.安装前准备
服务器:CentOS Linux release 7.9.2009 (Core)
FastDFS下载地址:https://github.com/happyfish100
(1)fastdfs
(2)libfastcommon
(3)fastdfs-nginx-module
(4)nginx-1.18.0
2.部署环境要求
3.在所有节点安装如下组件(代理服务器除外)
(1)安装gcc、libevent、zlib-devel、libtool、pcre-devel
yum -y install gcc* libevent zlib-devel libtool pcre-devel
(2)安装libfastcommon
tar -zxvf libfastcommon-1.0.36.tar.gz
cd libfastcommon-1.0.36
./make.sh
./make.sh install
(3)安装FastDFS
tar zxvf fastdfs-5.11.tar.gz
cd fastdfs-5.11
./make.sh
./make.sh install
备注:FastDFS安装完成,所有编译出来的文件存放在/usr/bin目录下, 所有配置文件存放在/etc/fdfs目录下,可以使用下放命令查看配置文件内容
ll /etc/fdfs
查看服务脚本
ll /etc/init.d/
查看命令工具
ll /usr/bin/fdfd_*
4.配置tracker服务器(在101和102主机上)
(1)复制tracker配置文件样本,并重名
cp /etc/fsfd/tracker.conf.sample /etc/fsfd/tracker.conf
(2)修改tracker配置文件
vim /etc/fsfd/track.conf
base_path=目录 #配置tracker存储数据的目录
store_group=group1 #设置存储组名称
(3)创建base-path 指定的tracker服务器数据存储目录
mkdir -p 目录(/fastdfs/tracker)
(4)启动tracker服务器
/etc/init.d/fdfs_track start
ps -ef | grep fdfs_track_traeckerd
5.配置storage服务(在103和104主机上)
(1)复制storage配置文件的样式文件将其重命名
cp /etc/fdfs/storage.conf.sample /etc/fdfs/stroage.conf
(2)编辑storage.conf配置文件
base_path=目录 #数据和日志的存储目录
base_path0=目录 #第一个存储目录
tracker_server=tracker跟踪服务器IP地址+端口(可以是多个)
group_name=group1 #和tracker中的组名保持一致
(3)创建数据存储目录
mkdir -p /fastdfs/storage
(4)启动storage服务器,并查看进程
/etc/init.d/fdfs_storaged start
ps -ef | grep fdfs_storaged
6.配置client客户端(在任意一条fastdfs节点上配置)4
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
mkdir -p /fastdfs/tracker
vim /etc/fdfs/clinet.conf
base_path=/fastdfs/stracker
tracker_server=rackerm=服务器IP地址和端口(有多少个tracker)
7.测试上传文件
fdfs_upload_file /etc/fdfs/client.conf 上传文件位置
或
fdfs_test /etc/fdfs/client.conf 上传的文件位置
切换到存储目录查看文件上传情况
cd 存储目录/data/00/00
ls
FastDFS生成的文件目录结构及名称示例
8.在所有storage节点安装fastdfs-nginx-module和nginx
fastDFS通过Tracker服务器,将文件放在Storage服务器存储,但是同组存储服务器之间需要进入文件复制,有同步延迟的问题,假设Tracker服务器将文件上传到了storage01,上传成功后文件ID已经返回给客户端。此时FastDFS存储集群机制会将这个文件同步到同组存储storage02,在文件还没有复制完成的情况下,客户端如果用这个文件ID在storage02上取文件,就会出现文件无法访问的错误。而fastdfs-nginx-module可以重定向文件连接到源服务器取文件,避免客户端由于复制延退导致的文件无法访问错误。(解压后的fastdfs-nginx--module在nginx安装时使用)
storage上的nginx是用于访问具体的文件,并且需要使用fastdfs模块
(1)解压并修改fastdfs-ngin-module的配置文件
tar zxvf fastdfs-ngin-module_v1.16.tar.gz
cd fastdfs-ngin-module/src
vim config
进入解压完成的目录,到src目录下,修改config配置文件,将文件路径中存放的local删掉。
修改完成后修改
cp /usr/include/fastcommon/* /usr/include/fastdfs/
(2)编译安装nginx
tar zxvf nginx-1.19.5.tar.gz
useradd -M -s /sbin/nologin nginx #创建系统用户,不创建家目录,不允许登录
cd nginx-1.19.5
./configure --prefix=安装目录 --user=nginx --greoup=nginx --add-module=/root/fastdfs-nginx-module/src
make
make install
ln -s 安装目录/sbin/* /usr/local/sbin/
(3)配置FASTDFS
将fast-nginx-module模块下的mod_fastdfs.conf文件拷贝到/etc/fds/目录
cp /root/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
vim /etc/fdfs/mod_fastdfs.conf
tracker_server=192.168.10.101:22122 #可以添加自己的服务器ip地址
url_have_group_name = true
store_path0=fastdfs/storage
(4)复制fastDfs的部分配置文件到/etc/fdfs目录
cp /root/fastdfs-5.11/conf/http.conf /root/fastdfs-5.11/conf/mime.types /etc/fdfs
(5) 在/fastdfs/storage文件存储目录下创建软链接,将其连接搭配实际存放数据的目录
ln -s /fastdfs/stroage/data/ /fastdfs/storage/data/M00
(6)配置nginx
vim /usr/local/nginx/conf/nginx.conf
location /group1/M00 {
ngx_fastdfs_module;
}
(7)重启nginx并测试
/usr/local/sbin/nginx
用上方测试上传获得的文件ID
9.部署nginx代理
在nginx安装完成后修改其配置文件
vim /usr/local/nginx/conf/nginx.conf
http{
upstream storage_sever_group1 {
server 192.168.10.103:80 weight=10;
server 192.168.10.104:80 weight=10;
}
server {
location / {
proxy_pass http://storage_server_group1;
}
}
}
用上方测试上传获得的文件ID但是把IP地址改为