分布式文件系统FastDFS 实战笔记之单点部署

1、FastDFS简介

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。

FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。它是由阿里巴巴开发,c语言实现的简单、高效、灵活的分布式文件系统。

分布式文件系统:传统的文件存储系统是存放在单台服务器上,如果服务器出现问题就会导致用户不能进行文件的上传和下载。而分布式文件系统采用多台服务器来存放数据,中间添加一个分布式文件管理来协调文件上传和下载。在分布式文件系统中,如果某个单个节点出现故障,还有其他节点可以继续进行文件的上传和下载。并且分布式文件系统有数据备份的功能可以防止数据的丢失,也可以提供扩容机制,无限增加存储的大小。

2、FastDFS 安装

实战部分全部是在centos7的系统下进行!!!

前期准备:
需要准备gcclibeventlibevent-devel等环境。

yum install gcc libevent libevent-devel -y  # 安装命令

开始安装:

  1. 安装libfastcommon公共函数库。
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz # 在/etc/soft下使用命令
tar -zxvf V1.0.7.tar.gz # 解压
./make.sh # 进入到libfastcommon-1.0.7目录下编译
./make.sh install # 安装
  1. 安装FastDFS
wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz # 在/etc/soft下使用命令
tar -zxvf V5.05.tar.gz # 解压
./make.sh # 编译
./make.sh install # 安装
  1. 检查是否安装成功,在/usr/bin这个目录下是否存在以fast-开头的若干文件,这些文件是fastdfs的启动命令。

  1. fastdfs的配置文件,在/etc/soft/fastdfs-5.05/conf/目录下,需要将这个目录下的http.confmime.type拷贝到/etc/fdfs/这个目录下。
cp http.conf /etc/fdfs/
cp mime.types /etc/fdfs/

3、FastDFS 配置和启动

  1. tracker.conf.sample配置:
# the tracker server port
# tracker的端口号,默认就行不用改,但是需要记住
port=22122
# the base path to store data and log files
# 会在这个目录下生成一些日志文件,这个目录需要自己手动创建
base_path=/home/xiaotanke/fastdfs/tracker
  1. storage.conf.sample配置:
# the base path to store data and log files
# 日志文件的存放位置,自己手动创建
base_path=/home/xiaotanke/fastdfs/storage
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
# 上传文件的保存路径,这个目录必须存在,并且是手动创建的
store_path0=/home/xiaotanke/fastdfs/storage/files
#store_path1=/home/yuqing/fastdfs2
# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
# 主机的ip地址,需要与自己的服务器对应,如果只需要在内网访问,就只需要配置内网就可以,如果需要外网访问就需要配置外网,一般都是配置内网,因为代码是在服务器上跑,这样更加安全
# 如果需要使用外网访问,需要把防火墙的22122端口打开
tracker_server=xx.xx.xx.xx:22122
  1. 启动
# 启动tracker
fdfs_trackerd /etc/fdfs/tracker.conf# 启动stroage
fdfs_storaged /etc/fdfs/storage.conf# 启动完成后查看进程是否启动成功
ps -ef|grep fdfs

像这样就是启动成功了,进入之前配置的文件保存路径 /home/xiaotanke/fastdfs/storage/files/data,会生成下面这些文件夹,这样就启动成功了。

  1. 关闭和重启服务
# 操作 tracker
fdfs_trackerd /etc/fdfs/tracker_conf stop/restart # 停止和重启服务
# 操作 stroage
fdfs_storaged /etc/fdfs/storage_conf stop/restart # 停止和重启服务kill -9 服务名称 # 也可以通过这个方式来强制停止服务,这样存在一定危险,不建议使用

4、测试文件上传、下载、删除

测试上传

进入 /etc/fdfs 下,会发现有一个 client.conf.sample,将文件修改为 client.conf,并进行下面的配置,这个配置文件只用于测试,没有其他作用。

