FastDFS

2023-11-27 14:46:44 浏览数 (1)

FastDFS

FastDFS安装与使用

下载地址

FastDFS所需软件: 链接: https://pan.baidu.com/s/15Lm9qWxmoyY1Mqz9pdCG9w 提取码: 99bg

什么是分布式文件系统

分布式文件系统解决了海量文件存储及传输访问的瓶颈问题,对海量视频的管理、对海量图片的管理等。 分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源不一定直接连接在本地节点上, 而是通过计算机网络与节点相连。

为什么会有分布文件系统

存在问题

分布式文件系统是面对互联网的需求而产生,互联网时代对海量数据如何存储? 靠简单的增加硬盘的个数已经满足 不了我们的要求,因为硬盘传输速度有限但是数据在急剧增长, 另外我们还要要做好数据备份、数据安全等。

解决办法

采用分布式文件系统可以将多个地点的文件系统通过网络连接起来 组成一个文件系统网络,结点之间通过网络进 行通信 一台文件系统的存储和传输能力有限,我们让文件在多台计算机上存储,通过多台计算共同传输 示例图

好处

一台计算机的文件系统处理能力扩充到多台计算机同时处理 一台计算机挂了还有另外副本计算机提供数据。 每台计算机可以放在不同的地域,这样用户就可以就近访问,提高访问速度

主流的分布式文件系统

  1. NFS 在客户端上映射NFS服务器的驱动器 客户端通过网络访问NFS服务器的硬盘完全透明。 结构图
  1. GFS GFS采用主从结构,一个GFS集群由一个master和大量的chunkserver组成 master存储了数据文件的元数据,一个文件被分成了若干块存储在多个chunkserver中。 用户从master中获取数据元信息,从chunkserver存储数据 结构图
  1. HDFS Hadoop分布式文件系统主要用于大数据 HDFS采用主从结构,一个HDFS集群由一个名称结点和若干数据结点组成 名称结点存储数据的元信息,一个完整的数据文件分成若干块存储在数据结点。 客户端从名称结点获取数据的元信息及数据分块的信息,得到信息客户端即可从数据块来存取数据。 结构

什么是fastDFS

简介

FastDFS是用c语言编写的一款开源的分布式文件系统,它是由淘宝资深架构师余庆编写并开源。 FastDFS专为互联 网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标, 使用FastDFS很 容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务

为什么要使用fastDFS

通用分布式文件系统 NFS、GFS都是通用的分布式文件系统 通用的分布式文件系统的优点的是开发体验好,但是系统复杂 性高、性能一般 | 专用分布式文件系统 专用的分布式文件系统虽然开发体验性差,但是系统复杂性低并且性能高。 fastDFS非常适合 存储图片等那些小文件,fastDFS不对文件进行分块, 所以它就没有分块合并的开销,fastDFS网络通信采用 socket,通信速度很快

fastDFS工作原理

FastDFS架构包括 Tracker server和Storageserver。 客户端请求Tracker server进行文件上传、下载,通过Tracker server调度最终由Storage server完成文件上传和下载。

结构图

Tracker

作用:

  1. Tracker Server作用是负载均衡和调度,
  2. 通过Tracker server在文件上传时可以根据一些策略找到Storage server提 供文件上传服务。
  3. 可以将tracker称为追踪服务器或调度服务器。

集群:

FastDFS集群中的Tracker server可以有多台 Tracker server之间是相互平等关系同时提供服务. 客户端请求Tracker server采用轮询方式,如果请求的tracker无法提供服务则换另一个tracker。

Storage

作用:

Storage Server作用是文件存储,客户端上传的文件最终存储在Storage服务器上

集群

Storage集群采用了分组存储方式。storage集群由一个或多个组构成,集群存储总容量为集群中所有组的存储容 量之和 一个组由一台或多台存储服务器组成,组内的Storage server之间是平等关系, 不同组的Storage server 之间不会相互通信 同组内的Storage server之间会相互连接进行文件同步,从而保证同组内每个storage上的文件 完全一致的 一个组的存储容量为该组内的存储服务器容量最小的那个

采用分组存储方式的好处

灵活、可控性较强。比如上传文件时,可以由客户端直接指定上传到的组也可以由 tracker进行调度选择。 一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务能力(纵向 扩容) 当系统容量不足时,可以增加组来扩充存储容量(横向扩容)。

Storage状态收集

