fastdfs分布式文件存储

fastdfs分布式文件存储

认识fastdfs

了解fastdfs

FastDFS是由国人余庆所开发,其项目地址https://github.com/happyfish100

FastDFS是一个轻量级的开源分布式文件系统,主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。

支持存储服务器在线扩容,支持相同的文件只保存一份,节约磁盘。

FastDFS只能通过Client API访问,不支持POSIX访问方式。

FastDFS适合中大型网站使用,用来存储资源文件(如:图片、文档、视频等)

FastDFS组成部分

FastDFS由跟踪服务器(tracker server)、存储服务器(storage server)和客户端(client)三个部分组成,主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。

Tracker server(跟踪服务器)
跟踪服务器:用来调度来自客户端的请求。且在内存中记录所有存储组和存储服务器的信息状态。
Storage server(存储服务器)
用来存储文件(data)和文件属性(metadata)
Client客户端
提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。

FastDFS服务器架构
  • 存储服务器会定期向跟踪服务器发送状态信息(心跳包)。
  • 客户端发起上传请求时,向跟踪服务器查询可用的存储服务器。
  • 客户端向存储服务器上传文件内容,存储服务器保存文件并生成文件路径以及文件名
  • 存储服务器将路径及文件名返回给客户端

在这里插入图片描述

使用

jar包准备
  • Maven
    <dependency>
      <groupId>org.csource</groupId>
      <artifactId>fastdfs-client-java</artifactId>
      <version>1.27</version>
    </dependency>

    <!--用于读字节数组  方法FileUtils-->      
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>
配置文件

resources文件夹下fdfs_client.conf( text格式 )