# 配置日志文件,这个文件夹需要手动创建
base_path=/home/xiaotanke/fastdfs/client#  配置访问地址,需要开启防火墙22122端口
tracker_server=xx.xx.xx.xx:22122
# 测试
# Usage: fdfs_test <配置文件client> <操作,upload/download/delete>
#   operation: upload, download, getmeta, setmeta, delete and query_servers# 上传测试,还需要开启防火墙的23000端口
fdfs_test /etc/fdfs/client.conf upload test.txt
[root@xiaotanke ~]# fdfs_test /etc/fdfs/client.conf upload test.txt # 下面是上传成功的输出
[2022-03-22 09:42:39] DEBUG - base_path=/home/xiaotanke/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: 0tracker_query_storage_store_list_without_group: server 1. group_name=, ip_addr=xx.xx.xx.xx, port=23000# group_name 是配置的组名,决定文件存放在哪个主机上
# remote_filename 是远程文件名 M00 是磁盘路径,是在storage.conf中配置的,M00是第一个磁盘路径,表示就是/home/xiaotanke/fastdfs/storage/files,rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt就是上传的文件名
# storage.conf中的配置# store_path_count=1,磁盘数目,默认是1,可以配置多个保存文件磁盘# store_path0=/home/xiaotanke/fastdfs/storage/files  磁盘路径
group_name=group1, ip_addr=xx.xx.xx.xx, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt
source ip address: xx.xx.xx.xx
file timestamp=2022-03-22 09:42:39
file size=36
file crc32=2057575212
# url是远程访问路径,但是不能访问,需要配置nginx才能访问
example file url: http://xx.xx.xx.xx/group1/M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt
storage_upload_slave_by_filename

进入/home/xiaotanke/fastdfs/storage/files/00/00,就会发现rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt这个文件,这就上传成功了。

测试下载

fdfs_test /etc/fdfs/client.conf group1 M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt
# group1是组名
# M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435.txt 是文件的磁盘访问路径

测试删除

fdfs_test /etc/fdfs/client.conf delete group1 M00/00/00/rBE6PmI5KY-ATAMgAAAAJHqkGyw435_big.txt
# 与下载类似

5、配置NginxFastDFS的 HTTP 访问

安装nginx

wget http://nginx.org/download/nginx-1.10.3.tar.gz # 安装命令
tar -zxvf nginx-1.10.3.tar.gz # 解压

安装fastDFS-Nginx-module这个扩展模块

wget http://jaist.dl.sourceforge.net/project/fastdfs/FastDFS%20Nginx%20Module%20Source%20Code/fastdfs-nginx-module_v1.16.tar.gz  # 下载扩展模块
tar -zxvf fastdfs-nginx-module_v1.16.tar.gz # 解压

配置nginx

# 进入到解压后的fastdfs-nginx-module的src目录下,并记录下这个src的目录位置 /etc/soft/fastdfs-nginx-module/src
# 然后进入自己的nginx目录,使用下面这个命令
./configure --prefix=/usr/local/nginx_fdfs --add-module=/etc/soft/fastdfs-nginx-module/src
# /usr/local/nginx_fdfs是扩展模块存放的位置
make # 编译
# 如果在make时出现 fatal error: fdfs_define.h: No such file or directory这个错误
# 需要修改fastdfs-nginx-module-1.20/src/config文件,在从1处重新配置
# ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
# CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
make install # 安装

安装完成后,可以在 /usr/local这个目录下看见 nginx-fdfs,这样就安装成功了。

配置Nginx-fdfs

# 扩展包的配置,将扩展包下的src下的 mod_fastdfs.conf 拷贝到 /etc/fdf目录下
mv mod_fastdfs.conf /etc/fdfs
# 然后进行下面的配置
# 配置tracker的地址
tracker_server=xx.xx.xx.xx:22122
# 默认是false,需要改为true
url_have_group_name = true
# 磁盘数目,必须和storage.conf中的磁盘数目一样
store_path_count=1
# 文件存储位置
store_path0=/home/xiaotanke/fastdfs/storage/files# 配置nginx_fdfs,配置nginx_fdfs中的conf目录中,编辑nginx.conf这个文件server {listen       80;server_name  localhost;location / {root   html;index  index.html index.htm;}# 就增加这一个配置就可以了location ~ /group[1-9]/M0[0-9]{ngx_fastdfs_module;} 。。。
}

启动nginx-fdfs

/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 # 启动服务器
ps -ef | grep nginx # 查看nginx的服务进程

== 如果出现错误,就查看 nginx_fdfs这个目录下的日志文件,进行错误的检查。==

测试

如果前面的配置都没有问题,就可以通过之前上传文件 fastdfs 返回的 url进行 http 访问。http://xx.xx.xx.xx/group1/M00/00/00/rBE6PmI5vGeAfz4zAABsPFBxCKc33.docx,下面就是在下载文件。

6、FastDFS 扩展模块执行流程

## 7、java实现文件上传、下载、删除

导入依赖

由于在maven中央仓库中没有fastdfs的依赖,我们使用别人的替代依赖。

<dependency><groupId>net.oschina.zcx7878</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27.0.0</version>
</dependency>

编写配置文件:在resources目录下创建fdfs_client.conf文件

connect_timeout = 2
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 9001
# http.anti_steal_token = no
# http.secret_key = FastDFS1234567890
# tracker的ip地址和端口号
tracker_server = xx.xx.xx.xx:222122connection_pool.enabled = true
connection_pool.max_count_per_entry = 500
connection_pool.max_idle_time = 3600
connection_pool.max_wait_time_in_ms = 1000

文件上传

package com.xiaotanke;import org.csource.common.MyException;
import org.csource.fastdfs.*;
import java.io.IOException;/*** @author tanKe* Date on 2022/3/26  16:01*/
public class FastDFSUtil {private static TrackerClient trackerClient = null;private static TrackerServer trackerServer = null;private static StorageClient storageClient = null;private static StorageServer storageServer = null;// 初始化static {// 将配置文件的tracker地址读取到内存中try {ClientGlobal.init("fdfs_client.conf");trackerClient = new TrackerClient();trackerServer = trackerClient.getConnection();storageServer = trackerClient.getStoreStorage(trackerServer);storageClient = new StorageClient(trackerServer,storageServer);} catch (IOException | MyException e) {e.printStackTrace();}}/*** FastDFS 文件上传测试*/public static void upload() throws MyException, IOException {// 本地文件上传方法// 参数1:文件路径;参数2:文件扩建名;参数3:文件属性,通常不上传// 路径必须是一个绝对路径String[] result = storageClient.upload_file("e:/favicon.png", "png", null);// 返回值是一个数组,一个存在两个值// 第一个值是上传后的组名// 第二个值是上传后的文件存储路径System.out.println(result[0]);System.out.println(result[1]);}
}

文件下载:前面初始化内容不变

/*** 文件下载测试* @param groupName 文件组名* @param filePath 文件存储路径* @param fileName 文件保存名称*/
public static Integer download(String groupName,String filePath,String fileName) throws MyException, IOException {// 返回结果是0表示下载成功,如果不是0而是其它值就表示下载失败return storageClient.download_file(groupName, filePath, fileName);
}
try {Integer result = FastDFSUtil.download("group1", "M00/00/00/rBE6PmI-196AbE6BAAAWUYjKqeY490.png", "test.png");if (result==0){System.out.println("文件下载成功");}else{System.out.println("文件下载失败");}
} catch (MyException | IOException e) {e.printStackTrace();
}

文件删除:初始化不变

/*** 删除文件测试* @param groupName 组名* @param filePath 文件存储路径*/
public static Integer delete(String groupName,String filePath) throws MyException, IOException {// 返回值为0则表示删除成功,返回值为1表示删除失败return storageClient.delete_file(groupName,filePath);
}
try {Integer result = FastDFSUtil.delete("group1", "M00/00/00/rBE6PmI-0wCAIJTEAAAWUYjKqeY103.png");if (result==0){System.out.println("文件删除成功");}else{System.out.println("文件删除失败");}
} catch (MyException | IOException e) {e.printStackTrace();
}

8、java-web实现FastDFS文件上传

导入依赖

<dependency><groupId>net.oschina.zcx7878</groupId><artifactId>fastdfs-client-java</artifactId><version>1.27.0.0</version>
</dependency>

编写配置文件

编写工具类

package com.xiaotanke.util;import org.csource.common.MyException;
import org.csource.fastdfs.*;
import java.io.IOException;/*** @author tanKe* Date on 2022/3/26  16:01*/
public class FastDFSUtil {private static StorageClient storageClient = null;// 初始化static {// 将配置文件的tracker地址读取到内存中try {ClientGlobal.init("fdfs_client.conf");TrackerClient trackerClient = new TrackerClient();TrackerServer trackerServer = trackerClient.getConnection();StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);storageClient = new StorageClient(trackerServer, storageServer);} catch (IOException | MyException e) {e.printStackTrace();}}/*** FastDFS 文件上传测试*/public static String[] upload(byte[] fileByte,String fileExtendName) throws MyException, IOException {// 本地文件上传方法// 参数1:文件字节数组;参数2:文件扩建名;参数3:文件属性,通常不上传// web上传文件通常是通过字节的方式来上传return storageClient.upload_file(fileByte,fileExtendName,null);// 返回值是一个数组,一个存在两个值// 第一个值是上传后的组名// 第二个值是上传后的文件存储路径}/*** 文件下载测试* @param groupName 文件组名* @param filePath 文件存储路径* @param fileName 文件保存名称*/public static Integer download(String groupName,String filePath,String fileName) throws MyException, IOException {// 返回结果是0表示下载成功,如果不是0而是其它值就表示下载失败return storageClient.download_file(groupName, filePath, fileName);}/*** 删除文件测试* @param groupName 组名* @param filePath 文件存储路径*/public static Integer delete(String groupName,String filePath) throws MyException, IOException {// 返回值为0则表示删除成功,返回值为1表示删除失败return storageClient.delete_file(groupName,filePath);}
}

编写控制器

package com.xiaotanke.controller;import com.xiaotanke.util.FastDFSUtil;
import org.csource.common.MyException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.multipart.MultipartFile;import java.io.IOException;/*** @author tanKe* Date on 2022/3/26  19:28*/
@Controller
public class FastDFSWeb {@PostMapping("/upload")public String upload(@RequestParam("myFile") MultipartFile multipartFile){if (multipartFile==null){return "fail";}String fileName = multipartFile.getOriginalFilename();System.out.println(fileName);if (ObjectUtils.isEmpty(fileName)){return "fail";}int index = fileName.lastIndexOf(".");String type = fileName.substring(index);String[] result = null;try {result = FastDFSUtil.upload(multipartFile.getBytes(), type);} catch (MyException | IOException e) {e.printStackTrace();return "fail";}if (result==null){return "fail";}return "success";}
}

前端页面

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>测试页面</title>
</head>
<body>
<form action="http://127.0.0.1:8080/upload" method="post" enctype="multipart/form-data"><input type="file" name="myFile"/><input type="submit" value="上传文件">
</form>
</body>
</html>