Storage server会连接集群中所有的Tracker server,定时向他们报告自己的状态, 包括磁盘剩余空间、文件同步 状况、文件上传下载次数等统计信息。

FastDFS安装与配置

FastDFS是 C 语言开发,建议在 linux 上运行 安装 FastDFS需要先将官网下载的源码进行编译,编译依赖 gcc 环境

1. 需要安装 gcc

yum install gcc-c

2. 安装libevent

FastDFS依赖libevent库 yum -y install libevent

3.安装libfastcommon

libfastcommon 是 FastDFS 官方提供的,libfastcommon 包含了 FastDFS 运行所需要的一些基础库

  1. 将libfastcommonV1.0.7.tar.gz拷贝至/usr/local/下
  1. 解压libfastcommonV1.0.7.tar.gz tar -zxvf libfastcommonV1.0.7.tar.gz
  2. 执行以下命令 cd libfastcommon-1.0.7 ./make.sh

./make.sh install

libfastcommon安装好后会自动将库文件拷贝至/usr/lib64下 由于FastDFS程序引用usr/lib目录

所以需要将/usr/lib64下的库文件拷贝至/usr/lib下。 ll /usr/lib64/

4.安装libevent

  1. 上传 libevent到服务器中 执行以下命令
  2. 解压 tar -zxvf libevent-2.0.15-stable.tar.gz
  3. 进入 libevent目录 cd libevent-2.0.15-stable/
  4. 执行 第一步: ./configure 第二步:make && make install 第三步:ln -s /usr/local/lib/libevent-2.0.so.5 /usr/lib/libevent-2.0.so.5

