FastDFS 简介
FastDFS 是基于 C 语言开发的,是一个轻量级开源的高性能分布式文件系统。主要功能有:文件存储、文件同步、文件访问(文件上传/下载),解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。FastDFS 特别适合中大型网站以文件为载体的在线服务,适合存储 4KB ~ 500MB 之间的小文件,如照片共享网站、视频共享网站(图片、文档、音频、视频等等)。
Github地址
FastDFS 架构
Client
客户端,实现文件上传下载的服务器,就是我们自己的项目所部署在的服务器。通过专有接口,使用 TCP/IP 协议与跟踪服务器或存储服务器进行数据交互。FastDFS 向使用者提供基本文件访问接口,比如 upload、download、append、delete等,以客户端库的方式提供给用户使用。
Tracker Server
跟踪服务器,负责文件访问的调度和负载均衡,负责管理所有的 Storage Server 和 group 组/卷。
Storage Server
存储服务器,负责文件存储,文件同步/备份,提供文件访问接口,文件元数据管理。以 group 为单位,每个 group 内可以有多台 Storage Server,数据互为备份,达到容灾的目的。每个 Storage 在启动以后会主动连接 Tracker,告知自己所属 group 等存储相关信息,并保持周期性心跳。
Group
组,也可称为 Volume 卷。同组内服务器上的文件是完全相的,同一组内的 Storage Server 之间是对等的,文件上传、删除等操作可以在任意一台 Storage Server 上进行。
Metadata
文件系统中存储的数据分为数据和元数据两部分,数据是指文件中的实际数据,即文件的实际内容;而元数据是用来描述一个文件特征的系统数据,诸如访问权限、文件拥有者以及文件数据块的分布信息等等。如果文件是一张图片,元数据就是图片的宽,高等等。
FastDFS 存储策略
为了支持大容量存储,Storage 存储服务器采用了分组(或分卷)的方式。存储系统由一个或多个组组成,组与组之间的文件是相互独立的,所有组的文件容量累加就是整个存储系统中的文件容量。一个组可以由一台或多台存储服务器组成,一个组下的存储服务器中的文件都是相同的,组中的多台存储服务器起到了冗余备份和负载均衡的作用。
当组中增加了新的服务器时,系统会自动同步已有的文件,同步完成后,系统自动将新增的服务器切换至线上提供服务。
当存储空间不足时,可以动态添加组,只需要增加一台或多台服务器,并将它们配置为一个新的组,即可扩大存储系统的容量。当你的某个应用或者模块(对应的 group)的并发过高的时候,可以直接在 group 中增加若干个 Storage 来实现负载均衡。
为了避免单个目录下的文件数太多,当 Storage 第一次启动时,会在每个数据存储目录中创建 2 级子目录,每级 256 个,总共 65536 个目录,上传的文件会以 hash 的方式被路由到其中某个目录下,然后将文件数据直接作为一个本地文件存储到该目录。
FastDFS 安装
首先要说明一下: tracker 和 storage 其实都是 fastdfs ,只不过启动时通过不同的配置文件启动,所扮演的角色不同而已。也就是说,安装 tracker 和 storage 就是在安装 fastdfs ,然后通过每个角色具体的配置文件启动即可。
下载资源
直接通过 Github:https://github.com/happyfish100 下载 libfastcommon , fastdfs ,fastdfs-nginx-module 三个项目对应的压缩包或者使用 git 命令下载,或者通过资源地址:https://sourceforge.net/projects/fastdfs/files/ 下载。
- libfastcommon :从 fastdfs 项目和 fastdht 项目中提取出来的公共 C 函数库。
- fastdfs :FastDFS 核心项目。
- fastdfs-nginx-module :Nginx 整合 FastDFS 时 Nginx 需要添加的模块资源。
安装依赖
FastDFS 是基于 C 语言开发的,安装它之前必须先安装它所依赖的环境。
yum install -y make cmake gcc gcc-c++
安装公共函数库
上传资源 libfastcommon-master.zip 至服务器 /usr/local/src 目录后并解压。
#安装 unzip 用于解压
yum install -y unzip
#解压 libfastcommon 至当前所在目录
unzip libfastcommon-master.zip
# 进入解压后的 libfastcommon-master 目录
cd libfastcommon-master
# 编译并安装
./make.sh && ./make.sh install
libfastcommon 默认安装在 /usr/lib64 和 /usr/include/fastcommon 两个目录中,并且会在 /usr/lib 目录中创建软链接。
安装 FastDFS
上传资源 fastdfs-master.zip 至服务器 /usr/local/src 目录后并解压。
#解压 fastdfs 至当前所在目录
unzip fastdfs-master.zip
# 进入解压后的 fastdfs-master 目录
cd fastdfs-master
# 编译并安装
./make.sh && ./make.sh install
fastdfs 默认安装在以下位置:
- /usr/bin :可执行文件
- /etc/fdfs :配置文件
- /etc/init.d :主程序代码
- /usr/include/fastdfs :插件组
启动 Tracker
tracker 和 storage 其实都是 fastdfs ,只不过启动时通过不同的配置文件启动,所扮演的角色不同而已。也就是说,安装 tracker 和 storage 就是在安装 fastdfs ,然后通过每个角色具体的配置文件启动即可。
查看 /etc/fdfs 目录下所有配置文件。
[root@localhost ~]# ls /etc/fdfs/
client.conf.sample storage.conf.sample storage_ids.conf.sample
tracker.conf.sample
client.conf.sample :客户端的配置文件,测试用
storage.conf.sample :存储器的配置文件
tracker.conf.sample :跟踪器的配置文件
编辑 tracker.conf 配置文件
#拷贝文件 tracker.conf.sample 并重命名为 tracker.conf
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
#编辑 tracker.conf 配置文件
vi /etc/fdfs/tracker.conf
配置文件中的配置项还是蛮多的,这里暂且关注以下几个即可,后期根据实际情况再对其他配置项
作出调整
#允许访问 tracker 服务器的 IP 地址,为空则表示不受限制
bind_addr =
#tracker 服务监听端口
port = 22122
#tracker 服务器的运行数据和日志的存储父路径(需要提前创建好)
base_path = /fastdfs/tracker
#tracker 服务器 HTTP 协议下暴露的端口
http.server_port = 8080
启动 tracker 服务
#创建 tracker 服务器的运行数据和日志的存储父路径
mkdir -p /fastdfs/tracker
#启动 tracker 服务
service fdfs_trackerd start
#查看 tracker 服务状态
service fdfs_trackerd status
#重启 tracker 服务
service fdfs_trackerd restart
#停止 tracker 服务
service fdfs_trackerd stop
启动 Storage
编辑 storage.conf 配置文件
#拷贝文件 storage.conf.sample 并重命名为 storage.conf
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
#编辑 storage.conf 配置文件
vi /etc/fdfs/storage.conf
也是先暂时关注几个
#storage 组名/卷名,默认为 group1
group_name = group1
#允许访问 storage 服务器的 IP 地址,为空则表示不受限制
bind_addr =
#storage 服务器的运行数据和日志的存储父路径(需要提前创建好)
base_path = /fastdfs/storage/base
#storage 服务器中客户端上传的文件的存储父路径(需要提前创建好)
store_path0 = /fastdfs/storage/store
#storage 服务器 HTTP 协议下暴露的端口
http.server_port = 8888
#tracker 服务器的 IP 和端口
tracker_server = 192.168.10.101:22122
启动 storage 服务
#创建 storage 服务器的运行数据和日志的存储父路径
mkdir -p /fastdfs/storage/base
#创建 storage 服务器中客户端上传的文件的存储父路径
mkdir -p /fastdfs/storage/store
#启动 storage 服务
service fdfs_storaged start
#查看 storage 服务状态
service fdfs_storaged status
#重启 storage 服务
service fdfs_storaged restart
#停止 storage 服务
service fdfs_storaged stop
查看 /fastdfs/storage/store 目录可以看到 Storage 服务器创建了 65536 个文件夹用于存储客户端上传的文件。
Client 操作
FastDFS 向使用者提供基本文件访问接口,比如 upload、download、append、delete 等,以客
户端库的方式提供给用户使用。
编辑 client.conf 配置文件
#拷贝文件 client.conf.sample 并重命名为 client.conf
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
#编辑 client.conf 配置文件
vi /etc/fdfs/client.conf
修改配置文件中以下两处内容即可
#client 客户端的运行数据和日志的存储父路径(需要提前创建好)
base_path = /fastdfs/client
#tracker 服务器的 IP 和端口
tracker_server = 192.168.10.101:22122
记得 mkdir -p /fastdfs/client 创建 Client 目录
上传文件
选择 Tracker Server
如上图所示,Storage Server 会定期向 Tracker Server 发送自己的所属 group 等存储相关信息。如果 Tracker Server 是集群环境,因为各个 Tracker 之间的关系是对等的,所以客户端上传时可以选择任意一个 Tracker
选择 group
当 Tracker 收到客户端上传文件的请求时,会为该文件分配一个可用的 group 用于存储,当选定了group 以后就要决定给客户端分配 group 中的哪个 Storage Server
如上图所示, tracker.conf 配置文件中 group 的可选规则有:
- round robin :所有的 group 间轮询
- specify group :指定一个具体的 group
- load balance :优先选择剩余存储空间多的 group
选择 Storage Server
当分配好 Storage Server 以后,客户端会向 Storage Server 发送上传文件请求,Storage Server会为文件分配一个具体的数据存储目录
storage.conf 配置文件中文件分发的可选规则有:
- round robin :在 group 中的所有 Storage 间轮询
- random :随机,按 hash code 分发
生成 file_id
选定存储目录以后,Storage 会为文件生一个 file_id,由 Storage Server IP、文件创建时间、文件
大小、文件 crc32 和一个随机数组成,然后将这个二进制串进行 base64 编码,转换为字符串
生成文件名
当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名,文件名由 group名称/存储目录/两级子目录/file_id.后缀名 拼接而成
FastDFS 文件上传返回信息解读
- group1 :组名/卷名。文件上传成功以后所在的 Storage 组名称,由 Storage 服务器返回
- M00 :虚拟磁盘路径。与 Storage 配置文件中磁盘选项 store_path* 对应。如果配置了store_path0 则是M00 ,如果配置了 store_path1 则是 M01 ,以此类推。比如:store_path0 =
/fastdfs/storage/store ,M00 则表示: /fastdfs/storage/store/data - /02/44 :数据两级目录。Storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据 文件
- wKgDrE34E8wAAAAAAAAGkEIYJK42378 :file_id,由 Storage Server IP、文件创建时间、文件大小、文件 crc32 和一个随机数组成,然后将这个二进制串进行 base64 编码,转换为字符串
上传方式一
上传命令格式为: fdfs_upload_file /etc/fdfs/client.conf 要上传的文件
[root@localhost ~]# fdfs_upload_file /etc/fdfs/client.conf
/usr/local/src/china.jpg
group1/M00/00/00/wKgKZl9skn6AHZKUAADhaCZ_RF0650.jpg
文件上传成功以后,会返回该文件在 Storage 服务器中的存储位置及随机生成的文件名。其中group1 表示 Storage 组名/卷名, M00 是一个虚拟目录,表示 /fastdfs/storage/store/data/ 真实路径中的 data 目录
查看 Storage 服务器发现该文件已成功上传
上传方式二
或者使用: fdfs_test /etc/fdfs/client.conf upload 要上传的文件 ,会返回该文件上传成功以后详细的相关信息
- group_name :Storage 组名/卷名
- remote_filename :上传成功文件的存储路径及文件名
- source_ip address :上传成功文件所在的 Storage 服务器的 IP 地址
- file timestamp :上传成功文件时的时间戳
- file size :上传成功文件的文件大小
- example file url :上传成功文件的 url 地址,配合 Nginx 可以直接访问
- storage_upload_slave_by_filename :FastDFS 的文件主/从特性,由主文件产生从文件
如下图所示,查看 Storage 服务器发现该文件已成功上传。后缀为 jpg-m 的文件存放了上传成功文件的元数据信息
下载文件
客户端 upload file 成功以后,会拿到一个 Storage 生成的文件名,接下来客户端根据这个文件名即可访问到该文件。跟 upload file 一样,在 download file 时客户端可以选择任意 Tracker Server。客户端发送 download 请求给某个 Tracker,必须带上文件名信息,Tracke 从文件名中解析出该文件的
group、大小、创建时间等信息,然后为该请求选择一个 Storage 用于提供读取服务
下载方式一
下载命令格式为: fdfs_download_file /etc/fdfs/client.conf group_name/remote_filename
fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/wKgKZl9smBAVBRKAADhaCZ_RF0518.jpg
下载方式二
使用: fdfs_test /etc/fdfs/client.conf download group_name remote_filename
fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/wKgKZl9smBAVBRKAADhaCZ_RF0518.jpg
删除文件
删除方式一
删除命令格式为: fdfs_delete_file /etc/fdfs/client.conf 要删除的文件
fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKgKZl9smBAVBRKAADhaCZ_RF0518.jpg
Tips:删除文件操作会将元数据文件一并删除
删除方式二
使用: fdfs_test /etc/fdfs/client.conf delete group_name remote_filename
fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/wKgKZl9smBAVBRKAADhaCZ_RF0518_big.jpg
使用nginx通过 HTTP 访问 FastDFS 中保存的图片信息
Nginx 整合 FastDFS 时 Nginx 需要添加 fastdfs-nginx-module 模块
直接通过 Github:https://github.com/happyfish100/fastdfs-nginx-modul 下载压缩包或者使用 git 命令下载
或者通过资源地址:**https://sourceforge.net/projects/fastdfs/files/** 下载。
下载以后,上传资源 fastdfs-nginx-module-master.zip 至服务器 /usr/local/src 目录后并解压。
unzip fastdfs-nginx-module-master.zip
<