概述
分布式文件系统
-
分布式文件系统(Distributed File System)是一个软件/软件服务器 此软件可以用来管理在多个服务器节点中的文件(这些服务器节点通过网络相连并构成一个庞大的文件存储服务器集群 即这些服务器节点都是用来存储文件资源的 且用dfs来管理这些文件)
-
传统文件系统与分布式文件系统的对比
-
传统文件系统的缺点
- 若用户数量多 则io操作会很频繁 则对磁盘的访问压力会较大
- 若磁盘故障 则可能会造成数据的丢失
- 一个磁盘的存储容量有限
FastDFS
-
fastdfs是一个开源的轻量级分布式文件系统 由c语言开发
-
fastdfs对文件进行管理的功能有存储、同步、访问(上传、下载、删除)等
-
fastdfs有冗余备份、线性扩容等机制 高可用、高性能 且解决了较大文件的存储问题 特别适合应用于如相册网站、文档网站、图片网站、视频网站等以文件为载体的在线服务的网站
-
架构
- 客户端
- 即使用java去连接/操作fastdfs的代码
- 服务端
- 跟踪器(tracker)
- 负责调度且在内存中记录集群中storage的状态信息 是客户端与storage的中间枢纽
- 因为信息都保存在内存中 因此性能高 一般的 一个较大的集群有3台tracker就够了
- 存储节点(storage)
- 负责存储文件与文件属性等信息到服务器磁盘中 文件的存储、同步、访问都由storage来完成
- 跟踪器(tracker)
- 客户端
在linux-minimal上安装fastdfs
-
linux-mini与linux的区别
-
linux-mini没有图形界面 但占用磁盘资源小 且公司里一般使用的都是linux-mini
-
由于linux-mini较linux来说缺少一些常用的工具库 因此推荐先安装下面的工具库 否则使用起来可能会不太方便
#net-tools为使用ifconfig命令等的工具库 yum install git lrzsz wget vim unzip net-tools -y
-
#先安装第三方库(gcc编译器、libevent库) 否则配置/编译时可能会报错
yum install gcc libevent libevent-devel -y
#从github中下载(若显示连不上github则需要自己手动下载 手动下载后用tar -zxvf命令解压缩)、编译且安装libfastcommon库
#libfastcommon库是从fastdfs中分离出来的c语言公用函数库
git clone https://github.com/happyfish100/libfastcommon.git --depth 1
cd libfastcommon
./make.sh
./make.sh install
#从github中下载、编译且安装libserverframe库
#注意 若不安装libserverframe库则在编译fastdfs时会出现错误:../common/fdfs_global.h:15:26: fatal error: sf/sf_global.h: No such file or directory
git clone https://github.com/happyfish100/libserverframe.git --depth 1
cd libserverframe
./make.sh
./make.sh install
#从github中下载、编译且安装fastdfs
git clone https://github.com/happyfish100/fastdfs.git --depth 1
cd fastdfs
./make.sh
./make.sh install
#fastdfs的编译出来的文件在/usr/bin目录下(以fdfs开头)
#fastdfs的配置文件在/etc/fdfs目录下
#复制fastdfs的conf目录下的两个文件到/etc/fdfs目录下 否则实际应用时可能会出现奇奇怪怪的问题
cp http.conf /etc/fdfs
cp mime.types /etc/fdfs
#备份配置文件
cd /etc/fdfs
cp client.conf client.conf.sample
cp storage.conf storage.conf.sample
cp storage_ids.conf storage_ids.conf.sample
cp tracker.conf tracker.conf.sample
#修改tracker.conf文件
#base_path为存储tracker的数据与日志文件的目录路径
base_path = /opt/fastdfs/tracker
#修改storage.conf文件
#base_path为存储storage的数据与日志文件的目录路径
base_path = /opt/fastdfs/storage
#store_path为存储真正文件的目录 可以写多个 结尾为0、1、..的数字 若写多个 则要改store_path_count
store_path0 = /opt/fastdfs/storage/files
#store_path1 = /home/yuqing/fastdfs1
store_path_count = 1
#tracker_server表示将此storage注册到哪个tracker下
tracker_server = 192.168.190.131:22122
#测试时使用一个tracker即可 剩余的要么注释掉要么删除掉
#tracker_server = 192.168.209.122:22122
#创建上述目录
mkdir -p /opt/fastdfs/tracker
mkdir -p /opt/fastdfs/storage/files
#启动fastdfs
#启动tracker(在任意目录下)
fdfs_trackerd /etc/fdfs/tracker.conf
#启动storage(在任意目录下)
#首次启动storage后会在$store_path$/data目录下新建256^2个存储文件的目录
fdfs_storaged /etc/fdfs/storage.conf
#查看storage是否已经注册到了tracker下
fdfs_monitor /etc/fdfs/storage.conf
#若有此信息说明注册成功
tracker server is 192.168.190.131:22122
#重启tracker
fdfs_trackerd /etc/fdfs/tracker.conf restart
#重启storage
fdfs_storaged /etc/fdfs/storage.conf restart
#关闭tracker
fdfs_trackerd /etc/fdfs/tracker.conf stop
#关闭storage
fdfs_storaged /etc/fdfs/storage.conf stop
#或kill命令关闭
#但不建议使用kill -9命令强制关闭 因为可能会产生文件信息不同步的问题
本地上传本地访问
#启动/重启fastdfs
fdfs_trackerd /etc/fdfs/tracker.conf (restart)
fdfs_storaged /etc/fdfs/storage.conf (restart)
#修改client.conf文件以测试文件上传
#base_path为存储client的日志文件的目录路径
base_path = /opt/fastdfs/client
#tracker_server表示将此client注册到哪个tracker下
tracker_server = 192.168.190.131:22122
#创建上述目录
mkdir -p /opt/fastdfs/client
#测试文件上传
fdfs_test /etc/fdfs/client.conf upload /opt/fastdfs-6.09.tar.gz
-----------------------------------------------------------------------------------
#tracker查询到有一个storage注册到它的名下
tracker_query_storage_store_list_without_group:
server 1. group_name=, ip_addr=192.168.190.131, port=23000
group_name=group1, ip_addr=192.168.190.131, port=23000
#此为上传的文件的信息且fastdfs会对上传的文件进行重新命名
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz
source ip address: 192.168.190.131
file timestamp=2022-10-11 10:52:15
file size=800112
file crc32=3103841170
#/group1为组名(非cluster下默认只有一个组group1)
#/M00为linux的虚拟磁盘名
#/00/00为目录名
#/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz为文件名
example file url: http://192.168.190.131/group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz
#此为上传的文件的从文件的信息
#一般的 上传的文件只需要存一份主文件即可
#在存放图片时需要存放它的大图与小图时可以存放从文件
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz
source ip address: 192.168.190.131
file timestamp=2022-10-11 10:52:15
file size=800112
file crc32=3103841170
example file url: http://192.168.190.131/group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz
-----------------------------------------------------------------------------------
#查看上传的文件情况
cd /opt/fastdfs/storage/files/data/00/00
ll
#此为从文件
wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz
#此为从文件的属性信息(m为meta)
wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz-m
#此为主文件
wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz
#此为主文件的属性信息(m为meta)
wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz-m
#删除测试文件
#删除主文件及其属性信息
fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I.tar.gz
#删除从文件及其属性信息
fdfs_delete_file /etc/fdfs/client.conf group1/M00/00/00/wKi-g2NE2l-AGCKaAAw1cLkA25I_big.tar.gz
本地上传远程访问
#通过nginx访问已经上传到fastdfs中的文件
#从github中下载fastdfs-nginx模块
#注意 在nginx的安装过程中才能配置fastdfs-nginx模块 因此得重新安装一遍nginx
git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1
#下载并解压nginx
wget https://nginx.org/download/nginx-1.22.0.tar.gz
tar -zxvf nginx-1.22.0.tar.gz
#先安装第三方库(gcc编译器、openssl库、pcre库、zlib库) 否则配置/编译nginx时可能会报错
yum install gcc openssl openssl-devel pcre pcre-devel zlib zlib-devel -y
#配置nginx的安装路径以及要添加的模块的源代码路径
cd nginx-1.22.0
./configure --prefix=/opt/nginx --add-module=/opt/fastdfs-nginx-module/src
#编译且安装nginx
make
make install
#拷贝文件 否则可能不能正常启动nginx
cp /opt/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs
#修改mod_fastdfs.conf文件
#base_path为存储fastdfs-nginx模块的日志文件的目录路径
base_path=/opt/fastdfs/fastdfs-nginx
#tracker_server表示将此fastdfs-nginx模块注册到哪个tracker下
tracker_server=192.168.190.131:22122
#若url中带有组名则设为true 默认为false
url_have_group_name = true
#store_path为storage存储真正文件的目录 可以写多个 若写多个 则要改store_path_count
store_path0=/opt/fastdfs/storage/files
#store_path1=/home/yuqing/fastdfs1
store_path_count=1
#创建上述目录
mkdir -p /opt/fastdfs/fastdfs-nginx
#配置nginx
#表示拦截此请求路径并用fastdfs的nginx模块进行转发
#ngx_fastdfs_module:此指令非nginx提供 而是由fastdfs-nginx模块提供的 而nginx根据此指令会找到mod_fastdfs.conf文件 进而找到tracker与storage
location ~ /group[1-9]/M0[0-9] {
ngx_fastdfs_module;
}
#启动nginx
./nginx -c /opt/nginx/conf/nginx.conf
#启动/重启fastdfs
fdfs_trackerd /etc/fdfs/tracker.conf (restart)
fdfs_storaged /etc/fdfs/storage.conf (restart)
#测试文件上传
cp /opt/fastdfs-6.09/conf/http.conf /opt/a.txt
fdfs_test /etc/fdfs/client.conf upload /opt/a.txt
#访问http://192.168.190.131/group1/M00/00/00/wKi-g2NFIHaAE1jiAAADxfUPwyI976.txt
远程上传远程/本地访问
-
即使用java代码来连接与操作fastdfs并在浏览器中访问fastdfs
-
先在github上下载fastdfs-client-java-master压缩包(此压缩包实则为java代码) 解压后将此压缩包打成jar包并放到maven仓库中
#进入源码包中打开cmd并输入maven命令 (../fastdfs-client-java-master>)mvn clean install
fastdfs-java
- 使用maven项目即可
添加依赖
<!-- fastdfs依赖 -->
<!-- 此gav可在源码包的pom文件中copy -->
<dependency>
<groupId>org.csource</groupId>
<artifactId>fastdfs-client-java</artifactId>
<version>1.29-SNAPSHOT</version>
</dependency>
拷贝源码包的fdfs_client.conf文件到resources目录中并修改
tracker_server = 192.168.190.131:22122
编写文件上传、下载、删除的代码
public class FastDFS {
public static void main(String[] args) {
fileUpload();
}
/**
* 文件上传
*/
public static void fileUpload() {
try {
//获取StorageClient对象
StorageClient sc = getStorageClient();
//local_filename为需要上传的文件的绝对路径
//file_ext_name为需要上传的文件的扩展名
//meta_list为需要上传的文件的属性信息 通常为null 即不用上传
//返回值为String[] strings[0]为组名(如group1) strings[1]为远程文件名(如M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png)
//此返回值很重要 建议存入数据库
String[] result = sc.upload_file("D:/001.png", "png", null);
for (String s : result) {
System.out.println(s);
}
} catch (IOException | MyException e) {
e.printStackTrace();
}
}
/**
* 文件下载
*/
public static void fileDownload() {
try {
//获取StorageClient对象
StorageClient sc = getStorageClient();
//group_name为需要下载的文件的组名
//remote_filename为需要下载的文件的远程文件名
//local_filename为需要下载的文件保存到哪个位置的绝对路径名
//返回值为int 若为0则表示下载成功 其它值都表示下载失败
int result = sc.download_file("group1",
"M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png",
"D:/002.png");
System.out.println(result);
} catch (IOException | MyException e) {
e.printStackTrace();
}
}
/**
* 文件删除
*/
public static void fileDelete() {
try {
//获取StorageClient对象
StorageClient sc = getStorageClient();
//group_name为需要删除的文件的组名
//remote_filename为需要删除的文件的远程文件名
//返回值为int 若为0则表示删除成功 其它值都表示删除失败
int result = sc.delete_file("group1",
"M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png");
System.out.println(result);
} catch (IOException | MyException e) {
e.printStackTrace();
}
}
/**
* 获取StorageClient对象
* @return StorageClient对象
*/
public static StorageClient getStorageClient() {
StorageClient sc = null;
try {
//读取fastdfs的配置文件以将所有的tracker_server地址读取到内存中
//默认从classpath中读取
ClientGlobal.init("fdfs_client.conf");
//创建TrackerClient对象以获取TrackerServer对象与StorageServer对象
TrackerClient tc = new TrackerClient();
TrackerServer ts = tc.getTrackerServer();
StorageServer ss = tc.getStoreStorage(ts);
//通过TrackerServer对象与StorageServer对象来获取StorageClient对象
//使用StorageClient对象以实现对文件的操作
sc = new StorageClient(ts, ss);
} catch (IOException | MyException e) {
e.printStackTrace();
}
return sc;
}
}
启动nginx、fastdfs以进行测试
#永久关闭防火墙
systemctl stop firewalld
systemctl disable firewalld
#启动nginx
./nginx -c /opt/nginx/conf/nginx.conf
#启动fastdfs
fdfs_trackerd /etc/fdfs/tracker.conf
fdfs_storaged /etc/fdfs/storage.conf
#访问http://192.168.190.131/group1/M00/00/00/wKi-g2NFYm6AYYnwAAEXDUO_9AI243.png或查看fastdfs的存储文件的目录
fastdfs-web
- 使用springboot项目
配置pom
添加依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot