前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >【FastDFS】一文学会一个分布式文件系统!

【FastDFS】一文学会一个分布式文件系统!

作者头像
行百里er
发布2022-11-22 16:36:24
3010
发布2022-11-22 16:36:24
举报
文章被收录于专栏:JavaJourneyJavaJourney

1FastDFS

使用背景

在引入分布式文件存储之前,在哪个项目中上传的图片就存储到哪个项目所在的服务器。其他项目模块可以通过 HTTP请求 获取图片。

比如 ServiceA 存储了图片 a.jpg ,而 serviceB 由于业务逻辑上的需要而使用到 serviceA 上的这个图片,那么可以通过访问 http://servicea/a.jpg 的方式获取到该图片。

同理,如果需要使用到另外一个服务模块 ServiceC 的图片,也可以通过 HTTP请求 的方式获取。

不同服务之间访问图片

这样做虽然可以实现不同模块之间图片的访问,但是其问题是显而易见的,比如:

  • 图片存储过于分散
  • 图片多的服务器压力比较大,可能会影响其他功能
  • 如果图片存储到项目路径中,则重启项目时图片文件会丢失;如果存储到项目之外的磁盘中,I/O操作性能低

如何解决这一问题呢?拆解! 将图片部分拆出来专门放到一个图片服务器上,谁用谁取就行了。

每个服务模块操作图片不会相互影响

想要搭建这样一个图片存储的服务器,就需要用到对应的图片存储技术或者工具。FastDFS 应运而生!

分布式文件系统

当然,要实现图片(视频文件、音频文件、文档等均可)单独存储的服务并非只有FastDFS,FastDFS只是分布式文件系统的其中一个选择。下面来看一下它有哪些分类。

通用分布式文件系统

和传统的本地文件系统(如ext3、NTFS等)相对应。其典型代表:lustreMooseFS

该类文件系统的优点是标准的文件系统操作方式,对开发者门槛较低;系统复杂性较高,需要支持若干标准的文件操作,如:目录结构、文件读写权限、文件锁等。

由于其复杂性更高,系统整体性能有所降低,因为要支持 POSIX标准(Portable Operating System Interface of UNIX,可移植操作系统接口),POSIX标准 定义了操作系统应该为应用程序提供的接口标准。

专用分布式文件系统

基于 Google File System 的思想,文件上传后不能修改。需要使用专有API对文件进行访问,也可称作分布式文件存储服务。

典型代表:MogileFSFastDFSTFS

该类文件系统复杂性较低,不需要支持若干标准的文件操作,如:目录结构、文件读写权限、文件锁等,系统比较简洁。

因为无需支持POSIX标准,可以省去支持POSIX引入的环节,系统更加高效。

FastDFS

FastDFS 是一个 轻量级的开源分布式文件系统

它主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。

实现了软件方式的磁盘阵列(Redundant Arrays of Independent Drives,RAID),可以使用廉价的IDE(Integrated Drive Electronics)硬盘进行存储,并且支持存储服务器在线扩容。

FastDFS 的相关知识可在 ChinaUnix 论坛的 FastDFS 板块进行查看,论坛地址:http://bbs.chinaunix.net/

FastDFS相关论坛

FastDFS系统架构

FastDFS系统架构图

FastDFS 系统架构中的角色:

  • Client :客户端,这个比较好理解,就是上传下载图片的那一端,使用者。
  • Tracker Server :跟踪服务器,主要做 调度 工作,在访问上起 负载均衡 的作用。在内存中记录集群中Group和Storage Server的状态信息,是连接Client和Storage server的枢纽
  • Storage Server:存储服务器,文件和文件属性(meta data)都保存到存储服务器上。

在FastDFS系统架构中,所有的服务器都是对等的,不存在Master-Slave关系。

Storage Server 存储服务器采用 分组 方式,同组内存储服务器上的文件完全相同(RAID 1);不同组的Storage Server之间不会相互通信

Storage Server主动向Tracker Server报告状态信息,Tracker Server之间也不会相互通信。

也就是说Tracker Server1获取的存储服务器信息,Tracker Server2并不知道,他们之间不相互通信。

安装FastDFS

