保姆级教程-分布式文件系统FastDFS(高效存储,有效解决大量资源上传下载)

x33g5p2x  于2022-02-17 转载在 其他  
字(11.8k)|赞(0)|评价(0)|浏览(273)

官方网站:https://github.com/happyfish100/

配置文档:https://github.com/happyfish100/fastdfs/wiki/

参考资料:https://www.oschina.net/question/tag/fastdfs

Java客户端:https://github.com/happyfish100/fastdfs-client-java

为什么要学习分布式文件系统?

在我们的web开发中,很多的时候都需要把本机的一些文件上传到web服务器上面去。

举一个简单的例子,按照一个传统的上传方式,前端使用form表单,提交按钮直接submit到后台,其关键的代码就是文件的接收,至于后面的存储操做,基本上都是对IO流的操做。而文件也只是保存到本地磁盘或对应的服务器。这样就会有一些致命的缺点。

如果这台计算机宕机了,那么会导致整个服务不可用,文件不能上传和下载了,如果这台计算机磁盘损坏了那么会丢失所有的文件。并且这台计算机的磁盘空间非常有限,很容易达到磁盘的上线导致无法上传文件。
了解完传统的文件上传系统的一些弊端后,我们针对下方的一个需求带大家进一步了解分布式文件系统的一些好处。

  • 需求案例:假设现在需要做一个类似抖音b站的,视频分享网站,会拥有大量的视频教程资源供用户观看以及上传下载,文件太多如果高效存储?用户访问量大如何保证下载速度呢?
  • :分布式文件系统是解决这些问题的有效方法之一

什么是分布式文件系统?

百度百科是这样说的!

  • 分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源不一定直接连接在本地节点上,而是通过计算机网络与节点相连。分布式文件系统的设计基于客户机/服务器模式。一个典型的网络可能包括多个供多用户访问的服务器。
  • 另外,对等特性允许一些系统扮演客户机和服务器的双重角色。例如,用户可以“发表”一个允许其他客户机访问的目录,一旦被访问,这个目录对客户机来说就像使用本地驱动器一样。

这里讲的可能会有些官方,没关系!下面我将结合上方的需求给大家做了一个简单的总结。

之前我们将上传的视频文件放在一台宿主机内,如果一个盘符内存不够,就增加硬盘个数,但是单纯的增加硬盘个数已经无法满足当代的需求,毕竟硬盘访问速度有限。

分布式文件系统将视频分别放在不同计算机内,通过网络将一个一个计算机的文件系统连接起来组成一个网络文件系统,形成一个分布式网络,一台计算机的文件系统处理能力扩充到多台计算机内同时处理,就算某一台计算机挂了,还有另外副本(备份)计算提供数据。每台计算机也可以放在不同的地域,这样用户就可以就近访问,提高访问速度。有效的解决单点故障文件丢失等一系列问题,特别适合我们高并发,常扩容的这么一个业务场景下。

FastDFS

FastDFS纯C语言实现,支持Linux、FreeBSD等UNIX系统类google FS,不是通用的文件系统,只能通过专有API访问,目前提供了C、Java和PHP API为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性FastDFS可以看做是基于文件的key value pair存储系统,称作分布式文件存储服务更为合适。

FastDFS是什么?

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载) 等,解决了大容量存储和负载均衡的问题。

特别适合以文件为载体的在线服务,如相册网站、视频网站、图片网站、文档网站等等。

FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

FastDFS整体架构

FastDFS文件系统主要由两大部分构成,一个是客户端,一个是服务端。

客户端(Client)通常指我们的程序

  • 比如我们的Java程序去连接FastDFS,操作FastDFS,那我们的Java程序就是一个客户端,FastDFS提供有API用来访问FastDFS文件系统,控制文件上传下载层( 如果你是 java 开发,你只需要关心着一层)。

服务端有两个部分构成

  1. 跟踪器(Tracker):跟踪器主要做调度工作,在内存中记录集群中存储节点storage的状态信息,是前端 Client 和后端存储节点storage的枢纽。因为相关信息全部在内存中,Tracker server 的性能非常高,一个较大的集群(比如上百个group)中有3台就足够了。
  2. 存储节点(Storage):存储节点(storage)用于存储文件,包括文件和文件属性(meta data)都保存到存储服务器磁盘上,完成文件管理的所有功能:文件存储,文件同步和提供文件访问等。

