FastDFS核心概念与架构原理解析

  • 为什么要使用分布式文件系统

    • 海量文件数据存储
    • 文件数据高可用(冗余备份)
    • 读写性能和负载均衡
    • 以上3点都是我们之前使用tomcat或nginx所不能够实现的,这也是我们为什么要使用分布式文件系统的原因
  • FastDFS 与 HDFS

    • Hadoop中的文件系统HDFS主要解决并行计算中分布式存储数据的问题。其单个数据文件通常很大,采用了分块(切分)存储的方式,所以是大数据大文件存储来使用的场景
    • FastDFS主要用于互联网网站,为文件上传和下载提供在线服务。所以在负载均衡、动态扩容等方面都支持得比较好,FastDFS不会对文件进行分快存储。FastDFS用于存储中小文件都是不错的,比如用户头像啊,一些较小的音视频文件啊等等都行
  • FastDFS常见术语

    • tracker:追踪者服务器,主要用于协调调度,可以起到负载均衡的作用,记录storage的相关状态信息。
    • storage:存储服务器,用于保存文件以及文件的元数据信息。
    • group:组,同组节点提供冗余备份,不同组用于扩容。
    • mata data:文件的元数据信息,比如长宽信息,图片后缀,视频的帧数等。
  • FastDFS架构 分布式文件系统-FastDFS OSS - 图1

  • FastDFS上传过程 分布式文件系统-FastDFS OSS - 图2

  • FastDFS下载过程

分布式文件系统-FastDFS OSS - 图3

FastDFS配置

  1. -

安装libfatscommon函数库

  1. # 解压
  2. tar -zxvf libfastcommon-1.0.42.tar.gz
  1. -

进入libfastcommon文件夹,编译并且安装

  1. ./make.sh
  2. ./make.sh install
  1. -

安装fastdfs主程序文件

  1. # 解压
  2. tar -zxvf fastdfs-6.04.tar.gz


进入到fastdfs目录,查看fastdfs安装配置

  1. cd fastdfs-6.04/
  2. vim make.sh
  1. TARGET_PREFIX=$DESTDIR/usr
  2. TARGET_CONF_PATH=$DESTDIR/etc/fdfs
  3. TARGET_INIT_PATH=$DESTDIR/etc/init.d


安装fastdfs

  1. ./make.sh
  2. ./make.sh install

分布式文件系统-FastDFS OSS - 图4
如上图,

  1. -

/usr/bin 中包含了可执行文件;

  1. -

/etc/fdfs 包含了配置文件; 分布式文件系统-FastDFS OSS - 图5

分布式文件系统-FastDFS OSS - 图6

  1. -