FastDFS 是由C语言编写的,所以在安装时服务器上需要有安装编译所需要的依赖,比如 make , cmakegcc 等。 基础文件安装好之后,再配置Tracker服务和Storage服务,这两个可以不在同一台服务器上。这里为了方便,我将Tracker和Storage配置在同一台服务器上。 有需要安装文件资料的可以关注我的微信公众号:行百里er,回复 DFS 即可获取。 下面开始安装。

1. 安装FastDFS依赖
代码语言:javascript
复制
yum install -y make cmake gcc gcc-c++
2. 上传并解压libfastcommon-master

libfastcommon 是从 FastDFSFastDHT 中提取出来的公共C函数库。

libfastcommon-master.zip 文件上传至 /usr/local/tmp 并解压:

代码语言:javascript
复制
# 解压zip文件
unzip libfastcommon-master.zip

解压libfastcommon

3. 编译并安装fastcommon

libfastcommon没有提供make命令安装文件。他提供了shell脚本可以直接进行编译和安装。shell脚本为 make.sh

fastcommon文件目录

代码语言:javascript
复制
# 进入libfastcommon-master
cd libfastcommon-master
# 编译
./make.sh
# 安装
./make.sh install

fastcommon安装过程

从上图可以看到,安装过程中创建了 /usr/lib64/usr/include/fastcommon 目录,这两个目录就是fastcommon的默认安装位置。

4. 创建fastcommon软链接

FastDFS 主程序设置的lib目录是 /usr/local/lib, 所以需要为fastcommon创建软连接,方便操作(相当于创建快捷方式)。

代码语言:javascript
复制
# 分别执行如下命令
ln -s /user/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
ln -s /usr/local/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
5. 安装FastDFS主程序

FastDFS_v5.08.tar.gz 上传到 /usr/local/tmp 下并解压。编译、安装的方法和安装fastcommon是一个套路。

代码语言:javascript
复制
cd /usr/loca/tmp
# 解压FastDFS_v5.08.tar.gz
tar zxf FastDFS_v5.08.tar.gz
# 进入解压后的FastDFS目录
cd FastDFS
# 编译
./make.sh
# 安装
./make.sh install

FastDFS安装过程

同样,该过程也创建了几个目录:

  • /usr/bin: 可执行文件所在的位置
  • /etc/fdfs: 配置文件所在的位置
  • /usr/bin: 主程序代码所在位置
  • /usr/include/fastdfs: 一些插件组所在的位置
6. 配置Tracker服务
代码语言:javascript
复制
# 进入配置文件目录
cd /etc/fdfs
# 把tracker配置文件复制一份
cp tracker.conf.sample tracker.conf
# 创建放置 tracker数据的目录
mkdir -p /usr/local/fastdfs/tracker
# 修改 tracker.conf 设置 tracker 内容存储目录
vi tracker.conf
base_path=/usr/local/fastdfs/tracker
port=22122

启动Tracker服务:

执行 service fdfs_trackerd start

代码语言:javascript
复制
# service fdfs_trackerd start
Reloading systemd:                                         [  OK  ]
Starting fdfs_trackerd (via systemctl):                    [  OK  ]

启动成功后,tracker数据目录自动创建了两个目录:data和logs。

tracker服务目录

7. 配置Storage

Tips: Storage和Tracker可以不在同一台服务器中,这里安装在同一台服务器中。

代码语言:javascript
复制
cd /etc/fdfs
# 复制Storage配置文件,storage.conf配置文件用来描述存储服务的行为
cp storage.conf.sample storage.conf
# 创建base目录,用于存储基础数据和日志
mkdir -p /usr/local/fastdfs/storage/base
# 创建store目录,用于存储上传的数据
mkdir -p /usr/local/fastdfs/storage/store
# 修改相关配置
vi storage.conf
base_path=/usr/local/fastdfs/storage/base
store_path0=/usr/local/fastdfs/storage/store
tracker_server=192.168.242.112:22122

关于这几项配置的说明:

  • base_path: 基础路径。用于保存storage server 基础数据内容和日志内容的目录。
  • store_path0: 存储路径。是用于保存FastDFS中存储文件的目录,就是要创建256*256个子目录的位置(后面通过演示可以看到创建出来的目录)。
  • tracker_server: 跟踪服务器,就是跟踪服务器的IP和端口。

启动Storage服务:

代码语言:javascript
复制
service fdfs_storaged start