下载安装

  • 下载安装分以下三个步骤,请按照顺序进行操作。

一.安装前置依赖包

检查Linux上是否安装了 gcc,libevent,libevent-devel

yum list installed | grep gcc
yum list installed | grep libevent
yum list installed | grep libevent-devel

如果没有安装以上前置依赖包,则需要通过下面命令进行安装

yum install gcc libevent libevent-devel-y

二.安装libfastcommon

前置依赖包安装成功后,我们紧接着需要安装公共函数库 libfastcommon

  1. 获取libfastcommon安装包
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.36.tar.gz

  1. 解压安装包
tar -zxvf V1.0.36.tar.gz

  1. 安装完成后进入 libfastcommon 目录
cd libfastcommon-1.0.36

  1. 在 libfastcommon 目录执行编译
./make.sh

  1. 安装 libfastcommon
./make.sh install

三.安装FastDFS

  1. 获取fast安装包,这里采用的版本为5.11
wget https://github.com/happyfish100/fastdfs/archive/V5.11.tar.gz

  1. 解压安装包
tar -zxvf V5.11.tar.gz

  1. 安装成功后进入目录
cd fastdfs-5.11

  1. 执行编译 make.sh 文件
./make.sh

  1. 安装 fastdfs
./make.sh install

  1. 安装成功后,查看可执行命令,这些命令放在usr/bin目录下表示不用去配置环境变量就可以直接使用我们fastdfs的命令
ls -la /usr/bin/fdfs*

  1. 拷贝 http.conf 文件到 /etc/fdfs 目录下
cp http.conf /etc/fdfs/

  1. 拷贝 mime.types 文件到 /etc/fdfs 目录下
cp mime.types /etc/fdfs/

拷贝这两个文件后续会用到,为了避免报错大家拷贝完记得进入目录查看一下

想要成功启动我们还需要进行修改以下两个配置

配置Tracker服务
  1. 修改 tracker 文件后缀,该文件在 /etc/fdfs 目录下,进入目录后发现有三个.sample后缀的文件(自动生成的fdfs模板配置文件),通过cp命令拷贝tracker.conf.sample,删除.sample后缀作为正式文件。
cd /etc/fdfs/

cp tracker.conf.sample tracker.conf

  1. 编辑 tracker.conf 文件,修改相关参数
vim tracker.conf

base_path 指定存放日志的路径,要求该路径必须存在。port 默认端口号。http.server_port 为http端口,需要和nginx相同

base_path=/home/fastdfs/tracker 
port=22122
http.server_port=80

修改完成后输入wq保存并退出,紧接着在配置的目录下创建该文件夹

mkdir /home/fastdfs/tracker

  1. 启动并测试
fdfs_trackerd

通过上方说明命令产生的结果fdfs_trackerd <config_file> [start | stop | restart] 可以告诉我们怎么去用

  • <config_file>代表配置文件是必选项,start为启动,stop为停止,restart为重启他们都是可选项,默认为start

我们想要运行trackerd.conf文件就可以通过下方命令去执行

fdfs_trackerd /etc/fdfs/tracker.conf

配置Storage服务
  1. 修改文件后缀
cd /etc/fdfs/

cp storage.conf.sample storage.conf

  1. 编辑 storage.conf 文件,修改相关参数
vim storage.conf

#storage存储data和log的跟路径,必须提前创建好
base_path=/home/fastdfs/storage

#storge默认23000,同一个组的storage端口号必须
port=23000

#默认组名,根据实际情况修改
group_name=group1

#存储路径个数,需要和store_path个数匹配
store_path_count=1

#真正存放文件的目录,如果为空,则使用base_path
store_path0=/home/fastdfs/storage/files

#配置该storage监听的tracker的ip和port
tracker_server=xx.xxx.xxx.xxx:22122

配置完成后不要忘记创建对应的文件夹

mkdir /home/fastdfs/storage
mkdir /home/fastdfs/storage/files
  1. 启动并测试
fdfs_storaged /etc/fdfs/storage.conf

查看我们两个服务是否启动成功

ps -ef|grep fdfs

四.安装Nginx和fastdfs-nginx-module模块

  1. 下载Nginx安装包
wget http://nginx.org/download/nginx-1.14.2.tar.gz

  1. 下载fastdfs-nginx-module安装包
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.20.tar.gz

  1. 解压nginx
tar -zxvf nginx-1.14.2.tar.gz

  1. 解压fastdfs-nginx-module
tar -xvf V1.20.tar.gz

  1. 进入nginx目录
cd nginx-1.14.2

  1. gcc 安装

安装 nginx 需要先将官网下载的源码进行编译,编译依赖 gcc 环境,如果没有 gcc 环境,则需要安装。

yum install gcc-c++

  1. PCRE pcre-devel 安装

PCRE(Perl Compatible Regular Expressions) 是一个Perl库,包括 perl 兼容的正则表达式库。nginx 的 http 模块使用 pcre 来解析正则表达式,所以需要在 linux 上安装 pcre 库,pcre-devel 是使用 pcre 开发的一个二次开发库。nginx也需要此库。

yum install -y pcre pcre-devel
  1. zlib 安装

zlib 库提供了很多种压缩和解压缩的方式, nginx 使用 zlib 对 http 包的内容进行 gzip ,所以需要在 Centos 上安装 zlib 库。

yum install -y zlib zlib-devel
  1. OpenSSL 安装

OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及 SSL 协议,并提供丰富的应用程序供测试或其它目的使用。

nginx 不仅支持 http 协议,还支持 https(即在ssl协议上传输http),所以需要在 Centos 安装 OpenSSL 库。

yum -y install openssl openssl-devel

  1. 配置,并加载fastdfs-nginx-module模块
./configure --prefix=/usr/local/nginx-fast --add-module=/home/nginx-linux/fastdfs-nginx-module-1.20/src

  1. 编译安装
make

make时出现问题请参考:https://chonglian.blog.csdn.net/article/details/122754262?spm=1001.2014.3001.5502

make install

  1. nginx启动,停止,重启命令
#上方nginx的安装目录
cd /usr/local/nginx-fast/sbin/

#启动
./nginx 

#此方式相当于先查出nginx进程id再使用kill命令强制杀掉进程
./nginx -s stop 

#此方式停止步骤是待nginx进程处理任务完毕进行停止
./nginx -s quit 

#重启
./nginx -s reload
配置Nginx和fastdfs-nginx-module模块
  1. 打开mod-fastdfs.conf所在位置拷贝到/etc/fdfs文件目录下
cd /home/nginx-linux/fastdfs-nginx-module-1.20/src/
cp mod_fastdfs.conf /etc/fdfs/
  1. 进入/etc/fdfs修改mod-fastdfs.conf
#基础路径,确保文件夹存在
base_path=/home/fastdfs/nginx_mod

#tracker的地址
tracker_server=xx.xxx.xxx.xxx:22122 

#url是否包含group名称
url_have_group_name=true 

#需要和storage配置的相同
storage_server_port=23000

#存储路径个数,需要和store_path个数匹配
store_path_count=1  

#文件存储的位置
store_path0=/home/fastdfs/storage/files

  1. base_path 创建基础目录
mkdir /home/fastdfs/nginx_mod

  1. 配置nginx,80端口server增加location
cd /usr/local/nginx-fast/conf/
location ~ /group[1-9]/M0[0-9] {
       ngx_fastdfs_module;
}

上传下载测试

完成上面诸多步骤后,我们的fastDFS就安装完毕了下面我们进行上传下载删除操作测试。

  1. 启动nginx
/usr/local/nginx-fast/sbin/nginx -c /usr/local/nginx-fast/conf/nginx.conf

通过命令检查我们nginx是否启动成功(两个进程)

ps -ef|grep nginx

上传文件

  1. 进入/etc/fdfs目录,有cp命令拷贝client.conf.sample,删除.sample后缀作为正式文件。

  1. 修改client.conf相关配置
#基础文件路径需要提前创建
base_path=/home/fastdfs/client

#tracker服务器IP地址和端口号
tracker_server=xx.xxx.xxx.xxx:22122

#tracker服务器的http端口号,必须和tracker的设置对应起来
http.tracker_server_port=80

  1. 创建基础路径文件夹
mkdir /home/fastdfs/client

  1. 重启 trackerd 与 storage
fdfs_trackerd /etc/fdfs/tracker.conf restart
fdfs_storaged /etc/fdfs/storage.conf restart

