分布式文件系统FastDFS技术如何进行有效整理?
- 内容介绍
- 文章标签
- 相关推荐
本文共计4552个文字,预计阅读时间需要19分钟。
FastDFS简介
1.FastDFS 1.1
1.1 理解基础概念1.1.1 什么是分布式文件系统?
全称:Distributed File System,简称DFS分布式文件系统,即DFS,是一种可以跨多台服务器存储和访问文件的系统。它可以看作是一个软件,也可以是一个服务。和Tomcat类似,它既可以是软件也可以是服务器。简而言之,DFS就是相对于单机文件系统而言,可以分布式存储文件的系统。
1、FastDFS 1.1、了解基础概念 1.1.1、什么是分布式文件系统?- 全称:Distributed File System,即简称的DFS
- 这个东西可以是一个软件,也可以说是服务器,和tomcat差不多,即相当于软件也相当于是服务器,这个软件就是用来管理文件的
- 这个软件所管理的文件通常不是在一个服务器节点上,而是在多个服务器节点上
- 服务器节点通过网络相连构成一个庞大的文件存储服务器集群,这些服务器都用于存储文件资源,通过分布式文件系统来管理这些服务器上的文件
1.1.2、传统文件系统 和 分布式文件系统对比
传统文件系统
- 缺点
- 所有的文件都存放在一台计算机中,如果这台计算机挂彩了,那么就会导致整个服务不可用( 文件不能上传和下载了 )
- 如果这台计算机磁盘损坏了,那么会丢失所有的文件
- 这台计算机的磁盘空间非常有限,很容易到达磁盘的上限,导致无法上传文件
-
回顾玩servlet时的文件上传和下载
文件上传
- 假如前端轰HTML写法是如下的样子:
<div id="image"> <label for="">标题图片:</label> <input type="file" id="file" name="file" > <img src="" alt="" width="100px" height="150px"> </div>- JS写法如下:
// 当图片发生改变时 —— 也就是用户点击file框,上传文件时 $("#file").on( 'change' , function () { // 创建一个FormData空对象,就相当于是伪造了一个form表单 let formData = new FormData(); // 这个FromData对象就用来装文件内容 // 文件的files属性本质是个数组 let files = $("#file").prop("files"); formData.append("upFile" , files[0] ); $.ajax( { url: '/ajax/upload.do', type: 'post', data: formData, dataType: 'json', cache: false, // 上传文件不需要缓存 contentType: false, // 不需要对内容类型进行处理 因为内容是一个FormData对象 processData: false, // 不需要对数据进行处理,因为上面的data是一个FormData对象 // 后台返回的格式 : // { "errno":"0" , "data":[ {"alt":"1633528500498.jpg" , "url":"/upload/2021-10-06/1633528500498.jpg"} ] } success: function (info) { info.data.forEach( function (data) { // $("#image img").remove(); // $("#image").append( ' <img src=" '+data.url+' " alt="" width="100px" height="150px"> ' ) /* 注掉的这种是:html中没有img标签时使用 因为:使用下面这种方法的情景是 —— 页面本来就有一个img框( 即:初始页面上这个file本身有一张图片 ),所以下面这种可以做到图片改变时把图片的路径换掉,也就是图片渲染( 也是数据回填 的思想 ) 但是:如果页面一开始file的位置是不应该有图片的,是后面用户选了之后才出现图片预览效果,那么:就使用注释掉的这种方法:追加 */ $("#image img").attr("src" , data.url ); }); } } ); })- 那么后端的low代码如下:
import com.alibaba.fastjson.JSON; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.github.com/happyfish100/fastdfs - FastDFS是一个开源的轻量级分布式文件系统,为互联网应用量身定做,简单、灵活、高效,采用C语言开发,由阿里巴巴开发并开源
- FastDFS对文件进行管理,功能包括:文件存储、文件同步( 指的是:文件系统 和 数据备份之间的同步 )、文件上传、文件下载、文件删除等
- FastDFS解决了大容量文件存储的问题
- FastDFS特别适合以文件为载体的在线服务,如相册网站、文档网站、图片网站、视频网站等
- FastDFS充分考虑了冗余备份、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务
- 冗余备份:指的是文件系统中存的文件 和 数据备份中存的文件完全一致的问题
- 线性扩容:文件系统 和 数据备份不断增加呗( 就是上图中再加几份嘛 ),和水平扩容类似
- 冗余备份:指的是文件系统中存的文件 和 数据备份中存的文件完全一致的问题
1.2.2、FastDFS的组成结构
- 由两大部分构成,一个是客户端,一个是服务端
- 客户端:指我们的程序,比如我们的Java程序去连接FastDFS、操作FastDFS,那我们的Java程序就是一个客户端。FastDFS提供专有API访问,目前提供了C、Java和PHP几种编程语言的API,用来访问FastDFS文件系统
- 服务端由两个部分构成:一个是跟踪器(tracker),一个是存储节点(storage)
- 跟踪器 tracker:这个玩意儿类似于Erueka / zookeeper注册中心,起到一个调度的作用。它是在内存中记录集群中存储节点storage的状态信息,是前端Client和后端存储节点storage的枢纽,因为相关信息全部在内存中,Tracker server的性能非常高,一个较大的集群(比如上百个group,group指的就是:文件系统 和 数据备份的组合,这二者就是一个group)中有3台就足够了
- 存储节点 storage:用于存储文件,包括文件和文件属性(meta data,如:文件名、文件大小、文件后缀...)都保存到存储服务器磁盘上。以及完成文件管理的所有功能:文件存储、文件同步和提供文件访问( 上传、下载、删除 )等
2、开始玩FastDFS 2.1、安装FastDFS
-
注:我的系统是centos 7
-
安装需要的依赖环境 gcc、libevent、libevent-devel
yum install gcc libevent libevent-devel -y
- 安装公共函数库libfastcommon 和 fastDFS压缩包
- 自行去前面官网中进行下载,当然:官网的wiki中有在线拉取命令
- 解压公共函数库libfastcommon
tar -zxvf libfastcommon-1.0.36.tar.gz
- 进入libfastcommon,执行里面的make.sh,编译公共函数
./make.sh
# 当然:可以把命令进行合并 执行如下命令 就是编译并安装
./make.sh && ./make.sh install
- 安装公共函数
./make.sh install
- 解压
fastdfs-5.11.tar.gz压缩包
tar -zxvf fastdfs-5.11.tar.gz
- 进入解压之后的文件,使用
make sh进行编译
./make.sh
# 一样的可以用组合命令 即:编译并安装
./make.sh && ./make.sh install
- 安装
./make.sh install
- 检查是否安装成功,进入如下的目录即可
cd /usr/bin
- 往后找,出现这些fdfs开头的文件就表示成功( 这些文件就是fastDFS的相关命令 )
- fastDFS配置文件所在地,进入如下目录即可
- 想要让fastDFS的配置文件生效,那么就需要放到下面的这个目录中
cd /etc/fdfs
- 拷贝两个配置文件到
etc/fdfs中,这两个配置文件在解压的fastDFS的conf中,一个叫www.csource.org/ for more detail. # 这是配置的client.conf中的信息 [2022-06-01 10:17:07] DEBUG - base_path=/opt/fastdfs/client, connect_timeout=30, network_timeout=60, tracker_server_count=1, 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: 0 tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=162.14.66.60, port=23000 group_name=group1, ip_addr=162.14.66.60, port=23000 storage_upload_by_filename # 重要的信息在这里group_name、remote_filename # group_name就是组名,在前面配置中见过它,就是说的文件系统 和 数据备份这二者的组合名 # remote_filename 远程文件名 这是关键中的关键,告知你:文件保存到那里去了 group_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt source ip address: 10.0.0.16 file timestamp=2022-06-01 10:17:07 file size=641 file crc32=1141168436 # 下面这个URL地址很重要,就是去浏览器访问上传的这个文件资源的地址,但是:目前还不可以访问,因为没有配置Nginx example file url: 162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt storage_upload_slave_by_filename group_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt source ip address: 10.0.0.16 file timestamp=2022-06-01 10:17:07 file size=641 file crc32=1141168436 example file url: 162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt- 单独说明:
remote_filename
remote_filename=M00/00/00/ M00 指的是:/opt/fastdfs/storage/files/data 就是前面去看默认创建文件数( 256 * 256 )的位置,跟前面的配置有关啊 00/00/ 指的就是:/opt/fastdfs/storage/files/data目录下的00子目录,这里面的00目录 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt 指的是:保存的文件名 fastdfs会重新生成文件名,以防的就是同名文件,造成附件覆盖的问题- 上图中几个文件解读
# _big 就是数据备份文件 # _m 就是meta data文件,即:文件属性文件( 文件名、文件后缀、文件大小..... ) -rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt -rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m # 这两个就是文件系统中的文件 -rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt -rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt 和 文件系统中的CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt存的内容是一样的 # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m 和 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m这两个备份文件也是相应的
2.2.4.2、测试文件下载和删除- 前面已经见过对应的语法了
fdfs_test <config_file> <operation> operation: upload, download, getmeta, setmeta, delete and query_servers # <> 表示必填- 变一下就可以了
# 变成下载的命令,然后使用此命令查看完整命令即可 fdfs_test /etc/fdfs/client.conf download # 根据执行上面的命令,得到文件下载的语法 fdfs_test <config_file> download <group_name> <remote_filename> # 那么想要下载刚刚上传的文件,执行如下的命令即可 fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt # 其中:group 和 remote_filename都在前面上传时见过了 # 注:这个下载是下载到当前所在目录的位置 # 同理:就可以得到文件删除的命令了 fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt- 以上这些
fdfs_test只会在测试时使用,其他地方基本上都不用的
2.3、安装Nginx-
上传
fastdfs-niginx扩展模块 并 解压 - 使用官网中wiki说明的命令拉取也行 -
安装nginx,要是有的话就跳过
- 记住两个目录
# nginx安装目录 /usr/local/nginx_fdfs # fastdfs-nginx模块的src目录 /usr/local/fastdfs-nginx-module-master/src- 进入nginx安装目录,进行模块添加配置
# 进入nginx安装目录 cd nginx_fdfs # 执行模块配置 # prefix 就是前面让记住的nginx安装目录 add-module就是fastdfs-nginx模块的src目录 ./configure --prefix=/usr/local/nginx_fdfs --add-module=/usr/local/fastdfs-nginx-module-master/src- 编译并安装
# 在安装的nginx目录下载执行下述命令 make & make install- 注释事项:Nginx的安装需要Linux安装相关的几个库,否则编译会出现错误,有这几个的话就不安装了
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
2.3.1、修改需要的配置文件- 将fastdfs-nginx扩展模块中的
mod_fastdfs.conf文件复制到/etc/fdfs中
cp /usr/local/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs- 修改
/etc/fdfs/mod_fastdfs.conf
vim mod_fastdfs.conf # 修改内容如下: # 这个目录要保证存在,不存在就要配置好了创建它 mkdir -p /opt/fastdfs/nginx_mod base_path=/opt/fastdfs/nginx_mod tracker_server=自己服务器ip:22122 # 访问地址是否带上组名 url_have_group_name = true store_path0=/opt/fastdfs/storage/files- 上面
base_path目录要是不存在记得创建
- 进入
nginx_fdfs的安装目录中,去nginx.conf中配置fastdfs-nginx的扩展模块
# 编辑nginx.conf文件 vim /usr/local/nginx_fdfs/conf/nginx.conf # 配置内容 location ~ /group[1-9]/M0[0-9] { ngx_fastdfs_module; } # 解读:ngx_fastdfs_module # 这个指令不是Nginx本身提供的,是扩展模块提供的,根据这个指令找到FastDFS提供的Nginx模块配置文件,然后找到Tracker,最终找到Stroager- 启动
nginx
/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf -t /usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf # 保险起见,查看nginx是否启动成功 ps -ef | grep nginx- 注意:这里很容易出现启动不起来,如果下面这个进程没有启动起来
nobody 3895 3894 0 15:45 ? 00:00:00 nginx: worker process- 那么:就去查看日志文件
cd /usr/local/nginx_fdfs/logs # 还有一份日志中也可能出现错误信息 cd /opt/fastdfs/nginx_mod
2.4、Java操作FastDFS 2.3.2、扩展模块执行流程- 下面这个流程很重要,涉及到另外更深入的知识( 如:集群部署FastDFS,本篇博客没有说明集群部署,哪些就是固定命令和流程,百度复制粘贴修改即可 )
2.4.1、文件上传- 在
resources目录下创建fastdfs.conf文件,并编写如下内容:
tracker_server=服务器ip:22122- 编写文件上传代码
package com.zixieqing; import org.csource.common.MyException; import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : UploadFile * @description : 该类功能 FastDFS文件上传 * @packageName : com.zixieqing */ public class UploadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、创建tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、创建storage客户端 - 这个对象就是用来上传文件、下载文件、删除文件的 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、上传文件 /* 这里有两个API需要了解 String[] upload_file(byte[] file_buff, int offset, int length, String file_ext_name, NameValuePair[] meta_list) 这个API常用来web中上传文件的 参数1 file_buff、文件字节 offset、length、从文件的那个位置开始上传,截止位置 参数4 file_ext_name、文件后缀 参数5 meta_list、文件的属性文件 String[] upload_file(String local_filename, String file_ext_name, NameValuePair[] meta_list) 这个API是上传本地文件的 参数1 local_filename、本地文件的绝对路径 参数2 file_ext_name、文件后缀名 参数3 meta_list、文件的属性文件,linux1中的哪个meta data,一般都不传 上述这两个API,注意返回值,这个String[] 很重要,就是涉及到linux中的那个组名group 和 远程文件名remote_filename,这个group和remote_fileName一般是存在数据库中的 */ String[] result = storageClient.upload_file("C:\\Users\\ZiXieQing\\Desktop\\图库\\19.jpg", "jpg", null); // 7、验证一下 for (String data : result) { System.out.println("data = " + data); } } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } }- 浏览器访问
2.4.2、文件下载- 把前面的文件上传代码改一下即可,换成另一个API而已
package com.zixieqing; import org.csource.common.MyException; import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DownloadFile * @description : 该类功能 fastDFS文件下载 * @packageName : com.zixieqing */ public class DownloadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、获取tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、创建storage客户端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、下载文件 /* 这里需要知道两个API byte[] download_file(String group_name, String remote_filename) 这个API常用于web操作 int download_file(String group_name, String remote_filename, String local_filename) 这个API是把文件下载到本地磁盘中 这个API的返回值结果很重要 */ String group = "group1"; String remoteFileName = "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"; // 存入本地磁盘路径+存入磁盘的文件名 String localFileName = "d:/靓妹.jpg"; // 只有返回值是0才表示下载成功,否则只要是其他数字都是下载失败( 其他数字有可能是组名错了,远程文件名错了........ int result = storageClient.download_file(group, remoteFileName, localFileName); // 7、验证 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } }
2.4.3、文件删除package com.zixieqing; import org.csource.common.MyException; import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DeleteFile * @description : 该类功能 FastDFS删除文件 * @packageName : com.zixieqing */ public class DeleteFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、获取tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、获取storage客户端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、执行文件删除 /* int delete_file(String group_name, String remote_filename) 参数1 group_name、组名 参数2 remote_filename、远程文件名 */ // 一样的,返回值是0就表示成功,其他都是删除失败 int result = storageClient.delete_file("group", "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"); // 7、验证一下 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); }finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } } - 单独说明:
本文共计4552个文字,预计阅读时间需要19分钟。
FastDFS简介
1.FastDFS 1.1
1.1 理解基础概念1.1.1 什么是分布式文件系统?
全称:Distributed File System,简称DFS分布式文件系统,即DFS,是一种可以跨多台服务器存储和访问文件的系统。它可以看作是一个软件,也可以是一个服务。和Tomcat类似,它既可以是软件也可以是服务器。简而言之,DFS就是相对于单机文件系统而言,可以分布式存储文件的系统。
1、FastDFS 1.1、了解基础概念 1.1.1、什么是分布式文件系统?- 全称:Distributed File System,即简称的DFS
- 这个东西可以是一个软件,也可以说是服务器,和tomcat差不多,即相当于软件也相当于是服务器,这个软件就是用来管理文件的
- 这个软件所管理的文件通常不是在一个服务器节点上,而是在多个服务器节点上
- 服务器节点通过网络相连构成一个庞大的文件存储服务器集群,这些服务器都用于存储文件资源,通过分布式文件系统来管理这些服务器上的文件
1.1.2、传统文件系统 和 分布式文件系统对比
传统文件系统
- 缺点
- 所有的文件都存放在一台计算机中,如果这台计算机挂彩了,那么就会导致整个服务不可用( 文件不能上传和下载了 )
- 如果这台计算机磁盘损坏了,那么会丢失所有的文件
- 这台计算机的磁盘空间非常有限,很容易到达磁盘的上限,导致无法上传文件
-
回顾玩servlet时的文件上传和下载
文件上传
- 假如前端轰HTML写法是如下的样子:
<div id="image"> <label for="">标题图片:</label> <input type="file" id="file" name="file" > <img src="" alt="" width="100px" height="150px"> </div>- JS写法如下:
// 当图片发生改变时 —— 也就是用户点击file框,上传文件时 $("#file").on( 'change' , function () { // 创建一个FormData空对象,就相当于是伪造了一个form表单 let formData = new FormData(); // 这个FromData对象就用来装文件内容 // 文件的files属性本质是个数组 let files = $("#file").prop("files"); formData.append("upFile" , files[0] ); $.ajax( { url: '/ajax/upload.do', type: 'post', data: formData, dataType: 'json', cache: false, // 上传文件不需要缓存 contentType: false, // 不需要对内容类型进行处理 因为内容是一个FormData对象 processData: false, // 不需要对数据进行处理,因为上面的data是一个FormData对象 // 后台返回的格式 : // { "errno":"0" , "data":[ {"alt":"1633528500498.jpg" , "url":"/upload/2021-10-06/1633528500498.jpg"} ] } success: function (info) { info.data.forEach( function (data) { // $("#image img").remove(); // $("#image").append( ' <img src=" '+data.url+' " alt="" width="100px" height="150px"> ' ) /* 注掉的这种是:html中没有img标签时使用 因为:使用下面这种方法的情景是 —— 页面本来就有一个img框( 即:初始页面上这个file本身有一张图片 ),所以下面这种可以做到图片改变时把图片的路径换掉,也就是图片渲染( 也是数据回填 的思想 ) 但是:如果页面一开始file的位置是不应该有图片的,是后面用户选了之后才出现图片预览效果,那么:就使用注释掉的这种方法:追加 */ $("#image img").attr("src" , data.url ); }); } } ); })- 那么后端的low代码如下:
import com.alibaba.fastjson.JSON; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.github.com/happyfish100/fastdfs - FastDFS是一个开源的轻量级分布式文件系统,为互联网应用量身定做,简单、灵活、高效,采用C语言开发,由阿里巴巴开发并开源
- FastDFS对文件进行管理,功能包括:文件存储、文件同步( 指的是:文件系统 和 数据备份之间的同步 )、文件上传、文件下载、文件删除等
- FastDFS解决了大容量文件存储的问题
- FastDFS特别适合以文件为载体的在线服务,如相册网站、文档网站、图片网站、视频网站等
- FastDFS充分考虑了冗余备份、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务
- 冗余备份:指的是文件系统中存的文件 和 数据备份中存的文件完全一致的问题
- 线性扩容:文件系统 和 数据备份不断增加呗( 就是上图中再加几份嘛 ),和水平扩容类似
- 冗余备份:指的是文件系统中存的文件 和 数据备份中存的文件完全一致的问题
1.2.2、FastDFS的组成结构
- 由两大部分构成,一个是客户端,一个是服务端
- 客户端:指我们的程序,比如我们的Java程序去连接FastDFS、操作FastDFS,那我们的Java程序就是一个客户端。FastDFS提供专有API访问,目前提供了C、Java和PHP几种编程语言的API,用来访问FastDFS文件系统
- 服务端由两个部分构成:一个是跟踪器(tracker),一个是存储节点(storage)
- 跟踪器 tracker:这个玩意儿类似于Erueka / zookeeper注册中心,起到一个调度的作用。它是在内存中记录集群中存储节点storage的状态信息,是前端Client和后端存储节点storage的枢纽,因为相关信息全部在内存中,Tracker server的性能非常高,一个较大的集群(比如上百个group,group指的就是:文件系统 和 数据备份的组合,这二者就是一个group)中有3台就足够了
- 存储节点 storage:用于存储文件,包括文件和文件属性(meta data,如:文件名、文件大小、文件后缀...)都保存到存储服务器磁盘上。以及完成文件管理的所有功能:文件存储、文件同步和提供文件访问( 上传、下载、删除 )等
2、开始玩FastDFS 2.1、安装FastDFS
-
注:我的系统是centos 7
-
安装需要的依赖环境 gcc、libevent、libevent-devel
yum install gcc libevent libevent-devel -y
- 安装公共函数库libfastcommon 和 fastDFS压缩包
- 自行去前面官网中进行下载,当然:官网的wiki中有在线拉取命令
- 解压公共函数库libfastcommon
tar -zxvf libfastcommon-1.0.36.tar.gz
- 进入libfastcommon,执行里面的make.sh,编译公共函数
./make.sh
# 当然:可以把命令进行合并 执行如下命令 就是编译并安装
./make.sh && ./make.sh install
- 安装公共函数
./make.sh install
- 解压
fastdfs-5.11.tar.gz压缩包
tar -zxvf fastdfs-5.11.tar.gz
- 进入解压之后的文件,使用
make sh进行编译
./make.sh
# 一样的可以用组合命令 即:编译并安装
./make.sh && ./make.sh install
- 安装
./make.sh install
- 检查是否安装成功,进入如下的目录即可
cd /usr/bin
- 往后找,出现这些fdfs开头的文件就表示成功( 这些文件就是fastDFS的相关命令 )
- fastDFS配置文件所在地,进入如下目录即可
- 想要让fastDFS的配置文件生效,那么就需要放到下面的这个目录中
cd /etc/fdfs
- 拷贝两个配置文件到
etc/fdfs中,这两个配置文件在解压的fastDFS的conf中,一个叫www.csource.org/ for more detail. # 这是配置的client.conf中的信息 [2022-06-01 10:17:07] DEBUG - base_path=/opt/fastdfs/client, connect_timeout=30, network_timeout=60, tracker_server_count=1, 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: 0 tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=162.14.66.60, port=23000 group_name=group1, ip_addr=162.14.66.60, port=23000 storage_upload_by_filename # 重要的信息在这里group_name、remote_filename # group_name就是组名,在前面配置中见过它,就是说的文件系统 和 数据备份这二者的组合名 # remote_filename 远程文件名 这是关键中的关键,告知你:文件保存到那里去了 group_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt source ip address: 10.0.0.16 file timestamp=2022-06-01 10:17:07 file size=641 file crc32=1141168436 # 下面这个URL地址很重要,就是去浏览器访问上传的这个文件资源的地址,但是:目前还不可以访问,因为没有配置Nginx example file url: 162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt storage_upload_slave_by_filename group_name=group1, remote_filename=M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt source ip address: 10.0.0.16 file timestamp=2022-06-01 10:17:07 file size=641 file crc32=1141168436 example file url: 162.14.66.60/group1/M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt- 单独说明:
remote_filename
remote_filename=M00/00/00/ M00 指的是:/opt/fastdfs/storage/files/data 就是前面去看默认创建文件数( 256 * 256 )的位置,跟前面的配置有关啊 00/00/ 指的就是:/opt/fastdfs/storage/files/data目录下的00子目录,这里面的00目录 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt 指的是:保存的文件名 fastdfs会重新生成文件名,以防的就是同名文件,造成附件覆盖的问题- 上图中几个文件解读
# _big 就是数据备份文件 # _m 就是meta data文件,即:文件属性文件( 文件名、文件后缀、文件大小..... ) -rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt -rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m # 这两个就是文件系统中的文件 -rw-r--r-- 1 root root 641 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt -rw-r--r-- 1 root root 49 Jun 1 10:17 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt 和 文件系统中的CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt存的内容是一样的 # CgAAEGKWzCOACGE1AAACgUQE2TQ590_big.txt-m 和 CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt-m这两个备份文件也是相应的
2.2.4.2、测试文件下载和删除- 前面已经见过对应的语法了
fdfs_test <config_file> <operation> operation: upload, download, getmeta, setmeta, delete and query_servers # <> 表示必填- 变一下就可以了
# 变成下载的命令,然后使用此命令查看完整命令即可 fdfs_test /etc/fdfs/client.conf download # 根据执行上面的命令,得到文件下载的语法 fdfs_test <config_file> download <group_name> <remote_filename> # 那么想要下载刚刚上传的文件,执行如下的命令即可 fdfs_test /etc/fdfs/client.conf download group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt # 其中:group 和 remote_filename都在前面上传时见过了 # 注:这个下载是下载到当前所在目录的位置 # 同理:就可以得到文件删除的命令了 fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/CgAAEGKWzCOACGE1AAACgUQE2TQ590.txt- 以上这些
fdfs_test只会在测试时使用,其他地方基本上都不用的
2.3、安装Nginx-
上传
fastdfs-niginx扩展模块 并 解压 - 使用官网中wiki说明的命令拉取也行 -
安装nginx,要是有的话就跳过
- 记住两个目录
# nginx安装目录 /usr/local/nginx_fdfs # fastdfs-nginx模块的src目录 /usr/local/fastdfs-nginx-module-master/src- 进入nginx安装目录,进行模块添加配置
# 进入nginx安装目录 cd nginx_fdfs # 执行模块配置 # prefix 就是前面让记住的nginx安装目录 add-module就是fastdfs-nginx模块的src目录 ./configure --prefix=/usr/local/nginx_fdfs --add-module=/usr/local/fastdfs-nginx-module-master/src- 编译并安装
# 在安装的nginx目录下载执行下述命令 make & make install- 注释事项:Nginx的安装需要Linux安装相关的几个库,否则编译会出现错误,有这几个的话就不安装了
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel –y
2.3.1、修改需要的配置文件- 将fastdfs-nginx扩展模块中的
mod_fastdfs.conf文件复制到/etc/fdfs中
cp /usr/local/fastdfs-nginx-module-master/src/mod_fastdfs.conf /etc/fdfs- 修改
/etc/fdfs/mod_fastdfs.conf
vim mod_fastdfs.conf # 修改内容如下: # 这个目录要保证存在,不存在就要配置好了创建它 mkdir -p /opt/fastdfs/nginx_mod base_path=/opt/fastdfs/nginx_mod tracker_server=自己服务器ip:22122 # 访问地址是否带上组名 url_have_group_name = true store_path0=/opt/fastdfs/storage/files- 上面
base_path目录要是不存在记得创建
- 进入
nginx_fdfs的安装目录中,去nginx.conf中配置fastdfs-nginx的扩展模块
# 编辑nginx.conf文件 vim /usr/local/nginx_fdfs/conf/nginx.conf # 配置内容 location ~ /group[1-9]/M0[0-9] { ngx_fastdfs_module; } # 解读:ngx_fastdfs_module # 这个指令不是Nginx本身提供的,是扩展模块提供的,根据这个指令找到FastDFS提供的Nginx模块配置文件,然后找到Tracker,最终找到Stroager- 启动
nginx
/usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf -t /usr/local/nginx_fdfs/sbin/nginx -c /usr/local/nginx_fdfs/conf/nginx.conf # 保险起见,查看nginx是否启动成功 ps -ef | grep nginx- 注意:这里很容易出现启动不起来,如果下面这个进程没有启动起来
nobody 3895 3894 0 15:45 ? 00:00:00 nginx: worker process- 那么:就去查看日志文件
cd /usr/local/nginx_fdfs/logs # 还有一份日志中也可能出现错误信息 cd /opt/fastdfs/nginx_mod
2.4、Java操作FastDFS 2.3.2、扩展模块执行流程- 下面这个流程很重要,涉及到另外更深入的知识( 如:集群部署FastDFS,本篇博客没有说明集群部署,哪些就是固定命令和流程,百度复制粘贴修改即可 )
2.4.1、文件上传- 在
resources目录下创建fastdfs.conf文件,并编写如下内容:
tracker_server=服务器ip:22122- 编写文件上传代码
package com.zixieqing; import org.csource.common.MyException; import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : UploadFile * @description : 该类功能 FastDFS文件上传 * @packageName : com.zixieqing */ public class UploadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、创建tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、创建storage客户端 - 这个对象就是用来上传文件、下载文件、删除文件的 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、上传文件 /* 这里有两个API需要了解 String[] upload_file(byte[] file_buff, int offset, int length, String file_ext_name, NameValuePair[] meta_list) 这个API常用来web中上传文件的 参数1 file_buff、文件字节 offset、length、从文件的那个位置开始上传,截止位置 参数4 file_ext_name、文件后缀 参数5 meta_list、文件的属性文件 String[] upload_file(String local_filename, String file_ext_name, NameValuePair[] meta_list) 这个API是上传本地文件的 参数1 local_filename、本地文件的绝对路径 参数2 file_ext_name、文件后缀名 参数3 meta_list、文件的属性文件,linux1中的哪个meta data,一般都不传 上述这两个API,注意返回值,这个String[] 很重要,就是涉及到linux中的那个组名group 和 远程文件名remote_filename,这个group和remote_fileName一般是存在数据库中的 */ String[] result = storageClient.upload_file("C:\\Users\\ZiXieQing\\Desktop\\图库\\19.jpg", "jpg", null); // 7、验证一下 for (String data : result) { System.out.println("data = " + data); } } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } }- 浏览器访问
2.4.2、文件下载- 把前面的文件上传代码改一下即可,换成另一个API而已
package com.zixieqing; import org.csource.common.MyException; import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DownloadFile * @description : 该类功能 fastDFS文件下载 * @packageName : com.zixieqing */ public class DownloadFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、获取tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、创建storage客户端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、下载文件 /* 这里需要知道两个API byte[] download_file(String group_name, String remote_filename) 这个API常用于web操作 int download_file(String group_name, String remote_filename, String local_filename) 这个API是把文件下载到本地磁盘中 这个API的返回值结果很重要 */ String group = "group1"; String remoteFileName = "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"; // 存入本地磁盘路径+存入磁盘的文件名 String localFileName = "d:/靓妹.jpg"; // 只有返回值是0才表示下载成功,否则只要是其他数字都是下载失败( 其他数字有可能是组名错了,远程文件名错了........ int result = storageClient.download_file(group, remoteFileName, localFileName); // 7、验证 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); } finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } }
2.4.3、文件删除package com.zixieqing; import org.csource.common.MyException; import org.csource.fastdfs.*; import java.io.IOException; /** * @author : ZiXieQing * @version : V1.0.0 * @className : DeleteFile * @description : 该类功能 FastDFS删除文件 * @packageName : com.zixieqing */ public class DeleteFile { public static void main(String[] args) { TrackerServer trackerServer = null; StorageServer storageServer = null; try { // 1、初始化配置文件 ClientGlobal.init("fastdfs.conf"); // 2、获取tracker客户端 TrackerClient trackerClient = new TrackerClient(); // 3、获取trackerServer trackerServer = trackerClient.getConnection(); // 4、获取storageServer storageServer = trackerClient.getStoreStorage(trackerServer); // 5、获取storage客户端 StorageClient storageClient = new StorageClient(trackerServer, storageServer); // 6、执行文件删除 /* int delete_file(String group_name, String remote_filename) 参数1 group_name、组名 参数2 remote_filename、远程文件名 */ // 一样的,返回值是0就表示成功,其他都是删除失败 int result = storageClient.delete_file("group", "M00/00/00/CgAAEGKYRg-AAIrWAAD8cA4U6dY771.jpg"); // 7、验证一下 System.out.println("result = " + result); } catch (IOException e) { throw new RuntimeException(e); } catch (MyException e) { throw new RuntimeException(e); }finally { // 8、释放资源 if (storageServer != null) { try { storageServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } if (trackerServer != null) { try { trackerServer.close(); } catch (IOException e) { throw new RuntimeException(e); } } } } } - 单独说明:

