FDFS基于docker安装-原理-代码示例

注意:该文章是我踩过很多坑以后结合其他总结出来的,如果你是初学者,建议耐心细读。

简介

FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。

FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)。

安装

先拉取镜像

docker pull delron/fastdfs

备注:也可以直接创建容器时拉取,但实测中发现这种方式很容易出问题

1:tracker安装

# tracker默认使用22122端口提供storage的注册和对外提供访问
docker run -d --name tracker -p 22122:22122 -v /home/besttop/data/fdfs:/var/fdfs delron/fastdfs tracker

备注:启动该服务后,一定要确认当前服务器的端口是否已经开放,否则storage无法访问。默认22122端口
特别注意:即使在同一个服务器上,storage通过ip访问tracker时也会经过防火墙过滤,所以必须开放端口。

#如果防火墙没有开启则忽略
#防火墙必须开启tracker端的端口
firewall-cmd --zone=public --add-port=22122/tcp --permanent
#防火墙添加端口后重载
firewall-cmd --reload

2:storage安装

#storage端   其中tracker_ip表示tracker端所在的ip地址,记得修改
docker run -d --network=host --name storage -e TRACKER_SERVER=tracker_ip:22122 -v /home/besttop/data/fdfs:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage

备注:

  • 客户端上传文件时,首先跟tracker交互获取storage的ip和端口后,将文件直接发给storage进行上传,tracker只提供基础信息,并不参与上传,因此要保证storage上传端口对外开放。默认上传端口为23000。
  • 客户端下载文件时,根据文件地址从tracker上获取storage的ip和端口等信息,直接从storage下载文件,tracker只提供基础信息,因此要保证storage下载端口对外开。默认下载端口为8888。
  • storage用到了网络host,表示该容器和主机公用一个网络栈,共享主机ip和端口。如果不用host,那么storage在向tracker注册的时候取的是容器中docker分配的ip,此时通过docker网络以外的客户端访问时,就连接不到storage。
  • 你可能注意到,storage对外开放了多个端口,但是storage容器并没有做端口映射,而客户端还可以访问,这是因为使用host网络共享主机网络栈时,该容器共享了主机的端口,所以不需要做端口映射。
#如果防火墙没有开启则忽略

#防火墙必须开启storage上传端口
firewall-cmd --zone=public --add-port=23000/tcp --permanent

#防火墙必须开启storage下载端口
firewall-cmd --zone=public --add-port=8888/tcp --permanent

#防火墙添加端口后重载
firewall-cmd --reload

文件访问

假设tracker和storage已经安装完成,且通过下方的示例代码测试通过(最好用图片测试),上传的文件地址假定为group1/M00/00/00/wKjG7Vz-RKWAICpaAAA6TVDwpMY220.gif 此时可以通过浏览器直接访问 http://tracker_ip:8888/group1/M00/00/00/wKjG7Vz-RKWAICpaAAA6TVDwpMY220.gif
特别注意:访问地址中的tracker_ip是tracker所在的ip,记得修改

fdfs原理详解

fdfs只有两个角色,tracker server和storage server,不需要存储文件索引信息,所有服务器都是对等的,不存在Master-Slave关系 。存储服务器采用分组方式,同组内存储服务器上的文件完全相同(RAID1)不同组的storage server之间不会相互通信 。由storage server定时主动向tracker server报告状态信息,tracker server之间通常不会相互通信。

文件传输机制

FastDFS系统中客户端上传文件流程:
  • client询问tracker上传到的storage
  • tracker返回一台可用的storage
  • client直接和storage通信完成文件上传,storage返回文件ID给客户端。
FastDFS系统中客户端下载文件流程:
  • client询问tracker下载文件的storage,参数为文件组名和文件名
  • tracker去storage查询访问的数据资源位置,将存储该资源的storage信息及文件位置信息返回给client
  • client直接和storage通信完成文件下载
FastDFS的同步机制:

采用binlog文件记录更新操作,根据binlog进行文件同步,同一组内的storage server之间是对等的,文件上传、删除等操作可以在任意一台storage server上进行,更改的数据由发生更改的storage server(源服务器)采用push方式,向同组内的其他storage server(目标服务器)进行同步
源数据(发生更改的数据)才需要同步,备份数据(原有的同步数据)不需要再次同步,否则就构成了环路了。
对于新增加的一台storage server时,由已有的一台storage server将已有的所有的数据(包括新增的数据和备份数据)同步到新增的服务器。

FastDFS的两大核心组件

Tracker:调度器

负责维持集群的信息,例如各group及其内部的storage node,这些信息也是storage node报告所生成的,每个storage node会周期性向tracker发心跳信息,让tracker知道自己还正常运行

Storage server:

以group为单位进行组织,任何一个storage server都应该属于某个group,一个group应该包含多个storage server,在同一个group内,各storage server的数据相互冗余。在同一组内storage节点之间的数据是相同的。

代码示例

pom.xml文件引入

     net.oschina.zcx7878
     fastdfs-client-java
     1.27.0.0

import org.csource.common.NameValuePair;
import org.csource.fastdfs.*;

public class FastDFSClient {

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

    public static void main(String[] args) throws Exception {
    	// 在resources目录下创建配置文件client.conf
    	// 配置文件中添加一行配置,ip是tracker所在服务器地址, tracker_server=192.168.198.237:22122
        FastDFSClient fastDFSClient = new FastDFSClient("client.conf");
        // 取本地文件绝对路径
        String path = fastDFSClient.uploadFile("C:\\Users\\wbt16\\Documents\\WeChat Files\\dreamwbt" +
                "\\FileStorage\\File\\2019-06\\b146d676fa8764ae098534dfc36a3418_t.gif");
        System.out.println(path);
    }

    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);
    }

    /**
     * 上传文件方法
     * 

Title: uploadFile

*

Description:

* * @param fileName 文件全路径 * @param extName 文件扩展名,不包含(.) * @param metas 文件扩展信息 * @return * @throws Exception */ public String uploadFile(String fileName, String extName, NameValuePair[] metas) throws Exception { String result = storageClient.upload_file1(fileName, extName, metas); return result; } public String uploadFile(String fileName) throws Exception { return uploadFile(fileName, null, null); } public String uploadFile(String fileName, String extName) throws Exception { return uploadFile(fileName, extName, null); } /** * 上传文件方法 *

Title: uploadFile

*

Description:

* * @param fileContent 文件的内容,字节数组 * @param extName 文件扩展名 * @param metas 文件扩展信息 * @return * @throws Exception */ public String uploadFile(byte[] fileContent, String extName, NameValuePair[] metas) throws Exception { String result = storageClient.upload_file1(fileContent, extName, metas); return result; } public String uploadFile(byte[] fileContent) throws Exception { return uploadFile(fileContent, null, null); } public String uploadFile(byte[] fileContent, String extName) throws Exception { return uploadFile(fileContent, extName, null); }

你可能感兴趣的:(FDFS)