实现分布式文件系统FastDFS

分布式文件系统

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

主流的分布式文件系统有NFS、GFS、HDSF

NFS
  • 在客户端上映射NFS服务器的驱动器
  • 客户端通过网络访问NFS服务器的硬盘完全透明
GFS
  • GFS采用主从结构,一个GFS集群由一个master和大量的chunkserver组成
  • master存储了数据文件的元数据,一个文件被分成了若干块存储在多个chunkserver中
  • 用户从master中获取数据元信息,从chunkserver存储数据

即文件分块存储在多个chunkserver服务器中,文件的记录信息在master服务器中。

HDFS
  • HDFS采用主从结构,一个HDFS集群由一个名称结点和若干数据结点组成
  • 名称结点存储数据的元信息,一个完整的数据文件分成若干块存储在数据结点
  • 客户端从名称结点获取数据的元信息及数据分块的信息,然后就可从数据块来存取数据

HDFS和GFS类似,都是将文件分块存储在多个服务节点上,由主节点记录文件信息。

FastDFS

FastDFS是用c语言编写的一款开源的分布式文件系统。FastDFS专为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。FastDFS不对文件进行分块,所以它没有分块合并的开销,很适合存储小文件。FastDFS网络通信采用socket,通信速度很快。

FastDFS架构

FastDFS架构包括 Tracker server和Storageserver。客户端请求Tracker server进行文件上传、下载,通过Trackerserver调度最终由Storage server完成文件上传和下载。
在这里插入图片描述
Tracker
Tracker Server作用是负载均衡和调度,通过Tracker server在文件上传时可以根据一些策略找到Storage server提供文件上传服务。可以将tracker称为追踪服务器或调度服务器。
Storage
Storage Server作用是文件存储,客户端上传的文件最终存储在Storage服务器上,Storage server没有实现自己的文件系统而是使用操作系统的文件系统来管理文件。可以将storage称为存储服务器。
Storage状态收集
Storage server会连接集群中所有的Tracker server,定时向他们报告自己的状态,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。

Tracker调度算法

在Tracker的配置文件tracker.conf中(稍后会安装),有三种调度策略:

# which storage server to upload file
# 0: round robin (default)
# 1: the first server order by ip address
# 2: the first server order by priority (the minimal)
  • 0表示轮询,依次轮询每个组返回给客户端上传文件
  • 1表示指定具体的组
  • 2表示负载均衡(默认),通过负载均衡算法,将当前比较空闲的storage组返回给客户端上传文件
文件上传流程

在这里插入图片描述
file_id即文件ID,用于访问文件的索引信息,文件索引信息包括:组名、虚拟磁盘路径、数据两级目录、文件名

FastDFS安装

https://www.cnblogs.com/yufeng218/p/8111961.html

注意:

  1. 在storage的配置文件中配置tracker_server时,不要用127.0.0.1,要用服务器的外网ip(如果用的是云服务器,tracker_server设置的是外网ip会导致在本服务器上测试上传会报错,没关系,因为只有设置为外网ip,才能通过windows上的java程序上传、下载图片)
  2. 同时,不要忘了开放tracker和storage监听的端口

Spring Boot项目中使用FastDFS

fastdfs的java客户端依赖包:

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

resources/config/fastdfs-client.properties配置文件:

#http连接超时时间
fastdfs.connect_timeout_in_seconds = 5
#tracker与storage网络通信超时时间
fastdfs.network_timeout_in_seconds = 30
#字符编码
fastdfs.charset = UTF-8
fastdfs.tracker_servers = tracker服务器的ip:tracker监听的端口

上传文件和下载文件测试:

@SpringBootTest
@RunWith(SpringRunner.class)
public class TestFastDFS {
    //上传文件
    @Test
    public void testUpload(){
        try {
            //加载fastdfs-client.properties配置文件
            ClientGlobal.initByProperties("config/fastdfs-client.properties");
            //定义TrackerClient,用于请求TrackerServer
            TrackerClient trackerClient = new TrackerClient();
            //连接tracker
            TrackerServer trackerServer = trackerClient.getConnection();
            //获取Stroage
            StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer);
            //创建stroageClient
            StorageClient1 storageClient1 = new StorageClient1(trackerServer,storeStorage);
            //向stroage服务器上传文件
            //本地文件的路径
            String filePath = "xxx/1.png";
            //上传成功后拿到文件Id
            String fileId = storageClient1.upload_file1(filePath, "png", null);
            System.out.println(fileId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //下载文件
    @Test
    public void testDownload(){
        try {
            //加载fastdfs-client.properties配置文件
            ClientGlobal.initByProperties("config/fastdfs-client.properties");
            //定义TrackerClient,用于请求TrackerServer
            TrackerClient trackerClient = new TrackerClient();
            //连接tracker
            TrackerServer trackerServer = trackerClient.getConnection();
            //获取Stroage
            StorageServer storeStorage = trackerClient.getStoreStorage(trackerServer);
            //创建stroageClient
            StorageClient1 storageClient1 = new StorageClient1(trackerServer,storeStorage);
            //下载文件
            //文件id
            String fileId = "testUpload打印的id";
            byte[] bytes = storageClient1.download_file1(fileId);
            //使用输出流保存文件
            FileOutputStream fileOutputStream = new FileOutputStream(new File("下载位置"));
            fileOutputStream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (MyException e) {
            e.printStackTrace();
        }
    }
}
发布了243 篇原创文章 · 获赞 87 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/IT_10/article/details/103995868