当前位置: 代码迷 >> 综合 >> 文件服务器之分布式文件存储系统(fastdfs)
  详细解决方案

文件服务器之分布式文件存储系统(fastdfs)

热度:15   发布时间:2023-12-18 17:40:52.0

1、分布式文件存储系统

上传图片,由于有多台服务器,所以不能找到图片在哪台服务器上面,这时就需要一个文件服务器进行管理图片。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gnnnI9Sn-1585211003406)(assets/1584107074588.png)]

FastDFS就是一个文件服务器。

2、FastDFS

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kqxVUROV-1585211003408)(assets/1584855017183.png)]

1 支持上传-> 给我们返回一个路径

2 支持下载-> 使用路径下载

小文件分布式文件的存储系统

小于1 个G的文件都是小文件,就可以不用拆分该文件

大文件需要拆分。

FastDFS 就是一个分布式文件存储系统,由两部分组成。

1 tracker(跟踪器)

2 storage(存储器)

如果想扩充FastDFS的容量,非常方便,直接添加组就行了

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KvsPRBdO-1585211003425)(assets/1584107517026.png)]

3、FastDFS的搭建

3.1、在服务器中创建FastDFS的容器

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s7sigUDQ-1585211003426)(assets/1584846243919.png)]

3.1.1、准备一个tracker

docker run -d --name tracker --net=host morunchang/fastdfs sh tracker.sh

3.1.2、准备一个storage

1 公网地址 : 开发时,使用公网

2 私网地址: 服务上线,使用私网

docker run -d --name storage --net=host -e TRACKER_IP=服务器公网:22122 -e GROUP_NAME=g1 morunchang/fastdfs sh storage.sh

可以使用docker logs 容器名称命令进行查看容器是否运行成功。

位于同一组的storage中的文件会进行备份。

位于不同组可以使用负载均衡。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cFrePqTe-1585211003427)(assets/1584108715256.png)]

3.2、添加项目依赖

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-b43sjZka-1585211003429)(assets/1584873611084.png)]

<!--spring boot项目导入的依赖-->
<dependency><groupId>com.github.tobato</groupId><artifactId>fastdfs-client</artifactId><version>1.26.7</version>
</dependency>
<!--测试类依赖-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope>
</dependency>

3.3、yml配置文件

fdfs:tracker-list:            #TrackerList参数,支持多个- 192.168.1.105:22122- 192.168.1.106:22122 

3.4、测试fastdfs的操作

package com.zxm.test;import com.github.tobato.fastdfs.domain.fdfs.StorageNode;
import com.github.tobato.fastdfs.domain.fdfs.StorageNodeInfo;
import com.github.tobato.fastdfs.domain.proto.storage.DownloadFileWriter;
import com.github.tobato.fastdfs.service.FastFileStorageClient;
import com.github.tobato.fastdfs.service.TrackerClient;
import com.zxm.utils.FastdfsUtil;
import lombok.SneakyThrows;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;import java.io.File;
import java.io.FileInputStream;
import java.util.HashSet;@SpringBootTest
@RunWith(SpringRunner.class)
public class FileUploadTest {
    @Autowiredprivate FastFileStorageClient fastFileStorageClient;@Autowiredprivate TrackerClient trackerClient;/*** 文件的上传*/@SneakyThrows@Testpublic void updateLoadTest(){
    // 也可以上传视频。只需要填入视频路径,然后将fileExtName换为视频的后缀就行。File file = new File("C:/Users/86131/Pictures/Saved Pictures/1.jpg");String path = fastFileStorageClient.uploadFile(new FileInputStream(file),file.length(),"jpg",new HashSet<>(0)).getFullPath();System.out.println(path);}/*** 文件的下载*/@Testpublic void testDownload(){
    String path = "C:/Users/86131/Desktop/临时文件夹/d2.jpg";fastFileStorageClient.downloadFile("g1","M00/00/00/rBHR8l5h-T6AQTubAApSuL6VXKQ831.jpg", new DownloadFileWriter(path));}/*** 文件的删除* 删除之后,还可以访问,但是不能下载了。*/@Testpublic void testDelete(){
    String fullPath = "g1/M00/00/00/rBHR8l5nSzeAS0pmAAVS7KokxMQ062.jpg";String groupName = FastdfsUtil.parseGroup(fullPath);System.out.println(groupName);String path = fullPath.replaceFirst(groupName+"/", "");System.out.println(path);fastFileStorageClient.deleteFile(groupName,path);System.out.println("删除完成");
// 或者直接使用下述方法就可删除。
// fastFileStorageClient.deleteFile("g1","M00/00/00/rBHR8l5nSzeAS0pmAAVS7KokxMQ062.jpg");}@Testpublic void trackerTest(){
    /*** 文件下载时候用到。* fetchStorage对象中包含组名,storage的服务器ip,端口*/StorageNodeInfo fetchStorage = trackerClient.getFetchStorage("g1", "M00/00/00/rBHR8l5nSzeAS0pmAAVS7KokxMQ062.jpg");/*** 文件上传时候用到* 得到当前注册到tracker上面的storege* 不同组可以使用负载均衡。*/StorageNode storeStorage = trackerClient.getStoreStorage();}}