5. tracker编译安装

  1. 将FastDFS_v5.05.tar.gz拷贝至/usr/local/下
  2. 解压: tar -zxvf FastDFS_v5.05.tar.gz
  3. 进入FastDFS目录 cd FastDFS
  4. 执行以下命令 ./make.sh ./make.sh install
  5. 安装成功将安装目录下的conf下的文件拷贝到/etc/fdfs/下 cp -ri conf/* /etc/fdfs
  6. 进入/etc/fdfs目录 cd /etc/fdfs
  7. 修改tracker.conf vim tracker.conf

base_path=/home/fastdfs http.server_port=80

  1. 创建目录 mkdir -p /home/fastdfs
  2. 启动 /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
  1. 查看是否启动 ps aux|grep dfs

6.进入/etc/fdfs

执行 修改配置文件 vim storage.conf

  1. group_name=group1
  2. base_path=/home/yuqing/FastDFS改为:base_path=/home/fastdfs
  3. store_path0=/home/fastdfs/fdfs_storage
  4. tracker_server=192.168.0.108:22122 #配置 tracker服务器:IP如果有多个则配置多个tracke
  5. http.server_port=80

创建文件夹: mkdir -p /home/fastdfs/fdfs_storage

启动 /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart

文件上传流程

流程图

文件信息

客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。 文件索引信息 包括:组名,虚拟磁盘路径,数据两级目录,文件名

  1. 组名: 文件上传后所在的storage组名称,在文件上传成功后有storage服务器返回,需要客户端自行保存。
  2. 虚拟磁盘路径: storage配置的虚拟路径,与磁盘选项store_path*对应。如果配置了store_path0则是M00, 如果配置了store_path1则是M01,以此类推。
  3. 数据两级目录: storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件
  4. 文件名: 是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创 建时间戳、文件大小、随机数和文件拓展名等信息

通过客户端上传图片

  1. 创建maven工程
  1. 安装fastdfs架包
代码语言:javascript复制
mvn install:install-file -DgroupId=org.csource.fastdfs -DartifactId=fastdfs -Dversion=1.2 -Dpackaging=jar -Dfile=fastdfs_client_v1.20.jar
  1. 引入依赖
代码语言:javascript复制
   <dependency>
            <groupId>org.csource.fastdfs</groupId>
            <artifactId>fastdfs</artifactId>
            <version>1.2</version>
        </dependency>
  1. 在resources当中创建fdfs_client.conf配置文件
代码语言:javascript复制
# connect timeout in seconds
# default value is 30s
connect_timeout=30

# network timeout in seconds
# default value is 30s
network_timeout=60

# the base path to store log files
base_path=/home/fastdfs

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=192.168.0.108:22122

#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false

# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600

# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf


#HTTP settings
http.tracker_server_port=80

#use "#include" directive to include HTTP other settiongs
##include http.conf
  1. 创建测试, 上传图片
代码语言:javascript复制
 public static void main(String[] args) throws Exception {
        //1. 加载配置文件
        ClientGlobal.init("src/main/resources/fdfs_client.conf");
        //2. 创建管理端对象
        TrackerClient trackerClient = new TrackerClient();
        //3. 通过管理端对象获取连接
        TrackerServer connection = trackerClient.getConnection();
        //4. 创建存储端对象
        StorageClient1 storageClient = new StorageClient1(connection, null);

        //创建文件属性信息对象数组
        NameValuePair[] meta_list = new NameValuePair[3];
        meta_list[0] = new NameValuePair("fileName","time");
        meta_list[1] = new NameValuePair("ExtName","jpg");
        meta_list[2] = new NameValuePair("zuozhe","joker");

        //5. 上传文件
        String path = storageClient.upload_file1("C:\Users\Joker_DJ\Pictures\timg.jpg", "jpg", meta_list);
        System.out.println("======"   path);
    }

启动测试

查看文件存放目录 cd /home/fastdfs/fdfs_storage/data/00/00

搭建图片服务虚拟主机

在Storage上安装nginx

在storage server上安装nginx的目的是对外通过http访问storage server 上的文件 使用 nginx 的模块 FastDFS-nginx-module 的作用是通过 http 方式访问 storage 中的文件

安装FastDFS-nginx

  1. 将 FastDFS-nginx-module_v1.16.tar.gz上到usr/local下
  2. 解压 tar -zxvf fastdfs-nginx-module_v1.16.tar.gz
  3. 进入src目录 cd fastdfs-nginx-module/src
  4. 修改config文件将/usr/local/路径改为/usr/ vim config
  1. 将FastDFS-nginx-module/src下的mod_FastDFS.conf拷贝至/etc/fdfs/下 cp mod_fastdfs.conf /etc/fdfs/
  2. 修改mod_fastdfs.conf vim /etc/fdfs/mod_fastdfs.conf

  1. base_path=/home/fastdfs
  1. tracker_server=192.168.0.108:22122
  1. url_have_group_name=true
  1. store_path0=/home/fastdfs/fdfs_storage

esc后保存并退出 :wq

  1. 将libfdfsclient.so拷贝至/usr/lib下 cp /usr/lib64/libfdfsclient.so /usr/lib/
  2. 复制 FastDFS的部分配置文件到/etc/fdfs目录 cd /usr/local/FastDFS/conf/ cp http.conf mime.types /etc/fdfs/

nginx安装

将nginx-1.8.1.tar.gz拷贝到/usr/local下

  1. 解压nginx-1.8.1.tar.gz tar -zxvf nginx-1.8.1.tar.gz
  2. 依赖包 sudo yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel
  3. 进入nginx目录 cd nginx-1.8.1/
  4. 执行配置 ./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/usr/local/fastdfs-nginx-module/src
  5. 在 nginx-1.8.1目录下依次执行 make make install useradd -s /sbin/nologin -M nginx id nginx
  6. 启动ngnix nginx
  7. 停止nginx nginx -s stop
  8. 重新加载配置 nginx -s reload
  9. 查看是否启动 ps -ef|grep nginx
  1. 修改配置文件 vim /opt/nginx/conf/nginx.conf
代码语言:javascript复制
	# 监听域名中带有group的,交给FastDFS模块处理
	        location ~/group([0-9])/ {
	            ngx_fastdfs_module;
	        }

重新加载配置 nginx -s reload

查看是否生效 在主机通过ip地址访问nginx http://192.168.0.108

启动

/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart nginx

访问上传图片的地址

http://192.168.0.108/group1/M00/00/00/wKgAbF8pL5KAUR9AAABCFe5hWE4513.jpg

云服务器访问需要开启的端口

  1. 22122
  2. 50548
  3. 55704
  4. 23000

设置FastDFS开机自启

虚拟机每次启动之后都要重新启动FastDFS和nginx,比较麻烦所以增加开机自启

在centos7 /etc/rc.d/rc.local 文件的权限被降低了,所以给rc.local文件增加可执行的权限 执行命令:chmod x /etc/rc.d/rc.local

编辑 /etc/rc.d/rc.local文件,增加启动项

  1. 编辑文件 vim /etc/rc.d/rc.local
  2. 增加文件如下 #fastdfs start /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart /usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart #nginx start /usr/local/nginx/sbin/nginx

基于SSM FastDFS vue实现图片上传

  1. 编写上传按钮事件
  1. 注意开启SpringMVC的媒体解析器
代码语言:javascript复制
 <!-- 配置多媒体解析器 -->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="defaultEncoding" value="UTF-8"></property>
        <!-- 设定文件上传的最大值5MB,5*1024*1024 -->
        <property name="maxUploadSize" value="5242880"></property>
    </bean>
  1. 引入pom文件 从本地安装
代码语言:javascript复制
  		<dependency>
            <groupId>org.csource.fastdfs</groupId>
            <artifactId>fastdfs</artifactId>
            <version>1.2</version>
        </dependency>
  1. 引入fastDFS配置文件和服务地址配置文件

application.properties

代码语言:javascript复制
FILE_SERVER_URL=http://192.168.0.108/

新建fastDFS配置文件夹

fdfs_client.conf

代码语言:javascript复制
# connect timeout in seconds
# default value is 30s
connect_timeout=30

# network timeout in seconds
# default value is 30s
network_timeout=60

# the base path to store log files
base_path=/home/fastdfs

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=192.168.0.108:22122

#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false

# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600

# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf


#HTTP settings
http.tracker_server_port=80

#use "#include" directive to include HTTP other settiongs
##include http.conf
  1. 在spring-mvc.xml加载属文件
代码语言:javascript复制
<context:property-placeholder location="classpath:config/application.properties" />
  1. 编写工具类
代码语言:javascript复制
import org.apache.commons.io.FilenameUtils;
import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

import java.io.IOException;

public class FastDFSClient {

    private TrackerClient trackerClient = null;
    private TrackerServer trackerServer = null;
    private StorageServer storageServer = null;
    private StorageClient1 storageClient = null;

    public FastDFSClient(String conf) throws Exception {
        if (conf.contains("classpath:")) {
            conf = conf.replace("classpath:", this.getClass().getResource("/").getPath());
        }
        ClientGlobal.init(conf);
        trackerClient = new TrackerClient();
        trackerServer = trackerClient.getConnection();
        storageServer = null;
        storageClient = new StorageClient1(trackerServer, storageServer);
    }

    /**
     * @param file 文件二进制
     * @param fileName 文件名
     * @param fileSize 文件大小
     * @return
     * @throws Exception
     */
    public String uploadFile(byte[] file, String fileName, long fileSize) throws Exception {
        NameValuePair[] metas = new NameValuePair[3];
        metas[0] = new NameValuePair("fileName", fileName);
        metas[1] = new NameValuePair("fileSize", String.valueOf(fileSize));
        metas[2] = new NameValuePair("fileExt", FilenameUtils.getExtension(fileName));
        String result = storageClient.upload_file1(file, FilenameUtils.getExtension(fileName), metas);
        return result;
    }

    /**
     *
     * @param storagePath  文件的全部路径 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg
     * @return -1失败,0成功
     * @throws Exception
     */
    public Integer delete_file(String storagePath){
        int result=-1;
        try {
            result = storageClient.delete_file1(storagePath);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return  result;
    }



}
  1. 在UploadController方法中上传图片