重启完记得查看进程有没有启动成功

ps -ef|grep fdfs

  1. 回到 ~目录创建要上传的文件aa.txt,内容为测试文件
cd ~
vim aa.txt

  1. 上传
fdfs_test /etc/fdfs/client.conf upload aa.txt

上传成功后这里面有几处重要信息

#group_name:组名    ip_addr:ip地址  port:端口号
group_name=group1, ip_addr=xx.xxx.xxx.xx, port=23000
storage_upload_by_filename
#remote_filename:远程文件名称(决定我们的文件存放在哪个磁盘目录下) M00:表示第一个磁盘路径=/home/fastdfs/storage/files/data	
group_name=group1, remote_filename=M00/00/00/rBOAlmH2mmqANl6tAAAADi991u4762.txt
source ip address: 172.19.128.150
file timestamp=2022-01-30 22:02:18
file size=14
file crc32=796776174
example file url: http://39.103.137.90/group1/M00/00/00/rBOAlmH2mmqANl6tAAAADi991u4762.txt
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/rBOAlmH2mmqANl6tAAAADi991u4762_big.txt
source ip address: 172.19.128.150
file timestamp=2022-01-30 22:02:18
file size=14
file crc32=796776174
example file url: http://39.103.137.90/group1/M00/00/00/rBOAlmH2mmqANl6tAAAADi991u4762_big.txt
  1. 查看结果

M00/00/00/rBOAlmH2mmqANl6tAAAADi991u4762.txt

cd /home/fastdfs/storage/files/data/00/00/

有big的表示备份的意思,-m表示文件的属性文件通常会记录文件的扩展名大小等基本信息。

  1. 通过浏览器访问

下载文件

  1. 通过download命令指定组名文件位置进行下载
/usr/bin/fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/rBOAlmH2mmqANl6tAAAADi991u4762.txt

删除文件

/usr/bin/fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/rBOAlmH2mmqANl6tAAAADi991u4762.txt

删除成功后我们进入storage/files/data目录进行查看发现除了备份文件与属性文件外源文件已经被成功删除了

FastDFS-扩展模块执行流程

  1. 扩展模块解析了请求的文件路径以后,到指定的Tracker获取组名为group1的这个机器所在IP以及端口。
  2. 扩展模块获取了stroage所在IP以及端口后,就会自动使用Fastdfs的命令到指定的机器中获取文件流。

常用命令

  1. 启动FastDFS(每个人的路径可能不一样,找到自己的安装路径)

启动tracker:fdfs_trackerd /etc/fdfs/tracker.conf

启动storage: fdfs_storaged /etc/fdfs/storage.conf

  1. 关闭FastDFS

关闭tracker:/usr/local/bin/stop.sh fdfs_tracker

关闭storage: /usr/local/bin/stop.sh fdfs_storage

  1. 重启FastDFS

重启tracker: /usr/local/bin/restart.sh fdfs_trackered

重启storage: /usr/local/bin/restart.sh fdfs_storaged

  1. 查看集群情况 (%FastDFS%为自己的安装路径)

在任意一台storage(tracker也可以):/usr/local/bin/fdfs_monitor %FastDFS%/storage.conf

  1. 删除一个storage (%FastDFS%为自己的安装路径)

在任意一台storage(tracker也可以):/usr/local/bin/fdfs_monitor %FastDFS%/storage.conf delete group2 20.12.1.73

  1. 上传文件

fdfs_upload_file

  1. 下载文件

fdfs_download_file

  1. 查看文件信息

fdfs_file_info

  1. 删除文件

fdfs_delete_file

  1. 追加文件内容

fdfs_upload_appenderfdfs_append_file

  1. 监控服务器状态命令

fdfs_monitor

Java操作FastDFS

因为Maven依赖库中没有添加FastDFS相关依赖我们想要在java项目中引入FastDFS就需要在本地进行手动配置

准备工作

  1. 下载源码包并解压

地址:https://gitcode.net/mirrors/happyfish100/fastdfs-client-java?utm_source=csdn_github_accelerator

  1. 采用maven命令编译成jar安装到本地maven库

通过cmd打开黑窗口(注意文件夹位置)

通过下方清空并安装命令它会进行自动打包(需要配置maven环境变量)