3.5、应用fastDFS的controller

package com.zxm.controller;import com.github.tobato.fastdfs.service.FastFileStorageClient;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;/*** 负责文件上传的控制器*/
@RestController
@RequestMapping("/admin/file")
public class FileController {
    @Autowiredprivate FastFileStorageClient fastFileStorageClient;// http://47.94.225.69:8080 fastDFS自定义地址配置。// 此处使用@Value注解从yml配置文件中注入。@Value("${resources.url}")private String serverAddress; /*** 上传一个图片* @param file* @return*/@SneakyThrows@PostMapping("/upload/element")public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file){
    // 开始上传文件String fullPath = fastFileStorageClient.uploadFile(file.getInputStream(),file.getSize(),"jpg",null).getFullPath();return ResponseEntity.ok(serverAddress+"/"+fullPath);}
}
# fastdfs的自定义地址配置
resources:url: http://47.94.225.69:8080

4、 fastdfs的原理分析

4.1、fastDFS文件上传的流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-55GwGQnp-1585211003431)(assets/1584875740800.png)]

tracker还具有负载均衡的效果,从多个storage中选出一个进行操作。

4.2、fastDFS文件下载的流程

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TA857ey2-1585211003434)(assets/1584876101834.png)]

5、FastDFS和Nginx结合使用

5.1、对tracker做负载均衡

为了承载更高的并发量,tracker可以做成集群。需要使用nginx做负载均衡。

5.2、nginx插件fastdfs-nginx-module的作用

FastDFS通过Tracker服务器,将文件放在某个Storage服务器存储,但是同组Storage存储服务器之间需要进入文件复制,有同步延迟的问题

假设Tracker服务器将文件上传到了Storage Server 11,上传成功后文件ID已经返回给客户端。此时FastDFS存储集群机制会将这个文件同步到同组存储Storage Server 12,在文件还没有复制完成的情况下,客户端如果用这个文件ID在Storage Server 12上取文件,就会出现文件无法访问的错误。 (Storage Server 11和Storage Server 12是同一个storage组)

,但是同组Storage存储服务器之间需要进入文件复制,有同步延迟的问题

假设Tracker服务器将文件上传到了Storage Server 11,上传成功后文件ID已经返回给客户端。此时FastDFS存储集群机制会将这个文件同步到同组存储Storage Server 12,在文件还没有复制完成的情况下,客户端如果用这个文件ID在Storage Server 12上取文件,就会出现文件无法访问的错误。 (Storage Server 11和Storage Server 12是同一个storage组)

fastdfs-nginx-module可以重定向文件连接到文件上传时的源服务器(Storage Server 11)取文件,避免客户端由于复制延迟导致的文件无法访问错误 。

  相关解决方案