zoukankan      html  css  js  c++  java
  • 分布式文件系统,FastDFS集群搭建与实战

    FastDFS是一个轻量级的分布式文件系统,在实际生产环境往往以集群的形式部署,保证了服务的高可用。本文重点阐述FastDFS集群的搭建和项目实战。

    工作流程

    上传流程图

    640?wx_fmt=png

    下载流程图

    640?wx_fmt=png

    基本概念可参考作者上篇文章:

    底层原理

    • FastDFS不会对文件进行分块存储,直接保存到Storage服务上,这也是不适合超大文件存储的原因,官方建议(4K~500M),优点:简介高效。

    • FastDFS采用分组存储方式,同一组可以包括多个Storage Server,其中一个Storage接收到上传的文件,会同步文件到同组其他Storage Server。

    • 一个组的存储容量为组内Storage Server容量最小的那个。优点:组内服务压力较大时可以增加Storage Server来缓解压力;系统容量不足时增加组来获得更大的存储空间。

    • 文件上传成功返回的文件ID由组名,磁盘目录和文件名构成。

    640?wx_fmt=jpeg

    集群服务器规划

    • 系统环境:centos 7.3

    • 跟踪服务器1(Tracker):192.168.72.135

    • 跟踪服务器2(Tracker):192.168.72.136

    • 存储服务器1(Storage):

              192.168.72.135---(group1)

    • 存储服务器2(Storage):

              192.168.72.136---(group1)

    • 存储服务器3(Storage):

              192.168.72.137---(group2)

    由于电脑性能有限,但要模拟多group,只虚拟了3个节点,对group1做了两个节点来备份数据,group2为单节点,生产环境要每个组至少两个节点来保证高可用。

    安装包

    • fastdfs-5.11.tar.gz

    • fastdfs-nginx-module-master.zip

    • libfastcommon-1.0.36.tar.gz

    • nginx-1.8.1.tar.gz

    集群部署

    Tracker和Storage部署

    • 1:节点1,节2,节点3分别安装FastDFS,具体安装参考上篇文章:

    • 2:分别关闭三个节点的防火墙,或者配置防火墙开放端口,关闭防火墙: systemctl stop firewalld

    • 3:修改节点1的tracker.conf配置文件:

      >mkdir /data/fdfs-tracker

      >vi /etc/fdfs/tracker.conf

      把base_path修改为:

          base_path=/data/fdfs-tracker

    • 4:修改节点2的tracker.conf配置文件:同上

    • 5:修改节点1的storage.conf配置文件:

      > mkdir /data/fdfs-storage/base

      > mkdir /data/fdfs-storage/storage0

      >vi /etc/fdfs/storage.conf

      把group_name修改为:

          group_name=group1

      把base_path修改为:

      base_path=/data/fdfs-storage/base

      把store_path0修改为:

      store_path0=/data/fdfs-storage/storage0

      把tracker_server修改两个tracker节点地址:

         tracker_server=192.168.72.135:22122

         tracker_server=192.168.72.136:22122

    • 6:修改节点2的storage.conf配置文件,同步骤5。

    • 7:修改节点3的storage.conf配置文件,

      把group_name修改为:

          group_name=group2

      其他同步骤5。

    • 8:节点1,节点2上启动tracker服务

      >service fdfs_trackerd start

    • 9:节点1,节点2和节点3上启动storage服务

      >service fdfs_storaged start

    Tracker和Storage安装完成,可以使用FastDFS自带的客户端进行上传下载测试,具体操作方法,

    fastdfs-nginx-module和nginx安装

    • 所有节点安装fastdfs-nginx-module模块

    • fastdfs-nginx-module模块作用:

      文件上传到组内一个storage存储后,storage服务会吧文件同步到组内其他storage,这就存在时间延时问题,如果此时客户端通过nginx访问到还未同步完成的组内其他storage会导致文件不存在无法访问错误,fastdfs-nginx-module可以解决该问题的发生,通过重定向到源storage节点来获取文件。

    • root目录解压fastdfs-nginx-module:

      >unzip fastdfs-nginx-module.zip

    • 安装依赖包:

      >yum install gcc gcc-c++ make automake autoconf libtool pcre* zlib openssl openssl-devel

    • 安装nginx

      >tar -zxvf nginx-1.8.1.tar.gz

      >cd nginx-1.8.1

      >./configure  --prefix=/opt/nginx  --add-module=/roo/fastdfs-nginx-module/src

      >make && make install

    • 复制fastdfs-nginx-module中配置文件到/etc/fdfs目录,并修改配置文件:

      >cp /root/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs

      >vi  /etc/fdfs/mod_fastdfs.conf

      tracker_server修改为:

          tracker_server=192.168.72.135:22122

          tracker_server=192.168.72.136:22122

      group_name修改为:

          节点1:group_name=group1

          节点2:group_name=group1

          节点3:group_name=group2

      url_have_group_name修改为:

          url_have_group_name = true

    • 复制FastDFS部分配置文件到/etc/fdfs目录:

      > cd /root/fastdfs-5.1/conf

      >cp http.conf  mime.types  /etc/fdfs/

    • 修改nginx.conf配置文件:

    • 640?wx_fmt=png

    • 启动nginx:

      >./nginx  -c  conf/nginx.conf

         

    到此FastDFS集群已经搭建完成,文件上传后可以通过任意storage节点上的nginx来获得文件

    实战

    • FastDFS提供了C,PHP和java客户端,选用java客户端来进行实战。

      创建maven工程,pom.xml文件添加依赖:

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

    添加配置文件

    • src/main/resoureces目录下添加fdfs_clent.conf配置文件,内容如下:

    connect_timeout = 60
    network_timeout = 60
    charset = UTF-8
    http.tracker_http_port = 8080
    http.anti_steal_token = no
    #tracker服务地址
    tracker_server = 192.168.72.135:22122
    tracker_server = 192.168.72.136:22122
    

    创建FdfsClient类

    • 静态代码块:

        private static StorageClient1 storageClient1 = null;
        private static String trackerServerUrl = null;
        //初始化FastDFS Client
        static{
            try{
                ClientGlobal.init("src/main/resources/fdfs_client.conf");
                TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
                TrackerServer trackerServer = trackerClient.getConnection();
                if (trackerServer == null){
                    System.out.println("getConnect  return null");
                }
                trackerServerUrl = trackerServer.getInetSocketAddress().getHostString();
                System.out.println("trackerServerUrl"  + trackerServerUrl);
                StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
                if (storageServer == null){
                    System.out.println("getStoreStorage return null");
                }
                storageClient1 = new StorageClient1(trackerServer,storageServer);
            }catch (Exception e){
                e.printStackTrace();
            }
        }

    文件上传

      public static String uploadFile(File file, String fileExt, Map<String,String> metaList) {
            try {
                byte[] buff = FileUtils.getFileByte(file);
                NameValuePair[] nameValuePairs = null;
                if (metaList != null) {
                    nameValuePairs = new NameValuePair[metaList.size()];
                    int index = 0;
                    for (Iterator<Map.Entry<String,String>> iterator = metaList.entrySet().iterator(); iterator.hasNext();) {
                        Map.Entry<String,String> entry = iterator.next();
                        String name = entry.getKey();
                        String value = entry.getValue();
                        nameValuePairs[index++] = new NameValuePair(name,value);
                    }
                }
               return "http://"+ trackerServerUrl + "/" + storageClient1.upload_file1(buff, fileExt, nameValuePairs);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

    文件下载

        public static int downloadFile(String fileId, String filePath,String fileName) {
            FileOutputStream fos = null;
            try {
                byte[] content = storageClient1.download_file1(fileId);
                FileUtils.getFile(content,  filePath, fileName);
                return 0;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fos != null) {
                    try {
                        fos.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            return -1;
        }
    

    获得文件属性

        public static Map<String,String> getFileMetadata(String fileId) {
            try {
                NameValuePair[] metaList = storageClient1.get_metadata1(fileId);
                if (metaList != null) {
                    HashMap<String,String> map = new HashMap<String, String>();
                    for (NameValuePair metaItem : metaList) {
                        map.put(metaItem.getName(),metaItem.getValue());
                    }
                    return map;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }

    文件删除

        public static int deleteFile(String fileId) {
            try {
                return storageClient1.delete_file1(fileId);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return -1;
        }

    往期推荐

     

    【技术篇】 

    【技术篇】 

    【技术篇】

    640?wx_fmt=jpeg

    Java架构师之路,一个汇聚六万技术人的圈子,让学习之路更有趣!

  • 相关阅读:
    【2018.05.05 C与C++基础】C++中的自动废料收集:概念与问题引入
    【2018.04.27 C与C++基础】关于switch-case及if-else的效率问题
    【2018.04.19 ROS机器人操作系统】机器人控制:运动规划、路径规划及轨迹规划简介之一
    March 11th, 2018 Week 11th Sunday
    March 10th, 2018 Week 10th Saturday
    March 09th, 2018 Week 10th Friday
    March 08th, 2018 Week 10th Thursday
    March 07th, 2018 Week 10th Wednesday
    ubantu之Git使用
    AMS分析 -- 启动过程
  • 原文地址:https://www.cnblogs.com/Java-Road/p/11824680.html
Copyright © 2011-2022 走看看