mvn clean install

  1. 通过idea工具创建普通的maven工程

  1. 添加依赖
<dependency>
            <groupId>org.csource</groupId>
            <artifactId>fastdfs-client-java</artifactId>
            <version>1.29-SNAPSHOT</version>
        </dependency>

  1. 在resources目录下准备一个fastdfs.conf文件并编写相关配置

  1. 创建工具类测试上传,下载,删除等一系列操作

上传文件

  1. 编写代码
/**
     * 文件上传
     */
    public static void upload(){
        try {
            //读取fastDFS的配置文件用于将所有的tracker的地址读取到内存中
            ClientGlobal.init("fastdfs.conf");
            System.out.println("初始化信息:"+ClientGlobal.configInfo());

            // 链接FastDFS服务器,创建tracker和Stroage
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getTrackerServer();
            StorageServer storageServer=trackerClient.getStoreStorage(trackerServer);

            //定义Stroage客户端对象,需要使用这个对象来完成具体的文件上传,下载和删除操作
            StorageClient storageClient=new StorageClient(trackerServer,storageServer);

            /**
             * 文件上传
             * 参数1:需要上传的文件的绝对路径
             * 参数2:需要上传的文件的扩展名
             * 参数3:文件的属性文件(通常不用上传)
             * 返回一个String数组,这个数据对我们非常重要必须妥善保管(建议存入数据库)
             * 数组中的一个元素为文件所在的组名
             * 数组中的第二个元素为文件所在远程路径名
             */
            String[] result= storageClient.upload_file("C:/Users/mzc/Desktop/剪辑素材/测试图片.jpg","jpg",null);

            for (String str:result){
                System.out.println(str);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  1. 运行

  1. 测试(运行成功后会得到组名和路径名,通过ip地址/组名/远程路径名进行访问)

下载文件

  1. 编写下载文件代码
/**
     * 下载文件
     */
    public static void download(){
        try {
            //读取fastDFS的配置文件用于将所有的tracker的地址读取到内存中
            ClientGlobal.init("fastdfs.conf");
            System.out.println("初始化信息:"+ClientGlobal.configInfo());

            // 链接FastDFS服务器,创建tracker和Stroage
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getTrackerServer();
            StorageServer storageServer=trackerClient.getStoreStorage(trackerServer);

            //定义Stroage客户端对象,需要使用这个对象来完成具体的文件上传,下载和删除操作
            StorageClient storageClient=new StorageClient(trackerServer,storageServer);

            /**
             * 文件下载
             * 参数1:需要下载的文件的组名
             * 参数2:需要下载文件的远程文件名
             * 参数3:需要保存的本地文件名
             * 返回一个int类型的数据,返回0表示文件下载成功,其他值表示文件下载失败
             */
            String groupName="group1";
            String remoteFileName="M00/00/00/rBOAlmIN4bCAKz-VAADA9OtiDMc665.jpg";
            String localFileName="E:/aa.jpg";
            int result= storageClient.download_file(groupName,remoteFileName,localFileName);
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  1. 运行程序

  1. 测试

删除文件

  1. 编写代码
/**
     * 删除文件
     */
    public static void delete(){
        try {
            //读取fastDFS的配置文件用于将所有的tracker的地址读取到内存中
            ClientGlobal.init("fastdfs.conf");
            System.out.println("初始化信息:"+ClientGlobal.configInfo());

            // 链接FastDFS服务器,创建tracker和Stroage
            TrackerClient trackerClient = new TrackerClient();
            TrackerServer trackerServer = trackerClient.getTrackerServer();
            StorageServer storageServer=trackerClient.getStoreStorage(trackerServer);

            //定义Stroage客户端对象,需要使用这个对象来完成具体的文件上传,下载和删除操作
            StorageClient storageClient=new StorageClient(trackerServer,storageServer);

            /**
             * 文件删除
             * 参数1:需要下载的文件的组名
             * 参数2:需要下载文件的远程文件名
             * 返回一个int类型的数据,返回0表示文件删除成功,其他值表示文件删除失败
             */
            String groupName="group1";
            String remoteFileName="M00/00/00/rBOAlmIN4bCAKz-VAADA9OtiDMc665.jpg";
            int result= storageClient.delete_file(groupName,remoteFileName);
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  1. 运行程序

  1. 测试

相关文章