FastDFS分布式存储
分布式文件系统 FastDFS 入门与集群部署实战
在大数据与云计算飞速发展的今天,海量非结构化数据(如图片、视频、文档)的存储与管理成为企业面临的重大挑战。传统单机存储方案受限于容量、性能和可靠性,已难以满足高并发、高可用和横向扩展的需求。FastDFS 作为一款开源的轻量级分布式文件系统,凭借其简洁高效的设计、良好的横向扩展能力及低成本的实现方案,成为中小型企业构建私有云存储或处理海量文件场景的优选方案
一、FastDFS 介绍
FastDFS 是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等。
FastDFS 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用 FastDFS 很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
补充知识点:FastDFS 适用场景与局限性
- 适用场景:中小规模(百 GB 级~数 TB 级)的图片 / 视频 / 附件存储,中小互联网业务的静态资源托管,对成本敏感、追求快速部署的私有云存储场景。
- 局限性:
- 不支持 POSIX 文件系统接口,只能通过专用 API 或 HTTP 访问;
- 不支持随机写入,仅支持追加 / 覆盖式修改;
- 不支持快照、复杂权限控制等高级特性;
- 大规模集群(千台以上节点)下的运维复杂度较高。
二、FastDFS 核心原理
FastDFS 是一个开源的轻量级分布式文件系统,纯 C 语言实现,目前提供了 C、Java 和 PHP API。功能包括:文件存储,文件同步,文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。
FastDFS 系统有三个核心角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server) 和 客户端(Client)。客户端请求 Tracker 服务器进行文件上传、下载,通过 Tracker 服务器调度最终由 Storage 服务器完成文件上传和下载,在底层存储上通过逻辑的分组概念,使得通过在同组内配置多个 Storage,从而实现软 RAID10。
1. FastDFS 架构详解
1.1 Tracker Server(跟踪服务器)
跟踪服务器,主要做调度工作,起到负载均衡的作用;负责管理所有的 Storage Server 和 Group(存储组)。
每个 Storage 在启动后会连接 Tracker,告知自己所属 Group 等信息,并保持周期性心跳。Tracker 上的元信息都是由 Storage 汇报的信息生成的,本身不需要持久化任何数据,这样使得 Tracker 非常容易扩展,直接增加 Tracker 机器即可扩展为 Tracker Cluster 服务,Cluster 里每个 Tracker 之间是完全对等的,所有的 Tracker 都接受 Storage 的心跳信息,生成元数据信息来提供读写服务,Tracker 根据 Storage 的心跳信息,建立 group => [storage server list] 的映射表。
1.2 Storage Server(存储服务器)
存储服务器,主要提供容量和备份服务:以 Group 为单位,每个 Group 内部可以有多台 Storage Server,数据互为备份。客户端上传的文件最终存储在 Storage 服务器上,Storage Server 没有实现自己的文件系统,而是利用操作系统的文件系统来管理文件,可以将 Storage 称为存储服务器。Storage 可配置多个数据存储目录,比如有 10 块磁盘,分别挂载在 /data/disk1~/data/disk10,则可将这 10 个目录都配置为 Storage 的数据存储目录。
1.3 Client(客户端)
客户端,即上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。FastDFS 向使用者提供基本文件访问接口,比如 upload、download、append、delete 等,以客户端库的方式提供给用户使用。
2. 文件上传流程详解
FastDFS 文件上传的核心流程如下:
- 客户端选择 Tracker Server:当集群中不止一个 Tracker 服务器时,由于 Tracker 之间是完全对等的关系,客户端在上传文件时可以任意选择一个 Tracker。
- Tracker 分配 Group:当 Tracker 接收到
upload_file的请求时,会为该文件分配一个可以存储该文件的 Group,支持以下选择规则:Round Robin:所有的 Group 间轮询;Specified Group:指定某一个确定的 Group;Load Balance:剩余存储空间多的 Group 优先。
- Tracker 分配 Storage Server:当选定 Group 后,Tracker 会在 Group 内选择一个 Storage Server 给客户端,支持以下选择规则:
Round Robin:在 Group 内的所有 Storage 间轮询;First server ordered by ip:按 IP 排序;First server ordered by priority:按优先级排序(优先级在 Storage 上配置)。
- 客户端写入 Storage Server:当分配好 Storage Server 后,客户端将向 Storage 发送写文件请求,Storage 将会为文件分配一个数据存储目录,支持以下规则:
Round Robin:多个存储目录间轮询;- 剩余存储空间最多的优先。
- 生成 FileId(文件标识):选定存储目录之后,Storage 会为文件生成一个 FileId,由 Storage 服务器 IP、文件创建时间、文件大小、文件 CRC32 和一个随机数拼接而成,然后将这个二进制串进行 Base64 编码,转换为可打印的字符串。选择两级目录:当选定存储目录之后,Storage 会为文件分配一个 FileId,每个存储目录下有两级
256*256的子目录,Storage 会按文件 FileId 进行两次 Hash,路由到其中一个子目录,然后将文件以 FileId 为文件名存储到该子目录下。 - 生成文件名:当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名,文件名由
group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。
上传成功后,客户端会收到一个完整的文件 ID,格式为 group_name/虚拟磁盘路径/两级目录/FileId,例如:group1/M00/02/44/wKgDrE34E8wAAAAAAAGkEIYJK42378.sh。
3. 文件下载流程详解
跟 upload_file 一样,在 download_file 时客户端可以选择任意 Tracker 服务器。Tracker 发送 download 请求给某个 Tracker,必须带上文件信息,Tracker 从文件名中解析出文件的 group、大小、创建时间 等信息,然后为该请求选择一个 Storage 服务器用来读请求。
(1)定位文件
客户端上传文件后,存储服务器将文件 ID 返回给客户端,此文件 ID 用于以后访问该文件的索引信息。文件索引信息包括:组名、虚拟磁盘路径、数据两级目录、文件名。
- 组名:文件上传后所在的 Storage 组名称,在文件上传成功后由 Storage 服务器返回,需要客户端自行保存。
- 虚拟磁盘路径:Storage 配置的虚拟路径,与磁盘选项
store_path*对应。如果配置了store_path0则是M00,如果配置了store_path1则是M01,以此类推。 - 数据两级目录:Storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
- 文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器 IP 地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。
(2)文件定位过程
- 通过组名,Tracker 能够快速定位到客户端需要访问的存储服务器组,并选择合适的存储服务器提供客户端访问;
- 存储服务器根据 “文件存储虚拟磁盘路径” 和 “数据文件两级目录” 可以很快定位到文件所在目录,并根据文件名找到客户端需要访问的文件。
4. 同步时间管理与数据同步机制
当一个文件上传成功后,客户端马上发起对该文件下载请求(或删除请求)时,Tracker 如何选定一个适用的存储服务器呢?其实每个存储服务器都需要定时将自身的信息上报给 Tracker,这些信息就包括了本地同步时间(即,同步到的最新文件的时间戳)。而 Tracker 根据各个存储服务器的上报情况,就能够知道刚刚上传的文件,在该存储组中是否已完成了同步。
FastDFS 数据同步机制补充
FastDFS 同组内的 Storage 节点之间会自动进行数据同步,核心机制如下:
- 主动同步:文件上传到主 Storage 后,自动同步到同组其他副本节点;
- 被动同步:可手动触发同步过程,将文件从主 Storage 同步到其他副本;
- 异步同步:文件上传后,后台线程异步完成副本同步,不阻塞客户端上传流程;
- 同步日志(Binlog):每个 Storage 写文件后,同时会写一份 Binlog,Binlog 里不包含文件数据,只包含文件名等元信息,用于后台同步,Storage 会记录向 Group 内其他 Storage 同步的进度,以便重启后能按上次的进度继续同步;进度以时间戳的方式进行记录,所以能保证集群内所有 Server 的时钟保持同步。
Tracker 会根据 Storage 上报的同步时间戳,选择数据最新的节点响应客户端请求,避免用户访问到还未同步完成的文件。
三、FastDFS 集群部署实战
本次部署采用 2 台 Tracker + 2 台 Storage + 1 台 Nginx 代理的架构,所有节点均使用 OpenEuler 24 操作系统,部署前先规划环境:
| 操作系统 | 配置 | 主机名 | IP | 备注 |
|---|---|---|---|---|
| OpenEuler24 | 2C4G | tracker01 | 192.168.10.101 | 跟踪服务器 1 |
| OpenEuler24 | 2C4G | tracker02 | 192.168.10.102 | 跟踪服务器 2 |
| OpenEuler24 | 2C4G | storage1 | 192.168.10.103 | 存储服务器 1 |
| OpenEuler24 | 2C4G | storage2 | 192.168.10.104 | 存储服务器 2 |
| OpenEuler24 | 2C4G | nginx | 192.168.10.105 | 代理服务器 |
FastDFS 相关软件包下载地址:
- FastDFS:https://github.com/happyfish100
- libfastcommon:基础依赖库
- fastdfs-nginx-module:Nginx 访问 FastDFS 模块
- nginx-1.19.5:反向代理服务器
1. 基础环境准备(所有节点执行)
1.1 关闭防火墙与 SELinux
bash
运行
# 关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭内核安全机制
setenforce 0
sed -i "s/^SELINUX=.*/SELINUX=disabled/g" /etc/selinux/config
1.2 安装依赖包
bash
运行
yum -y install zlib-devel gcc* libtool pcre-devel
yum -y install libjpeg libevent
2. 安装 libfastcommon(所有节点执行)
libfastcommon 是 FastDFS 的基础依赖库,必须先安装:
bash
运行
# 解压源码包
tar zxvf libfastcommon-1.0.36.tar.gz
cd libfastcommon-1.0.36
# 编译安装
./make.sh
./make.sh install
# 配置库文件
cd /usr/lib64
ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
cp libfastcommon.so /usr/lib/
3. 安装编译 FastDFS(所有节点执行)
bash
运行
# 解压 FastDFS 源码包
tar zxvf fastdfs-5.11.tar.gz
cd fastdfs-5.11
# 编译安装
./make.sh
./make.sh install
# 复制配置文件模板
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
cp conf/http.conf /etc/fdfs/
cp conf/mime.types /etc/fdfs/
4. 配置 Tracker 服务器(tracker01、tracker02 节点执行)
4.1 修改 Tracker 配置文件
bash
运行
vi /etc/fdfs/tracker.conf
修改以下关键配置:
ini
disabled=false # 启用配置文件
port=22122 # tracker 服务器端口(默认22122)
base_path=/fastdfs/tracker # 存储日志和数据的根目录
store_group=group1 # 设置存储组名称(可自定义)
4.2 创建基础目录
bash
运行
mkdir -p /fastdfs/tracker
4.3 启动 Tracker 服务
bash
运行
/etc/init.d/fdfs_trackerd start
# 验证启动状态
ps -ef | grep fdfs_trackerd
补充:Tracker 高可用说明
两台 Tracker 节点完全对等,客户端可同时配置多个 Tracker 地址,实现故障自动切换。Tracker 本身不存储数据,所有元数据均由 Storage 节点上报,因此无需主从复制,直接横向扩展即可。
5. 配置 Storage 服务(storage1、storage2 节点执行)
5.1 修改 Storage 配置文件
bash
运行
vi /etc/fdfs/storage.conf
修改以下关键配置:
ini
disabled=false # 启用配置文件
port=23000 # storage 服务器端口
base_path=/fastdfs/storage # 数据和日志文件存储目录
store_path0=/fastdfs/storage # 第一个存储目录(可配置多个 store_path*)
tracker_server=192.168.10.101:22122 # tracker 服务器IP和端口
tracker_server=192.168.10.102:22122 # 配置两个 tracker 实现高可用
group_name=group1 # 需要和 tracker 中的组名保持一致
http.server_port=8888 # http 访问文件的端口
5.2 创建基础数据目录
bash
运行
mkdir -p /fastdfs/storage
5.3 启动 Storage 服务
bash
运行
/etc/init.d/fdfs_storaged start
# 验证启动状态
ps -ef | grep fdfs_storaged
补充:Storage 节点数据同步说明
同组内的 Storage 节点会自动进行数据同步,无需手动配置。Storage 启动后会向所有 Tracker 节点上报心跳,包含自身状态、剩余空间、同步时间戳等信息,Tracker 会据此维护节点健康状态。
6. 配置 Client 客户端(任意 FastDFS 节点执行)
bash
运行
vi /etc/fdfs/client.conf
修改以下关键配置:
ini
base_path=/fastdfs/tracker
tracker_server=192.168.10.101:22122
tracker_server=192.168.10.102:22122
7. 测试文件上传(任意节点执行)
7.1 上传文件
bash
运行
# 方式1:使用 fdfs_upload_file 命令上传
fdfs_upload_file /etc/fdfs/client.conf logo.jpg
# 方式2:使用 fdfs_test 工具上传
fdfs_test /etc/fdfs/client.conf upload logo.jpg
7.2 查看上传结果
上传成功后会返回文件 ID,例如:group1/M00/00/00/wKgKZ2gaACmAb6raAAFMnKMrMI895.jpg,同时会输出文件访问 URL:http://192.168.10.103/group1/M00/00/00/wKgKZ2gaACmAb6raAAFMnKMrMI895.jpg。
7.3 验证文件存储目录
文件实际存储路径为:/fastdfs/storage/data/00/00/wKgKZ2gaACmAb6raAAFMnKMrMI895.jpg,可通过以下命令查看:
bash
运行
ls -lh /fastdfs/storage/data/00/00/
8. 配置 fastdfs-nginx-module 与 Nginx(所有 Storage 节点执行)
FastDFS 通过 Tracker 服务器,将文件放在 Storage 服务器存储,但是同组存储服务器之间需要进入文件复制,有同步延迟的问题。假设 Tracker 服务器将文件上传到了 storage01,上传成功后文件 ID 已经返回给客户端。此时 FastDFS 存储集群机会将这个文件同步到同组存储 storage02,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 storage02 上取文件,就会出现文件无法访问的错误。而 fastdfs-nginx-module 可以重定向文件连接到文件上传时的源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。
8.1 解压并修改 fastdfs-nginx-module 配置
bash
运行
tar zxvf fastdfs-nginx-module-v1.16.tar.gz
cd fastdfs-nginx-module/src
# 修改 config 文件,指定依赖库路径
vi config
# 修改以下内容(主要是路径修正)
ngx_addon_name=ngx_http_fastdfs_module
HTTP_MODULES="$HTTP_MODULES ngx_http_fastdfs_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_fastdfs_module.c"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
CORE_LIBS="$CORE_LIBS -L/usr/lib -lfastcommon -lfdfsclient"
CFLAGS="$CFLAGS -D_FILE_OFFSET_BITS=64 -DFDFS_OUTPUT_CHUNK_SIZE=256*1024 -DFDFS_MOD_CONF_FILENAME=\"/etc/fdfs/mod_fastdfs.conf\""
8.2 复制模块配置文件
bash
运行
cp /root/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
vi /etc/fdfs/mod_fastdfs.conf
修改关键配置:
ini
connect_timeout=10
base_path=/tmp
tracker_server=192.168.10.101:22122
tracker_server=192.168.10.102:22122
url_have_group_name=true # 表示URL中包含组名称
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/fastdfs/storage
8.3 编译安装 Nginx(集成 fastdfs 模块)
bash
运行
# 解压 Nginx 源码包
tar zxvf nginx-1.19.5.tar.gz
cd nginx-1.19.5
# 复制 FastDFS 头文件
cp /usr/include/fastdfs/* /usr/include/
cp /usr/include/fastcommon/* /usr/include/
# 配置 Nginx,添加 fastdfs 模块
./configure \
--prefix=/usr/local/nginx \
--user=nginx \
--group=nginx \
--add-module=/root/fastdfs-nginx-module/src/
# 编译安装
make && make install
# 创建软链接
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
8.4 配置 Nginx 支持 FastDFS
bash
运行
vi /usr/local/nginx/conf/nginx.conf
在 http 块中添加以下配置:
nginx
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
server {
listen 80;
server_name localhost;
location /group1/M00 {
ngx_fastdfs_module;
}
}
}
8.5 启动 Nginx
bash
运行
# 创建 Nginx 用户
useradd nginx -s /sbin/nologin
# 启动 Nginx
nginx
# 验证启动状态
ps -ef | grep nginx
9. 部署 Nginx 代理(代理节点执行)
代理节点的作用是统一入口,将请求转发到后端 Storage 节点,实现负载均衡:
bash
运行
# 安装 Nginx(同步骤8的编译安装方式,无需添加 fastdfs 模块)
tar zxvf nginx-1.19.5.tar.gz
cd nginx-1.19.5
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
make && make install
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin/
# 修改代理配置
vi /usr/local/nginx/conf/nginx.conf
添加 upstream 和 proxy_pass 配置:
nginx
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream storage_server_group1 {
server 192.168.10.103:80 weight=10;
server 192.168.10.104:80 weight=10;
}
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://storage_server_group1;
}
}
}
启动代理 Nginx 后,即可通过代理节点 IP 访问文件:
plaintext
http://192.168.10.105/group1/M00/00/00/wKgKZ2gaACmAb6raAAFMnKMrMI895.jpg
四、FastDFS 总结与扩展
通过本文的学习,我们全面认识了 FastDFS 作为轻量级分布式文件系统的技术特点:通过 Tracker Server 调度与 Storage Server 分组存储实现高效负载均衡,支持断点续传、文件同步与高可用容错,尤其适合中小规模非结构化数据存储场景。从环境部署到集群配置,从客户端集成到性能调优,我们实践了 FastDFS 的完整搭建流程,并探讨了其与 Nginx、CDN 等技术结合的优化方案。
尽管 FastDFS 在元数据管理、动态扩容灵活性等方面存在一定局限性,但其低门槛、高性价比的特性仍使其在特定场景中具有强大生命力。希望通过本文的学习,你不仅能掌握 FastDFS 的技术细节,更能领悟分布式系统设计的核心思想,为未来应对更复杂的存储需求积累宝贵经验。
补充知识点:FastDFS 性能优化与运维建议
- 存储目录优化:配置多个
store_path,分散磁盘 I/O 压力,避免单盘瓶颈; - 内存与磁盘配置:Tracker 节点建议配置 4G+ 内存,Storage 节点建议使用 SSD 存储热点数据,机械盘存储冷数据;
- 监控告警:通过
fdfs_monitor工具监控集群状态,配置磁盘使用率、节点心跳、同步延迟告警; - 备份策略:同组多副本 + 跨组备份,避免单组故障导致数据丢失;
- 限流与缓存:前端搭配 CDN 缓存静态资源,减少回源请求,降低 Storage 节点压力。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)