FastDFS实战笔记相关推荐

  1. [转载]秀脱linux实战笔记linux-kernel-3.0.3实战篇

    +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 秀脱linux实战笔记linux-kernel-3.0.3实战片篇: QQ:     6 ...

  2. 机器学习实战笔记(Python实现)-04-Logistic回归

    转自:机器学习实战笔记(Python实现)-04-Logistic回归 转自:简单多元线性回归(梯度下降算法与矩阵法) 转自:人工神经网络(从原理到代码) Step 01 感知器 梯度下降

  3. Unity3D项目实战笔记(10):Unity3D编译IPA的PostEvents–节约时间利器

    最近,SDK支付等接入差不多了,就从Unity3D生成IPA (企业版License), 然,需要手动执行的PostEvents竟然多大10项+, 这些我默默的承受了1周时间,每次约浪费20分钟-额外 ...

  4. 云炬Qtpy5开发与实战笔记 2PyCharm添加QTDesinger扩展并创建第一个.ui文件

    1.配置使用QTDesigner扩展工具 在pycharm的项目配置中配置扩展工具,将QTDesigner加入其中: 2.在pycharm中打开QTDesigner 或者: 此时,我们就可以使用QTD ...

  5. 云炬Qtpy5开发与实战笔记 1开发第一个桌面应用Hello World

    云炬Qtpy5开发与实战笔记 0搭建开发环境(傻瓜式安装) 1.打开 Pycharm,选择 Create New Project,创建一个新项目 2.选择Pure Python表示创建一个纯Pytho ...

  6. mysql颠覆实战笔记(五)--商品系统设计(二):定时更新商品总点击量

    继续回到沈老师的MYSQL颠覆实战,首先回顾下上一节课的内容,请大家会看下上节课写的存储过程. 打开prod_clicklog表, 我们只要把日期(不含时分秒)的部分存在数据库中, 如果同一日期有相同 ...

  7. kaggle实战笔记_1.数据处理

    kaggle实战笔记_1.数据处理 数据处理的重要性比模型更重要 如果正负样本是1:100的话,直接拿去做建模,问题是非常大的,如果其评判标准为accuracy的话,如果把任何一个样本都判定为负样本的 ...

  8. 设置gradle远程仓库_有幸得到Alibaba内部Gradle实战笔记,趁双节来狂补

    Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具.它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,目前也增加了基于Kotlin语言的k ...

  9. tshark/wireshark/tcpdump实战笔记(更新中...)

    注意Wireshark表示意义: Source: 发送方IP Destination: 接收方IP Protoco: 协议 Length: 这里显示的物理层(Frame)数据长度,Frame层长度最长 ...

最新文章

  1. msclass 文字滚动_文字无缝循环滚动(标题向上滚动)
  2. 深入tornado中的IOStream
  3. 9.6-OOP语言 对接口和抽象类的理解
  4. mqtt 之 last will(遗愿)
  5. linux网络管理技术,linux网络管理 一
  6. OpenCV 坎尼边缘检测器Canny Edge Detector
  7. jOOQ类型安全数据库查询教程
  8. JavaScript中的位置协议属性
  9. codeforces 1039B Subway Pursuit【二分+随机】
  10. 玩转LiteOS组件:玩转Librws
  11. seaborn绘制概率密度图
  12. python 生成器装饰器_七.python迭代器生成器装饰器
  13. Android7.1开机启动wifi adb
  14. ​30 岁了,依然一事无成
  15. DL_C1_week4_2(build a deep neural network 2)
  16. AdventNet 系列软件license
  17. windowsXP sp3 升级包
  18. Redis云管理平台CacheCloud
  19. 卡耐基梅隆大学计算机金融专业,卡内基梅隆大学硕士费用 - 卡耐基梅隆大学计算机金融MS研究生接不接受gre成绩?不?...
  20. 2020年全新Java学习路线图,含配套视频,学完即为中级Java程序员!!(转载)

热门文章

  1. cpu负载很高而使用率很低的缘故
  2. 6天的假期开始!但是,我还剩36.5天的年假!
  3. vue单页面应用和多页面应用
  4. 机器学习中的端到端学习(End-to-End Learning)
  5. C++中strtol函数的使用方法
  6. PI调节器与无差拍电流预测控制器性能对比
  7. wds - 第一个实验——点亮LED
  8. Codeup墓地-2117
  9. 重构-改善既有代码的设计+
  10. SQL Server导入.mdf文件及显示附加数据库时出错问题处理