FastDFS
- 1、分布式文件系统
- 2、FastDFS环境搭建
- 3、分布式文件系统FastDFS的HTTP访问
- 4、FastDFS分布式文件系统Java客户端
- 5、FastDFS在web项目中的应用
- 6、FastDFS分布式文件系统集群
1、分布式文件系统
1.1 FastDFS简介
-
分布式文件系统 (Distributed File System) 是一个软件/软件服务器,这个软件可以用来管理文件。但这个软件所管理的文件通常不是在一个服务器节点上,而是在多个服务器节点上,这些服务器节点通过网络相连构成一个庞大的文件存储服务器集群,这些服务器都用于存储文件资源,通过分布式文件系统来管理这些服务器上的文件。
-
FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。
-
FastDFS是一个开源的轻量级分布式文件系统,为互联网应用量身定做,简单、灵活、高效,采用C语言开发,由阿里巴巴开发并开源。
-
FastDFS对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载、文件删除)等,解决了大容量文件存储的问题,特别适合以文件为载体的在线服务,如相册网站、文档网站、图片网站、视频网站等等。
-
FastDFS充分考虑了冗余备份、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。
-
FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。
Tracker Server
:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。Storage Server
:存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。Client
:客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。
- 常见的分布式文件系统有:FastDFS、GFS、HDFS、Lustre 、Ceph 、GridFS 、mogileFS、TFS等。
1.2 FastDFS整体架构
FastDFS代码托管在github上:https://github.com/happyfish100/fastdfs
-
FastDFS文件系统由两大部分构成,一个是客户端,一个是服务端
客户端通常指我们的程序,比如我们的Java程序去连接FastDFS、操作FastDFS,那我们的Java程序就是一个客户端,FastDFS提供专有API访问,目前提供了C、Java和PHP几种编程语言的API,用来访问FastDFS文件系统。
-
服务端由两个部分构成:一个是跟踪器(tracker),一个是存储节点(storage)
- 跟踪器(tracker)主要做调度工作,在内存中记录集群中存储节点storage的状态信息,是前端Client和后端存储节点storage的枢纽。因为相关信息全部在内存中,Tracker server的性能非常高,一个较大的集群(比如上百个group)中有3台就足够了。
- 存储节点(storage)用于存储文件,包括文件和文件属性(meta data)都保存到存储服务器磁盘上,完成文件管理的所有功能:文件存储、文件同步和提供文件访问等。
1.3 FastDFS的存储策略
-
为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。
-
在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。
1.4 FastDFS的上传过程
-
FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。
-
Storage Server会定期的向Tracker Server发送自己的存储信息。当Tracker Server Cluster中的Tracker Server不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。
-
当Tracker收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storage server。当分配好storage server后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个fileid,最后根据以上的信息生成文件名存储文件。
1.5 FastDFS的文件同步
-
写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。
-
每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。
-
storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。
1.6 FastDFS的文件下载
- 客户端uploadfile成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。
- 跟upload file一样,在downloadfile时客户端可以选择任意tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。
2、FastDFS环境搭建
2.1 FastDFS安装
2.1.1 安装前的准备
(1) 检查Linux上是否安装了 gcc、libevent、libevent-devel
yum list installed | grep gcc
yum list installed | grep libevent
yum list installed | grep libevent-devel
(2) 如果没有安装,则需进行安装
yum install gcc libevent libevent-devel –y
2.1.2 安装 libfastcommon 库
- libfastcommon 库是 FastDFS 文件系统运行需要的公共 C 语言函数库
注意
:目前最新版本的v1.0.39和最新版的FastDFS5.11不兼容,所有我们这里使用的版本是v1.0.36 下载地址:https://github.com/happyfish100
(1) 将下载好的libfastcommon文件上传到Linux(/home/)
(2) 解压下载下来的tar.gz压缩包到当前目录
tar -zxvf libfastcommon-1.0.36.tar.gz
(3) 切换到解压后的libfastcommon目录
cd libfastcommon-1.0.36
(4) 执行make脚本进行编译
./make.sh
注意
: make编译的时候如果报错,需解决错误后再次进行make,通常发生错误是由于Linux缺少某些依赖库导致,根据错误提示解决错误
(5) 执行make install进行安装
./make.sh install
2.1.3 安装FastDFS
-
FastDFS没有Windows版本,不能在Windows下使用。
-
FastDFS需要安装部署在Linux环境下,我们这里使用的是fastdfs-5.11版本(201901)
-
下载地址:https://github.com/happyfish100/fastdfs/archive/V5.11.tar.gz
(1) 将下载好的FastDFS文件上传到Linux(/home/)
(2) 解压下载下来的tar.gz压缩包到当前目录
tar -zxvf fastdfs-5.11.tar.gz
(3) 切换到解压后FastDFS的目录
cd fastdfs-5.11
(4) 执行make脚本进行编译
./make.sh
(5) 执行make install进行安装
./make.sh install
-
所有编译出来的文件存放在/usr/bin目录下
-
所有配置文件存放在/etc/fdfs目录下
(6) 查看安装后的效果
A、 查看FastDFS相关的可执行程序
ll /usr/bin/fdfs*
- /usr/bin是Linux的环境变量,可通过echo $PATH查看
B、 查看FastDFS的配置文件
ll /etc/fdfs/
(7) 另外注意需要把解压后的fastdfs-5.11/conf目录下的两个文件拷贝到/etc/fdfs/ ,否则后续会有很多奇怪问题不好解决
cp http.conf /etc/fdfs/
cp mime.types /etc/fdfs/
2.2 FastDFS配置文件详解
1. 去掉/etc/fdfs/目录下FastDFS配置文件的后缀名
2. 修改tracker.conf文件
- 默认指向的FastDFS作者余庆的目录,因为在我们的机器上不存在,所有手动改一下
base_path=/opt/fastdfs/tracker #配置tracker存储数据的目录
3. 修改storage.conf文件
base_path=/opt/fastdfs/storage #storage存储数据目录
store_path0=/opt/fastdfs/storage/files #真正存放文件的目录
tracker_server=192.168.235.128:22122 #注册当前存储节点的跟踪器地址
4. 在Linux服务器上创建上面指定的目录
/opt/fastdfs/tracker
/opt/fastdfs/storage
/opt/fastdfs/storage/files
5. 然后启动FastDFS
2.3 FastDFS启动
FastDFS服务启动需要启动两个脚本:
1. 启动FastDFS的tracker服务
在任意目录下执行:fdfs_trackerd /etc/fdfs/tracker.conf
2. 启动FastDFS的storage服务
在任意目录下执行:fdfs_storaged /etc/fdfs/storage.conf
3. 查看启动进程
有启动的执行命令即为启动成功
4. 查看storage是否已经注册到了tracker下
fdfs_monitor /etc/fdfs/storage.conf
5. 首次启动storage后,会在配置的路径下创建存储文件的目录
2.4 FastDFS重启与FastDFS关闭
2.4.1 FastDFS重启
- 重启tracker
fdfs_trackerd /etc/fdfs/tracker.conf restart
- 重启storage
fdfs_storaged /etc/fdfs/storage.conf restart
2.4.2 FastDFS关闭
- 关闭tracker执行命令
在任意目录下执行:fdfs_trackerd /etc/fdfs/tracker.conf stop
- 关闭storage执行命令
在任意目录下执行:fdfs_storaged /etc/fdfs/storage.conf stop
或者kill关闭fastdfs,但不建议在线上使用kill -9
强制关闭,因为可能会导致文件信息不同步
问题。
2.5 FastDFS测试
FastDFS安装完成之后,可以使用fdfs_test
脚本测试文件上传。
测试之前,需要修改client.conf配置文件,修改两个配置
base_path=/opt/fastdfs/client
tracker_server=192.168.179.128:22122
在/opt/fastdfs/
目录下创建client
2.5.1 测试文件上传
- 准备需要上传的文件
- 执行上传命令fdfs_test /etc/fdfs/client.conf upload /root/aa.txt
- 切换到存储目录查看文件上传情况
FastDFS生成的文件目录结构及名称示例
2.5.2 测试文件删除
fdfs_delete_file /etc/fdfs/client.conf group1/要删除的文件路径
注意
● 没有搭建集群默认只有一个组group1
● 后缀名包含-m的为属性文件(meta)
● 在Linux中并没有磁盘一说,是虚拟的
3、分布式文件系统FastDFS的HTTP访问
概述
-
在文件上传的时候,上传成功的信息中有提示我们可以通过某个路径去访问上传的文件,但是我们直接访问这个路径,却不可以,那么已经上传到FastDFS文件系统中的文件,我们如何在浏览器中访问呢?
-
FastDFS提供了一个Nginx扩展模块,利用该模块,我们可以通过Nginx访问已经上传到FastDFS上的文件
3.1 前期准备工作
-
将Fastdfs的Nginx扩展模块源代码上传到Linux上
-
解压下载下来的fastdfs-nginx-module-master.zip 文件
unzip fastdfs-nginx-module-master.zip
3.2 安装Nginx并且添加fastDFS模块
因为这个模块必须在Nginx的安装的过程中才能添加,所有我们需要重新安装一个nginx,为了和原来已安装的Nginx进行区分,我们把新安装的Nginx取名为nginx_fdfs
1. 将Nginx的tar包上传到Linux上
2. 解压上传的Nginx文件
3. 切换至解压后的Nginx主目录,执行配置操作
cd nginx-1.14.2
./configure --prefix=/usr/local/nginx_fdfs --add-
module=/home/soft/fastdfs-nginx-module-master/src
• prefix是指定nginx安装路径
• add-module指定fastDFS的nginx模块的源代码路径
# 常见报错问题
①/home/dfs/fastdfs-nginx-module-master/src/common.c:351:32: error: request for member ‘path’ in something not a structure or union
g_fdfs_store_paths.paths[i].path);
解决方案:
原因:软件不匹配!
# wget https://sourceforge.net/projects/fastdfs/files/FastDFS%20Nginx%20Module%20Source%20Code/fastdfs-nginx-module_v1.16.tar.gz
# tar -zxvf fastdfs-nginx-module_v1.16.tar.gz
②/home/dfs/fastdfs-nginx-module/src/common.c:21:25: fatal error: fdfs_define.h: No such file or directory
#include "fdfs_define.h"
解决方案:
原因:编译安装nginx的fastdfs插件的头文件没有找到,由于编译nginx时候系统会到/usr/local /include
编译安装fastdfs-nginx-module时则默认保存在了/usr/include目录。
修复:ln -s /usr/include/fast* /usr/local/include/
③ fatal error: common_define.h: No such file or directory
解决方案:
原因:在安装FastDFS的时候,其中的函数声明、宏定义、函数原型被指到了 “ /usr/include/fastdfs /usr/include/fastcommon ” 目录下
vi /home/dfs/fastdfs-nginx-module/src/config
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
》》》
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
4. 执行命令进行编译
make
5. 执行命令进行安装
make install
6. 以上安装Nginx的FastDFS扩展模块注意事项
我们知道,Nginx的安装需要Linux安装相关的几个库,否则编译会出现错误,这几个库分别是:
• gcc编译器是否安装
检查是否安装:yum list installed | grep gcc
执行安装:yum install gcc -y
• openssl库是否安装
检查是否安装:yum list installed | grep openssl
执行安装:yum install openssl openssl-devel -y
• pcre库是否安装
检查是否安装:yum list installed | grep pcre
执行安装:yum install pcre pcre-devel -y
• zlib库是否安装
检查是否安装:yum list installed | grep zlib
执行安装:yum install zlib zlib-devel -y
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
7. FastDFS扩展模块执行流程
3.3 FastDFS的Nginx访问配置
将/home/soft/fastdfs-nginx-module-master/src(自己实际存放Nginx扩展模块的目录)目录下的mod_fastdfs.conf文件拷贝到 /etc/fdfs/目录下,这样才能正常启动Nginx
cp /home/soft/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs/
1. 修改mod_fastdfs.conf配置文件
base_path=/opt/fastdfs/nginx_mod
tracker_server=192.168.235.128:22122
url_have_group_name = true
store_path0=/opt/fastdfs/storage/files
2. 在/opt/fastdfs/目录下创建nginx_mod目录
3. 配置Nginx的配置文件
#拦截请求路径中包含 /group[1-9]/M0[0-9] 的请求,用 fastdfs的Nginx 模块进行转发
location ~ /group[1-9]/M0[0-9] {
ngx_fastdfs_module;
}
ngx_fastdfs_module; #这个指令不是Nginx本身提供的,是扩展模块提供的,根据这个指令找到FastDFS提供的Nginx模块配置文件,然后找到Tracker,最终找到Stroager。
3.4 FastDFS的Nginx访问启动与测试
1. 启动带有Fastdfs模块的Nginx
2. 重启或启动FastDFS服务进程
fdfs_trackerd /etc/fdfs/tracker.conf restart
fdfs_storaged /etc/fdfs/storage.conf restart
3. 上传一个文件进行测试验证
fdfs_test /etc/fdfs/client.conf upload /root/aa.txt
4. 在浏览器访问上传的文件
当遇到400错误,检查配置/etc/fdfs/mod_fastdfs.conf
url_have_group_name=true
该配置表示访问路径中是否需要带有group1,改为true表示路径中需要有group1
5. 扩展
模拟大型网站用户头像的处理方式,上传一张图片,然后自己写一个html页面,src指向上传的图片。
4、FastDFS分布式文件系统Java客户端
在实际项目开发中,FastDFS提供的主要功能
● upload:上传文件
● download:下载文件
● delete:删除文件
4.1 FastDFS文件系统的Java客户端
FastDFS文件系统Java客户端是指采用Java语言编写的一套程序,专门用来访问fastDFS文件系统,其实就是一个jar包。
注意:大家如果能连上 mvnrepository上搜索到的用友云提供的fastdfs-client,那大家就下载那个jar包使用,如果连不上,这个jar包需要我们自己来打。
1. 下载官方的源代码
从https://codeload.github.com/happyfish100/fastdfs-client-java/zip/master上下载FastDFS源代码到本地
2. 解压
3. 采用maven命令编译成jar安装到本地maven库
mvn clean install
4. 在Java程序中使用它提供的API来访问FastDFS文件系统
4.2 FastDFS文件上传功能实现
4.2.1 需求
使用Java客户端,编程操作fastDFS分布式文件系统,上传本地文件到FastDFS服务器上。
4.2.2 实现步骤
- 使用IDEA创建普通的maven项目,不需要使用
- 在pom.xml文件中添加我们打包好的FastDFS本地仓库的jar包(FastDFS的java客户端依赖)
<!--加入FastDFS的java客户端依赖-->
<dependencies>
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.27-SNAPSHOT</version>
</dependency>
</dependencies>
- 拷贝源代码包中的fdfs_client.conf文件到resources目录下,在里面主要配置tracker地址
tracker_server = 192.168.235.128:22122
- 编写代码,进行上传测试
在com.bjpowernode.fastdfs包下创建FastDFS类,在其中编写上传代码
package com.bjpowernode.fastdfs;
import org.csource.common.MyException;
import org.csource.fastdfs.*;
import java.io.IOException;
public class FastDFS {
public static void main(String[] args) {
fileUpload();
}
//上传文件的方法
public static void fileUpload(){
TrackerServer trackerServer = null;
StorageServer storageServer = null;
try {
//1.加载配置文件,默认去classpath下加载
ClientGlobal.init("fdfs_client.conf");
//2.创建TrackerClient对象
TrackerClient trackerClient = new TrackerClient();
//3.创建TrackerServer对象
trackerServer = trackerClient.getConnection();
//4.创建StorageServler对象
storageServer = trackerClient.getStoreStorage(trackerServer);
//5.创建StorageClient对象,这个对象完成对文件的操作
StorageClient storageClient = new StorageClient(trackerServer,storageServer);
//6.上传文件 第一个参数:本地文件路径 第二个参数:上传文件的后缀 第三个参数:文件信息
String [] uploadArray = storageClient.upload_file("D:/aa.txt","txt",null);
for (String str:uploadArray) {
System.out.println(str);
}
} catch (IOException e) {
e.printStackTrace();
} catch (MyException e) {
e.printStackTrace();
} finally {
if(storageServer != null){
try {
storageServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(trackerServer != null){
try {
trackerServer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
- 运行程序,在Linux上,FastDFS存储目录下查看上传文件内容
4.3 FastDFS文件上传功能封装
4.3.1 需求
因为使用FastDFS进行文件操作代码大多都是通用的,所以我们这里在FastDFS类中将通用的功能进行封装,并提供上传、下载、删除文件的方法。
注意:这里只是简单的封装,如果多线程会有问题
4.3.2 实现步骤
- 抽取获取StorageClient的方法
public static StorageClient getStorageClient() throws IOException, MyException {
//1.加载配置文件,默认去classpath下加载
ClientGlobal.init("fdfs_client.conf");
//2.创建TrackerClient对象
TrackerClient trackerClient = new TrackerClient();
//3.创建TrackerServer对象
trackerServer = trackerClient.getConnection();
//4.创建StorageServler对象
storageServer = trackerClient.getStoreStorage(trackerServer);
//5.创建StorageClient对象,这个对象完成对文件的操作
StorageClient storageClient = new StorageClient(trackerServer,storageServer);
return storageClient;
}
- 定义两个全局变量
private static TrackerServer trackerServer = null;
private static StorageServer</