FastDFS 分布式存储
目录
一、介绍
二、FastDFS 原理
1、FastDFS架构
(1)Tracker server
(2)Storage server
(3)Client
2、文件的上传
(1)选择tracker server
(2)选择storage server
(3)选择storage path
(4)生成Fileid(文件标识)
(5)生成文件名
3、文件的下载
(1)定位文件
(2)定位文件所在的 group
(3)定位文件位置
4、同步时间管理
5、集成Nginx
三、FastDFS 部署
1、基础环境
2、安装libfastcommon
3、安装编译FastDFS
4、配置tracker 服务器
5、配置Storage 服务
6、配置client
7、测试上传文件
8、在所有storage节点安装fastdfs-nginx-module和nginx
9、部署代理
一、介绍
FastDFS 是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
FastDFs 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
二、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 服务器上,Storageserver 没有实现自己的文件系统,而是利用操作系统的文件系统来管理文件,可以将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 之间是完全对等的关系,客户端在 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、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。
3、文件的下载
跟 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)定位文件位置
存储服务器根据“文件存储虚拟磁盘路径”和“数据文件两级目录”可以很快定位到文件所在目录,并根据文件名找到客户端需要访问的文件
4、同步时间管理
当一个文件上传成功后,客户端马上发起对该文件下载请求(或删除请求)时,tracker是如何选定一个适用的存储服务器呢? 其实每个存储服务器都需要定时将自身的信息上报给 tracker,这些信息就包括了本地同步时间(即,同步到的最新文件的时间戳)。而 tracker根据各个存储服务器的上报情况,就能够知道刚刚上传的文件,在该存储组中是否已完成了同步。
同步信息上报如下图:
写文件时,客户端将文件写至 group内一个storage server 即认为写文件成功,storageserver 写完文件后,会由后台线程将文件同步至同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 部署
FastDFS 下载地址:https://github.com/happyfish100
fastdfs
libfastcommon
fastdfs-nginx-module
nginx-1.19.0
操作系统 | 主机 | IP | 备注 |
OpenEuler24 | 01 | 192.168.10.101 | 跟踪(tracker)服务器 |
OpenEuler24 | 02 | 192.168.10.102 | 跟踪(tracker)服务器 |
OpenEuler24 | 03 | 192.168.10.103 | 存储(storage)服务器 |
OpenEuler24 | 04 | 192.168.10.104 | 存储(storage)服务器 |
OpenEuler24 | 05 | 192.168.10.105 | 代理(nginx)服务器 |
1、基础环境
#关闭防火墙
systemctl stop firewalld
systemctl disable firewalld#关闭内核安全机制
setenforce 0
sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
2、安装libfastcommon
#01/02/03/04
dnf -y install zlib-devel gcc libtool pcre-devel
dnf -y install libeventtar zxvf libfastcommon-1.0.36.tar.gz
cd libfastcommon-1.0.36./make.sh #编译
./make.sh install #安装cd /usr/lib64
ll libfast* #查看所有以libfast开头的内容
cp libfastcommon.so /usr/lib #覆盖原有模块文件
3、安装编译FastDFS
#01/02/03/04
tar zxvf fastdfs-5.11.tar.gz
cd fastdfs-5.11./make.sh
./make.sh install
4、配置tracker 服务器
01/02
修改配置文件
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
vi /etc/fdfs/tracker.conf
disabled=false #4,启用配置文件
port=22122 #11,tracker 服务器端口(默认22122)
base_path=/fastdfs/tracker #22,存储日志和数据库的根目录
store_group=group1 #53,设置存储组名称
创建base_path 指定的目录
mkdir -p /fastdfs/tracker
启动tracker 服务器
/etc/init.d/fdfs_trackerd start
初次启动,会在/fastdfs/tracker 目录下生成 logs、data 两个目录
fdfs_trackerd /etc/fdfs/tracker.conf restart #重启服务
5、配置Storage 服务
03/04
修改配置文件
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
vim /etc/fdfs/storage.conf
disabled=false #4,启用配置文件
group_name=group1 #11,需要和tracker中的组名保持一致
port=23000 #24,storage服务端口
base_path=/fastdfs/storage #41,数据和日志文件存储根目录
store_path0=/fastdfs/storage #109,第一个存储目录
tracker_server=192.168.10.101:22122 #118,tracker服务器IP和端口
tracker_server=192.168.10.102:22122 #119,tracker服务器IP和端口
http.server_port=8888 #284,http访问文件的端口
创建基础数据目录
mkdir -p /fastdfs/storage
启动storage服务器,并检查进程
[root@bogon ~]# /etc/init.d/fdfs_storaged start[root@bogon ~]# ps -ef | grep fdfs_storaged
root 5631 1 0 13:42 ? 00:00:03 fdfs_storaged /etc/fdfs/storage.conf restart
root 5745 2821 0 15:26 pts/1 00:00:00 grep --color=auto fdfs_storaged
[root@bogon ~]#
6、配置client
在任意一个Fastdfs节点上配置,如02
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
mkdir -p /fastdfs/trackervim /etc/fdfs/client.conf
base_path=/fastdfs/tracker #10
tracker_server=192.168.10.101:22122 #14,tracker服务器IP和端口
tracker_server=192.168.10.102:22122 #15,tracker服务器IP和端口
7、测试上传文件
[root@bogon ~]# fdfs_upload_file /etc/fdfs/client.conf logo.jpg
group1/M00/00/00/wKgKZ2hKYbeACu5YAAGpeNijigU142.jpg或[root@bogon ~]# fdfs_test /etc/fdfs/client.conf upload logo.jpg
This is FastDFS client test program v5.11Copyright (C) 2008, Happy Fish / YuQingFastDFS may be copied only under the terms of the GNU General
Public License V3, which may be found in the FastDFS source kit.
Please visit the FastDFS Home Page http://www.csource.org/
for more detail.[2025-06-12 13:13:29] DEBUG - base_path=/fastdfs/tracker, connect_timeout=30, network_timeout=60, tracker_server_count=2, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=192.168.10.103, port=23000server 2. group_name=, ip_addr=192.168.10.104, port=23000group_name=group1, ip_addr=192.168.10.104, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/wKgKaGhKYhKAZEGNAAGpeNijigU477.jpg
source ip address: 192.168.10.104
file timestamp=2025-06-12 13:13:54
file size=108920
file crc32=3634596357
example file url: http://192.168.10.104/group1/M00/00/00/wKgKaGhKYhKAZEGNAAGpeNijigU477.jpg
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/wKgKaGhKYhKAZEGNAAGpeNijigU477_big.jpg
source ip address: 192.168.10.104
file timestamp=2025-06-12 13:13:54
file size=108920
file crc32=3634596357
example file url: http://192.168.10.104/group1/M00/00/00/wKgKaGhKYhKAZEGNAAGpeNijigU477_big.jpg
注意:
group1/M00:此目录是生成的虚拟目录
文件存储的目录为03或04上的/fastdfs/storage/data/00/00
03/04
[root@bogon ~]# ll /fastdfs/storage/data/00/00
总计 332
-rw-r--r--. 1 root root 108920 6月12日 13:13 wKgKaGhKYhKAZEGNAAGpeNijigU477_big.jpg
-rw-r--r--. 1 root root 49 6月12日 13:13 wKgKaGhKYhKAZEGNAAGpeNijigU477_big.jpg-m
-rw-r--r--. 1 root root 108920 6月12日 13:13 wKgKaGhKYhKAZEGNAAGpeNijigU477.jpg
-rw-r--r--. 1 root root 49 6月12日 13:13 wKgKaGhKYhKAZEGNAAGpeNijigU477.jpg-m
-rw-r--r--. 1 root root 108920 6月12日 13:12 wKgKZ2hKYbeACu5YAAGpeNijigU142.jpg
8、在所有storage节点安装fastdfs-nginx-module和nginx
FastDFs 通过 Tracker 服务器,将文件放在 Storage 服务器存储,但是同组存储服务器之间需要进入文件复制,有同步延迟的问题。假设 Tracker 服务器将文件上传到了storage03,上传成功后文件ID已经返回给客户端。此时 FastDFS 存储集群机制会将这个文件同步到同组存储 storage04,在文件还没有复制完成的情况下,客户端如果用这个文件 ID在storage04 上取文件,就会出现文件无法访问的错误。而 fastdfs-nginx-module 可以重定向文件连接到源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。(解压后的 fastdfs-nginx-module 在nginx 安装时使用)
storage 上的 nginx 是用于访问具体的文件,并且需要使用 fastdfs 模块。
03/04
解压并修改fastdfs-nginx-module的配置文件
tar zxvf fastdfs-nginx-module_v1.16.tar.gz
cd fastdfs-nginx-module/src/
vi configCORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/" #4
CORE_LIBS="$CORE_LIBS -L/usr/lib -lfastcommon -lfdfsclient" #5
编译安装Nginx
tar zxvf nginx-1.19.5.tar.gz
cd nginx-1.19.5
useradd nginx
cp /usr/include/fastcommon/* /usr/include/fastdfs/
./configure --prefix=/usr/local/nginx --add-module=/root/fastdfs-nginx-module/src/ --with-cc-opt="-Wno-error=format-truncation"
注意:这里的-add-module后面的只就是刚刚拷贝的fastdfs-nginx-module的src目录。
make && make install
ln -s /usr/local/nginx/sbin/* /usr/local/sbin/
配置FastDFS
将 fastdfs-nginx-module 模块下的 mod fastdfs.conf 文件拷贝到 /etc/fdfs/日录
cp /root/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
vim /etc/fdfs/mod_fastdfs.conftracker_server=192.168.10.101:22122
tracker_server=192.168.10.102:22122
url_have_group_name = true #53,这个表示是否需要增加一个上述自定义名字的需要,改为true,url中包括group名称
store_path0=/fastdfs/storage
复制FastDFS的部分配置文件到/etc/fdfs目录
cp /root/fastdfs-5.11/conf/http.conf /etc/fdfs/
cp /root/fastdfs-5.11/conf/mime.types /etc/fdfs/
在/fastdfs/storage 文件存储目录下创建软连接,将其链接到实际存放数据的目录
ln -s /fastdfs/storage/data /fastdfs/storage/M00
配置Nginx
vim /etc/usr/local/nginx/conf/nginx.conflocation /group1/M00 {ngx_fastdfs_module;
}
nginx -t
nginx
浏览器访问图片
http://192.168.10.103/group1/M00/00/00/wKgKaGhKYhKAZEGNAAGpeNijigU477_big.jpg
或
http://192.168.10.104/group1/M00/00/00/wKgKaGhKYhKAZEGNAAGpeNijigU477_big.jpg
9、部署代理
05
dnf -y install pcre-devel zlib-devel gcc
tar zxvf nginx-1.19.5.tar.gz
cd nginx-1.19.5
useradd nginx
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
make && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/vim /usr/loca/nginx/conf/nginx.conf
http {upstream mycluster {server 192.168.10.103:80 weight=1;server 192.168.10.104:80 weight=1;
}server {location / {proxy_pass http://mycluster;}}
}
http://192.168.10.105/group1/M00/00/00/wKgKaGhKYhKAZEGNAAGpeNijigU477_big.jpg