代码语言:javascript复制
@RestController
@RequestMapping("/upload")
public class UploadController {

    @Value("${FILE_SERVER_URL}")
    private String FILE_SERVER;

    @RequestMapping("/uploadFile")
    public Result uploadFile(MultipartFile file) throws Exception {
        try {
            FastDFSClient fastDFS = new FastDFSClient("classpath:fastDFS/fdfs_client.conf");
            //上传文件返回文件保存的路径和文件名
            String path = fastDFS.uploadFile(file.getBytes(), file.getOriginalFilename(), file.getSize());
            /**
             保存数据库...
             */
            //拼接上服务器的地址返回给前端
            return new Result(true, FILE_SERVER   path);
        } catch (Exception e) {
            e.printStackTrace();
            return new Result(false, "上传失败!");
        }
    }
}
  1. 删除图片
代码语言:javascript复制
    /*删除图片*/
    @RequestMapping("/delteImage")
    public Result delteImage(String url){
        try {
            String path  = url.substring(FILE_SERVER.length());
            FastDFSClient fastDFS =new FastDFSClient("classpath:fastDFS/fdfs_client.conf");
            Integer integer = fastDFS.delete_file(path);
            if (integer == 0){
                return new Result(true, "删除成功");
            }else {
                return new Result(false, "删除失败");
            }
        } catch (Exception e) {
            return new Result(false, "删除失败");
        }
    }

0 人点赞