拷贝配置文件如下

  1. cp /home/software/FastDFS/fastdfs-6.04/conf/* /etc/fdfs/

分布式文件系统-FastDFS OSS - 图7

  • 配置tracker服务

    • 说明

      • tracker和storage都是同一个fastdfs的主程序的两个不同概念,配置不同的配置文件就可以设定为tracker或者storage
    • 配置tracker
      /etc/fdfs下都是一些配置文件,配置tracker即可
      1. vim tracker.conf

分布式文件系统-FastDFS OSS - 图8

  1. -

修改tracker配置文件,此为tracker的工作目录,保存数据以及日志

  1. base_path=/usr/local/fastdfs/tracker
  1. mkdir /usr/local/fastdfs/tracker -p
  • 启动tracker服务
    1. /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf


检查进程如下:

  1. ps -ef|grep tracker
  • 停止tracker
    1. /usr/bin/stop.sh /etc/fdfs/tracker.conf
  • 配置storage服务

    • 修改该storage.conf配置文件 分布式文件系统-FastDFS OSS - 图9 ```nginx

      修改组名

      group_name=imooc

      修改storage的工作空间

      base_path=/usr/local/fastdfs/storage

      修改storage的存储空间

      store_path0=/usr/local/fastdfs/storage

      修改tracker的地址和端口号,用于心跳

      tracker_server=192.168.1.153:22122

后续结合nginx的一个对外服务端口号

http.server_port=8888

  1. -
  2. 创建目录
  3. ```nginx
  4. mkdir /usr/local/fastdfs/storage -p
  • 启动storage
    前提:必须首先启动tracker
    1. /usr/bin/fdfs_storaged /etc/fdfs/storage.conf


检查进程如下:

  1. ps -ef|grep storage

分布式文件系统-FastDFS OSS - 图10

  • 测试上传

    • 修改的client配置文件 分布式文件系统-FastDFS OSS - 图11
      1. base_path=/usr/local/fastdfs/client
      2. tracker_server=192.168.1.153:22122
  1. mkdir /usr/local/fastdfs/client
  1. -

测试:

  1. wget https://www.imooc.com/static/img/index/logo.png
  2. ./fdfs_test /etc/fdfs/client.conf upload /home/logo.png

分布式文件系统-FastDFS OSS - 图12

  • 配置nginx fastdfs实现文件服务器

    引子
    fastdfs安装好以后是无法通过http访问的,这个时候就需要借助nginx了,所以需要安装fastdfs的第三方模块到nginx中,就能使用了。

注:nginx需要和storage在同一个节点。

  • 安装nginx插件

    • 解压nginx的fastdfs压缩包
      1. tar -zxvf fastdfs-nginx-module-1.22.tar.gz
  • 复制配置文件如下:
    1. cp mod_fastdfs.conf /etc/fdfs

分布式文件系统-FastDFS OSS - 图13

  • 修改/fastdfs-nginx-module/src/config文件,主要是修改路径,把local删除,因为fastdfs安装的时候没有修改路径,原路径是/usr分布式文件系统-FastDFS OSS - 图14
  • 安装nginx(略)

    • 其中配置如下:
      1. ./configure \
      2. --prefix=/usr/local/nginx \
      3. --pid-path=/var/run/nginx/nginx.pid \
      4. --lock-path=/var/lock/nginx.lock \
      5. --error-log-path=/var/log/nginx/error.log \
      6. --http-log-path=/var/log/nginx/access.log \
      7. --with-http_gzip_static_module \
      8. --http-client-body-temp-path=/var/temp/nginx/client \
      9. --http-proxy-temp-path=/var/temp/nginx/proxy \
      10. --http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
      11. --http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
      12. --http-scgi-temp-path=/var/temp/nginx/scgi \
      13. --add-module=/home/software/fdfs/fastdfs-nginx-module-1.22/src
  • 主要新增一个第三方模块,修改 mod_fastdfs.conf 配置文件:
    1. base_path=/usr/local/fastdfs/tmp
    2. tracker_server=192.168.1.153:22122
    3. group_name=imooc
    4. url_have_group_name = true
    5. store0_path=/usr/local/fastdfs/storage
  1. mkdir /usr/local/fastdfs/tmp
  • 修改nginx.conf,添加如下虚拟主机:

    1. server {
    2. listen 8888;
    3. server_name localhost;
    4. location /imooc/M00 {
    5. ngx_fastdfs_module;
    6. }
    7. }

FastDFS整合SpringBoot技术落地

  • pom依赖
    1. <!-- fastdfs依赖 -->
    2. <dependency>
    3. <groupId>com.github.tobato</groupId>
    4. <artifactId>fastdfs-client</artifactId>
    5. <version>1.26.7</version>
    6. </dependency>
  • 上传接口
    1. public String upload(MultipartFile file, String fileExtName) throws Exception;
  • 接口实现类 ```java @Autowired private FastFileStorageClient fastFileStorageClient;

@Override public String upload(MultipartFile file, String fileExtName) throws Exception {

  1. StorePath storePath = fastFileStorageClient.uploadFile(file.getInputStream(),
  2. file.getSize(),
  3. fileExtName,
  4. null);
  5. String path = storePath.getFullPath();
  6. return path;

}

  1. -
  2. 上传controller
  3. ```java
  4. @ApiOperation(value = "用户头像修改", notes = "用户头像修改", httpMethod = "POST")
  5. @PostMapping("uploadFace")
  6. public IMOOCJSONResult uploadFace(
  7. @ApiParam(name = "userId", value = "用户id", required = true)
  8. String userId,
  9. @ApiParam(name = "file", value = "用户头像", required = true)
  10. MultipartFile file,
  11. HttpServletRequest request,
  12. HttpServletResponse response) throws Exception {
  13. String path = "";
  14. // 开始文件上传
  15. if (file != null) {
  16. // 获得文件上传的文件名称
  17. String fileName = file.getOriginalFilename();
  18. if (StringUtils.isNotBlank(fileName)) {
  19. // 文件重命名 imooc-face.png -> ["imooc-face", "png"]
  20. String fileNameArr[] = fileName.split("\\.");
  21. // 获取文件的后缀名
  22. String suffix = fileNameArr[fileNameArr.length - 1];
  23. if (!suffix.equalsIgnoreCase("png") &&
  24. !suffix.equalsIgnoreCase("jpg") &&
  25. !suffix.equalsIgnoreCase("jpeg")) {
  26. return IMOOCJSONResult.errorMsg("图片格式不正确!");
  27. }
  28. path = fileService.upload(file, suffix);
  29. }
  30. } else {
  31. return IMOOCJSONResult.errorMsg("文件不能为空!");
  32. }
  33. if (StringUtils.isNotBlank(path)) {
  34. String finalUserFaceUrl = fileResource.getOssHost() + path;
  35. Users userResult = centerUserService.updateUserFace(userId, finalUserFaceUrl);
  36. userResult = setNullProperty(userResult);
  37. CookieUtils.setCookie(request, response, "user",
  38. JsonUtils.objectToJson(userResult), true);
  39. } else {
  40. return IMOOCJSONResult.errorMsg("上传头像失败");
  41. }
  42. return IMOOCJSONResult.ok();
  43. }

第三方云存储解决方案-OSS

  • 使用OSS优点

    • SDK使用简单
    • 提供强大的文件处理功能
    • 零运维成本
    • 图形化管理控制台
    • CDN加速
  • OSS基本配置
    1. file.host=http://192.168.1.156:8888/
    2. file.endpoint=oss-cn-beijing.aliyuncs.com
    3. file.accessKeyId=LTAI4Fo5zZe
    4. file.accessKeySecret=uTVnXbuTTg
    5. file.bucketName=imooctest
    6. file.objectName=foodie-dev/images
    7. file.ossHost=https://imooctest.oss-cn-beijing.aliyuncs.com/
  • OSS实现文件上传

    1. @Override
    2. public String uploadOSS(MultipartFile file, String userId, String fileExtName) throws Exception {
    3. // 构建ossClient
    4. OSS ossClient = new OSSClientBuilder()
    5. .build(fileResource.getEndpoint(),
    6. fileResource.getAccessKeyId(),
    7. fileResource.getAccessKeySecret());
    8. InputStream inputStream = file.getInputStream();
    9. String myObjectName = fileResource.getObjectName() + "/" + userId + "/" + userId + "." + fileExtName;
    10. ossClient.putObject(fileResource.getBucketName(), myObjectName, inputStream);
    11. ossClient.shutdown();
    12. return myObjectName;
    13. }