启动成功后,配置文件中base_path指向的目录中出现FastDFS服务相关数据目录(data目录、logs目录);

配置文件中的store_path0指向的目录中同样出现FastDFS存储相关数据录(data目录)。

其中$store_path0/data/目录中默认创建若干子孙目录(两级目录层级总计256*256个目录),是用于存储具体文件数据的。

Storage 服务器启动比较慢,因为第一次启动的时候,需要创建256*256个目录。

启动Storage服务

代码实现FastDFS的文件上传下载

完整代码仓库:https://github.com/xblzer/JavaJourney/tree/master/code/fastdfs

创建Maven项目,添加fastdfs-java-client依赖
代码语言:javascript
复制
<dependency>
    <groupId>cn.bestwu</groupId>
    <artifactId>fastdfs-client-java</artifactId>
    <version>1.27</version>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-lang3</artifactId>
    <version>3.4</version>
</dependency>
添加配置文件

在资源文件目录下创建文件 fdfs_client.conf ,文件内容如下:

代码语言:javascript
复制
connect_timeout = 10
network_timeout = 30
charset = UTF-8
http.tracker_http_port = 8080
tracker_server = 192.168.242.112:22122  

其中的tracker_server就是安装fastdfs时配置的tracker服务的IP地址和端口。

上传文件
Code

上传文件代码:

代码语言:javascript
复制
/**
  * 上传文件
  * @param file 文件
  * @param fileName 文件名
  * @return 返回一个数组,第一个元素是组名称,第二个元素是图片名称
  */
public static String[] uploadFile(File file, String fileName) {
    FileInputStream fis = null;
    try {
        fis = new FileInputStream(file);
        int len = fis.available();
        byte[] fileBuff = new byte[len];
        fis.read(fileBuff);

        return storageClient.upload_file(fileBuff, getFileExt(fileName), null);
    } catch (Exception e) {
        e.printStackTrace();
        return null;
    } finally {
        if (fis != null) {
            try {
                fis.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

测试一下:

代码语言:javascript
复制
public static void main(String[] args) {
    File file = new File("D:/apptest/test.jpg");
    String fileName = "test.jpg";
    String[] uploadResult = uploadFile(file, fileName);
    System.out.println(Arrays.toString(uploadResult));
}

执行结果:

测试上传

FastDFS文件上传执行流程
  1. 客户端访问Tracker
  2. Tracker获取Storage的信息并返回
  3. 客户端拿到Storage的信息,将文件内容和元数据发送过去
  4. Storage返回文件存储id,格式是数组,其内容包含组名和文件名

Storage返回

FastDFS文件上传时序图:

文件上传时序图

下载文件
Code

下载文件部分代码:

代码语言:javascript
复制
/**
  * 文件下载
  * @param groupName 组名
  * @param remoteFileName 文件名
  * @return 返回一个流
  */
public static InputStream downloadFile(String groupName, String remoteFileName) {
    try {
        byte[] bytes = storageClient.download_file(groupName, remoteFileName);
        return new ByteArrayInputStream(bytes);
    } catch (Exception ex) {
        return null;
    }
}

测试代码:

代码语言:javascript
复制
// 下载
try {
    // 上传时有个返回结果包含group和文件磁盘及文件名信息
    InputStream is = downloadFile("group1", "M00/00/00/wKjycGK25DSAM3pvAAGQJOaIBGg984.jpg");
    OutputStream os = new FileOutputStream("D:/fastdfs.png");
    int index;
    while((index = is.read())!=-1){
        os.write(index);
    }
    os.flush();
    os.close();
    is.close();
} catch (IOException e) {
    e.printStackTrace();
}
FastDFS文件下载执行流程
  1. client询问tracker下载文件的storage,参数为文件标识(组名和文件名);
  2. tracker返回一台可用的storage;
  3. client直接和storage通讯完成文件下载。

FastDFS文件下载时序图

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 行百里er 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1FastDFS
    • 使用背景
      • 分布式文件系统
        • 通用分布式文件系统
        • 专用分布式文件系统
      • FastDFS
        • FastDFS系统架构
        • 安装FastDFS
      • 代码实现FastDFS的文件上传下载
        • 创建Maven项目,添加fastdfs-java-client依赖
        • 添加配置文件
        • 上传文件
        • 下载文件
    相关产品与服务
    文件存储
    文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档