• 分布式文件存储FastDFS 邓维


    分布式文件存储--FastDFS

    FastDFS 下载: https://sourceforge.net/projects/fastdfs/

    简介:

         FastDFS是一款开源的轻量级分布式文件系统纯C实现,支持Linux、FreeBSD等UNIX系统类google FS,不是通用的文件系统,只能通过专有API访问,目前提供了C、Java和PHP API为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性FastDFS可以看做是基于文件的key value pair存储系统,称作分布式文件存储服务更为合适。

    FastDFS由 跟 踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)构成。

    Tracker server 追踪服务器

    • 跟踪服务器, 主要做调度工作, 起负载均衡的作用。 在内存中记录集群中所有存储组和存储服务器的状态信息, 是客户端和数据服务器交互的枢纽。追踪服务器负责接收客户端的请求,选择合适的组合storage server ,tracker server 与 storage server之间也会用心跳机制来检测对方是否活着。
    • Tracker需要管理的信息也都放在内存中,并且里面所有的Tracker都是对等的(每个节点地位相等),很容易扩展
    • 客户端访问集群的时候会随机分配一个Tracker来和客户端交互。

    Storage server 储存服务器

    存储服务器( 又称:存储节点或数据服务器) , 文件和文件属性( metadata) 都保存到存储服务器上。 Storage server直接利用OS的文件系统调用管理文件。实际存储数据,分成若干个组(group),实际traker就是管理的storage中的组,而组内机器中则存储数据,group可以隔离不同应用的数据,不同的应用的数据放在不同group里面,

    group

           组, 也可称为卷。 同组内服务器上的文件是完全相同的 ,同一组内的storage server之间是对等的(同一组内的文件服务器相互备份), 文件上传、 删除等操作可以在任意一台storage server上进行 

    客户端Client
    • 主要是上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。每个客户端服务器都需要安装Nginx

    上传交互过程

    • 1. client询问tracker上传到的storage,不需要附加参数;
    • 2. tracker返回一台可用的storage;
    • 3. client直接和storage通讯完成文件上传。

    下载交互过程

    • 1. client询问tracker下载文件的storage,参数为文件标识(卷名和文件名);
    • 2. tracker返回一台可用的storage;
    • 3. client直接和storage通讯完成文件下载。
    • 需要说明的是,client为使用FastDFS服务的调用方,client也应该是一台服务器,它对tracker和storage的调用均为服务器间的调用。

     java整合FastDFS

     <!--FastDFS java客户端-->
            <dependency>
                <groupId>net.oschina.zcx7878</groupId>
                <artifactId>fastdfs-client-java</artifactId>
                <version>1.27.0.0</version>
            </dependency>
    Utils
    /**
     * FastDFS 文件存取Utils
     */
    public class FastDFSClient {
    
        static {
            //从classpath下获取文件对象获取路径
            String path = new ClassPathResource("fdfs_client.conf").getPath();
            try {
                ClientGlobal.init(path);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 图片上传
         *
         * @param file
         * @return
         */
        public static String[] upload(FastDFSFile file) {
            try {
                TrackerClient trackerClient = new TrackerClient();
                TrackerServer trackerServer = trackerClient.getConnection();
                StorageClient storageClient = new StorageClient(trackerServer, null);
                //参数1 字节数组
                //参数2 扩展名(不带点)
                //参数3 元数据( 文件的大小,文件的作者,文件的创建时间戳)
                NameValuePair[] meta_list = new NameValuePair[]{new NameValuePair(file.getAuthor()), new NameValuePair(file.getName())};
                String[] strings = storageClient.upload_file(file.getContent(), file.getExt(), meta_list);
                // strings[0]==group1  strings[1]=M00/00/00/wKjThF1aW9CAOUJGAAClQrJOYvs424.jpg
                return strings;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
        /**
         * 图片下载
         *
         * @param groupName
         * @param remoteFileName
         * @return
         */
        public static InputStream downFile(String groupName, String remoteFileName) {
            ByteArrayInputStream byteArrayInputStream = null;
            try {
                //3.创建trackerclient对象
                TrackerClient trackerClient = new TrackerClient();
                //4.创建trackerserver 对象
                TrackerServer trackerServer = trackerClient.getConnection();
                //5.创建stroageserver 对象
                //6.创建storageclient 对象
                StorageClient storageClient = new StorageClient(trackerServer, null);
                //7.根据组名 和 文件名 下载图片
    
                //参数1:指定组名
                //参数2 :指定远程的文件名
                byte[] bytes = storageClient.download_file(groupName, remoteFileName);
                byteArrayInputStream = new ByteArrayInputStream(bytes);
                return byteArrayInputStream;
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                try {
                    if (byteArrayInputStream != null) {
                        byteArrayInputStream.close();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }
    
    
        /**
         * 图片删除
         *
         * @param groupName
         * @param remoteFileName
         */
        public static void deleteFile(String groupName, String remoteFileName) {
            try {
                //3.创建trackerclient对象
                TrackerClient trackerClient = new TrackerClient();
                //4.创建trackerserver 对象
                TrackerServer trackerServer = trackerClient.getConnection();
                //5.创建stroageserver 对象
                //6.创建storageclient 对象
                StorageClient storageClient = new StorageClient(trackerServer, null);
                int i = storageClient.delete_file(groupName, remoteFileName);
                if (i == 0) {
                    System.out.println("删除成功");
                } else {
                    System.out.println("删除失败");
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        /**
         * 根据组名获取组的信息
         *
         * @param groupName
         * @return
         */
        public static StorageServer getStorages(String groupName) {
            try {
                TrackerClient trackerClient = new TrackerClient();
                //4.创建trackerserver 对象
                TrackerServer trackerServer = trackerClient.getConnection();
    
                //参数1 指定traqckerserver 对象
                //参数2 指定组名
                StorageServer group1 = trackerClient.getStoreStorage(trackerServer, groupName);
                return group1;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    
        /**
         * 根据文件名和组名获取文件的信息
         *
         * @param groupName
         * @param remoteFileName
         * @return
         */
        public static FileInfo getFile(String groupName, String remoteFileName) {
            try {
                TrackerClient trackerClient = new TrackerClient();
                //4.创建trackerserver 对象
                TrackerServer trackerServer = trackerClient.getConnection();
    
                StorageClient storageClient = new StorageClient(trackerServer, null);
    
                //参数1 指定组名
                //参数2 指定文件的路径
                FileInfo fileInfo = storageClient.get_file_info(groupName, remoteFileName);
                return fileInfo;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    
        /**
         * 根据文件名和组名 获取组信息的数组信息
         *
         * @param groupName
         * @param remoteFileName
         * @return
         */
        public static ServerInfo[] getServerInfo(String groupName, String remoteFileName) {
            try {
                //3.创建trackerclient对象
                TrackerClient trackerClient = new TrackerClient();
                //4.创建trackerserver 对象
                TrackerServer trackerServer = trackerClient.getConnection();
    
                ServerInfo[] group1s = trackerClient.getFetchStorages(trackerServer, groupName, remoteFileName);
                return group1s;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
    
        }
    
        /**
         * 获取tracker 的ip和端口的信息,
         * http://192.168.211.132:8080
         *
         * @return
         */
        public static String getTrackerUrl() {
            try {
                //3.创建trackerclient对象
                TrackerClient trackerClient = new TrackerClient();
                //4.创建trackerserver 对象
                TrackerServer trackerServer = trackerClient.getConnection();
                //tracker 的ip的信息
                String hostString = trackerServer.getInetSocketAddress().getHostString();
    
                //http://192.168.211.132:8080/group1/M00/00/00/wKjThF1aW9CAOUJGAAClQrJOYvs424.jpg img
                int g_tracker_http_port = ClientGlobal.getG_tracker_http_port();
                return "http://" + hostString + ":" + g_tracker_http_port;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    FastDFSFile 

    /**
     * 文件存取Bean
     */
    public class FastDFSFile implements Serializable {
    
        //文件名字
        private String name;
        //文件内容
        private byte[] content;
        //文件扩展名
        private String ext;
        //文件MD5摘要值
        private String md5;
        //文件创建作者
        private String author;
    
        public FastDFSFile(String name, byte[] content, String ext, String md5, String author) {
            this.name = name;
            this.content = content;
            this.ext = ext;
            this.md5 = md5;
            this.author = author;
        }
    
        public FastDFSFile(String name, byte[] content, String ext) {
            this.name = name;
            this.content = content;
            this.ext = ext;
        }
    
        public FastDFSFile() {
        }
    }

    fdfs_client.conf

    #连接超时的世界 s
    connect_timeout=60
    #网络超时时间
    network_timeout=60
    #字符编码
    charset=UTF-8
    # tracker的http通信协议的端口
    http.tracker_http_port=8080
    # 22122 trackerserver的tcp 端口
    tracker_server=192.168.211.132:22122






  • 相关阅读:
    HDU 5795
    HDU5783
    HDU 5791
    VK Cup 2016
    Codeforces Round #357 (Div. 2)
    Educational Codeforces Round 15
    HDU5724
    博弈学习 3
    Spring的多配置文件加载
    spring 核心技术
  • 原文地址:https://www.cnblogs.com/dw3306/p/14562312.html
Copyright © 2020-2023  润新知