connect_timeout = 2    //连接超时时间
network_timeout = 30   //网络连接超时时间
charset = UTF-8
http.tracker_http_port = 8111
tracker_server = 192.168.20.252:22122   //跟踪服务器IP地址
使用客户端api
public class DfsUtil {
    private static TrackerClient client = null;
    private static String httpPort = null;
    private static String REAL_NAME = "realName";
    private static String FILE_SIZE = "size";
    private static String UPLOAD_TIME = "uploadTime";
    //初始化fastdfs服务
    static {
        String conf_path = DfsUtil.class.getClassLoader().getResource("fdfs_client.conf").getPath();
        try {
            //加载conf配置文件
            ClientGlobal.init(conf_path);
            //所有的跟踪服务器信息在TrackerClient对象中。
            //知道所有的跟踪服务器组
            client = new TrackerClient();
            // 得到http服务端口
            httpPort = ClientGlobal.getG_tracker_http_port() + "";
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    //上传(文件信息,文件的元数据信息)  
    //byte[] bytes 一般用于10M以下文件
    public static String upload(byte[] bytes,String realName,long size){
        TrackerServer ts = null;
        //创建存储服务器对象
        StorageServer ss = null;
        StorageClient1 storageClient1 = null;
        try {
            //从跟踪服务器组拿到一个具体的跟踪服务器
            ts = client.getConnection();
            //即使传入的存储服务器对象为null也会自动分配
            //也可以指定具体存储服务器对象 一般为null
            storageClient1 = new StorageClient1(ts, ss);
            //获取文件后缀名
            String extName = realName.substring(realName.lastIndexOf(".") + 1);
            //元数据列表,(类似写的注释)上传文件习惯把上传日期,文件大小,文件真实名
            NameValuePair[] metaList = new NameValuePair[]{
                new NameValuePair(REAL_NAME,realName),
                new NameValuePair(FILE_SIZE,size+""),
                new NameValuePair(UPLOAD_TIME,System.currentTimeMillis()+""),
            };
            //上传 并返回上传结果
            String s = storageClient1.upload_file1(bytes, extName, metaList);
            return s;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //释放连接
            if(storageClient1!=null)storageClient1=null;
            if(ss!=null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ts!=null){
                try {
                    ts.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
    

    //获取文件元数据信息
    public static Map<String,String> getMetaList(String path){
        TrackerServer ts = null;
        StorageServer ss = null;
        StorageClient1 storageClient1 = null;
        try {
            ts = client.getConnection();
            storageClient1 = new StorageClient1(ts, ss);
            //根据得来的路径从数据库拉取资源 返回数组
            NameValuePair[] metadata1 = storageClient1.get_metadata1(path);
            //遍历数组 放入集合map
            Map<String,String> result = new HashMap<>();
            for(NameValuePair nv:metadata1){
                result.put(nv.getName(),nv.getValue());
            }
            return result;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(storageClient1!=null)storageClient1=null;
            if(ss!=null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ts!=null){
                try {
                    ts.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    //下载
    public static byte[] download(String path){
        TrackerServer ts = null;
        StorageServer ss = null;
        StorageClient1 storageClient1 = null;
        try {
            ts = client.getConnection();//
            storageClient1 = new StorageClient1(ts, ss);
            byte[] bytes = storageClient1.download_file1(path);
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(storageClient1!=null)storageClient1=null;
            if(ss!=null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ts!=null){
                try {
                    ts.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }

    //删除
    public static boolean delete(String path){
        TrackerServer ts = null;
        StorageServer ss = null;
        StorageClient1 storageClient1 = null;
        try {
            ts = client.getConnection();//
            storageClient1 = new StorageClient1(ts, ss);
            //表示删除文件,0成功,2失败
            int i = storageClient1.delete_file1(path);
            return i==0?true:false;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(storageClient1!=null)storageClient1=null;
            if(ss!=null) {
                try {
                    ss.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if(ts!=null){
                try {
                    ts.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return false;
    }

    //生成HttpUrl   用于图片展示等
    public static String getHttpPath(String path){
        String url ="http://";
        try {
            //得到一台具体的跟踪服务器
            TrackerServer connection = client.getConnection();
            //得到跟踪服务器的主机名
            String hostName = connection.getInetSocketAddress().getHostName();
            url = url+hostName+":"+httpPort+"/"+path;
            return url;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }
}
//Test
public class AppTest
{
    /**
     * Rigorous Test :-)
     */
    //上传
    @Test
    public void upload() throws IOException {
        File f = new File("C:/Users/JAVASM/Desktop/学习笔记/学习中/java/java图片/4.jpg");
        byte[] bytes = FileUtils.readFileToByteArray(f);
        String name = f.getName();
        long length = f.length();

        String upload = DfsUtil.upload(bytes, name, length);
        System.out.println(upload);
        //group1/M00/00/12/wKgU_F9yra6AUyizAACoxG3uRvc315.jpg  group1-存储服务器
    }

    //获取文件元数据信息
    @Test
    public void getMetaDatas(){
        String path = "group1/M00/00/12/wKgU_F9yra6AUyizAACoxG3uRvc315.jpg";
        Map<String, String> metaList = DfsUtil.getMetaList(path);
        System.out.println(metaList);
    }
    
    //下载 用到了
    @Test
    public void download() throws IOException {
        String path = "group1/M00/00/12/wKgU_F9yra6AUyizAACoxG3uRvc315.jpg";
        byte[] download = DfsUtil.download(path);
        File f = new File("D:/aa.png");
        FileUtils.writeByteArrayToFile(f,download);
    }

    //删除
    @Test
    public void del() throws IOException {
        String path = "group1/M00/00/12/wKgU_F9yra6AUyizAACoxG3uRvc315.jpg";
        boolean delete = DfsUtil.delete(path);
    }

    //生成HttpUrl
    @Test
    public void getHttpPath(){
        String path = "group1/M00/00/12/wKgU_F9yra6AUyizAACoxG3uRvc315.jpg";
        String httpPath = DfsUtil.getHttpPath(path);
        System.out.println(httpPath);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值