分布式文件系统之FastDfs

本文引用至:https://sh.qihoo.com/pc/detail?url=https%3A%2F%2Fwww.toutiao.com%2Fi6642852421280203277%2F&check=edce824a247c0dfa&sign=baike&uid=15484592.2690209269186620000.1543843680589.368

一、 什么是fastDfs

fastDfs是一个轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。

二、 为什么要使用fastDfs

在单体应用时代可以使用 apache的common-fileupload或者struts进行文件的上传下载,但是对于海量的数据,文件资源和程序都放在一起会影响性能,特别是针对现在的微服务框架,更需要使用分布式的文件系统去上传,下载图片或者文件,对于海量的文件存储,fastDfs是个不错的选择。

fastDfs有两个重要的部件:

① 跟踪器(tracker)

简单来说就是控制文件上传的路由,负责分配文件的地址,保持周期性心跳。

存储节点(storage)

相当于一个存贮的容器,以 group 为单位,每个 group 内可以有多台 storage server。

引用官方的一个原理图

三、 如何安装

安装的教程网上是有很多的,这里不再过多的阐述。

这里针对linux版本的单节点的安装推荐两篇网上的安装教程:

https://blog.csdn.net/zxl315/article/details/53535751

http://www.cnblogs.com/adolfmc/p/4239575.html

主要有这4个配置文件

如果需要配置修改fastDfs的密码的话,可以修改下图的这个地方

四、 如何使用

1. 引入依赖

在javaweb程序中使用的时候,如果项目没有使用maven,需要下载jar包 fastdfs_client_v1.19.jar,然后引入。

如果是maven项目的话,需要在pom.xml文件中引入fastdfs_client 依赖。

 

 

org.csource

 

fastdfs-client-java

 

5.0.4

 

 

2. 配置参数

在src/main/resource 下创建 fdfs_client.conf 配置文件

#fdfs_client.conf 配置

connect_timeout = 10

 

network_timeout = 30

 

charset = UTF-8

 

http.tracker_http_port = 8888

 

http.anti_steal_token = no

 

http.secret_key = FastDFS1234567890

 

tracker_server = 192.168.220.88:22122

 

#如果有多台服务,指定集群的IP

 

#tracker_server = 192.168.220.89:22122

 

#tracker_server = 192.168.220.90:22122

 

 

3. 工具类

1) 初始化

初始化fastDfs的跟踪器和存储器,上传和下载的时候就可以调用这个初始化了。

	/**

 

* @Description:初始化fastDfs

 

* @author: jhy

 

* @date: 2017年10月31日 上午9:52:16

 

*/

 

public static Map init() {

 

Map map = new HashMap();

 

try {

 

String classPath = new File(FastDfsUtil.class.getResource("/").getFile()).getCanonicalPath();

 

classPath = URLDecoder.decode(classPath,"utf-8");

 

String configFilePath = classPath + File.separator + "fdfs_client.conf";

 

logger.info("配置文件:" + configFilePath);

 

// 初始化参数

 

ClientGlobal.init(configFilePath);

 

// 初始化跟踪器

 

TrackerClient trackerClient = new TrackerClient();

 

TrackerServer trackerServer = trackerClient.getConnection();

 

// 初始化存储器

 

StorageServer storageServer = null;

 

StorageClient storageClient = new StorageClient(trackerServer, storageServer);

 

map.put("trackerClient", trackerClient);

 

map.put("trackerServer", trackerServer);

 

map.put("storageClient", storageClient);

 

map.put("storageServer", storageServer);

 

return map;

 

} catch (Exception e) {

 

e.printStackTrace();

 

}

 

return null;

 

}

 

2) 上传文件

通过传入file和文件名,上传成功返回上传成功的路径

	/**

 

* @Description:上传文件

 

* @author: jhy

 

* @date: 2017年10月25日 上午9:28:52

 

* @param:file:上传文件流

 

*/

 

public static Map upload(File file, String fileName) {

 

Map map = new HashMap();

 

try {

 

// 初始化fastDfs

 

Map initMap = FastDfsUtil.init();

 

TrackerClient trackerClient = (TrackerClient) initMap.get("trackerClient");

 

TrackerServer trackerServer = (TrackerServer) initMap.get("trackerServer");

 

StorageClient storageClient = (StorageClient) initMap.get("storageClient");

 

// 初始化参数

 

NameValuePair[] meta_list = new NameValuePair[3];

 

meta_list[0] = new NameValuePair("width", "120");

 

meta_list[1] = new NameValuePair("heigth", "120");

 

meta_list[2] = new NameValuePair("author", "jhy");

 

//获取文件后缀名

 

String prefix = fileName.substring(fileName.lastIndexOf(".") + 1);

 

FileInputStream fis = new FileInputStream(file);

 

byte[] file_buff = null;

 

if(fis != null){

 

int len = fis.available();

 

file_buff = new byte[len];

 

fis.read(file_buff);

 

}

 

logger.info("文件长度: " + file_buff.length);

 

// 声明组

 

String group_name = null;

 

// 根据跟踪器和组查找存储器

 

StorageServer[] storageServers = trackerClient.getStoreStorages(trackerServer, group_name);

 

if (storageServers == null) {

 

logger.info("无法找到存储器服务:" + storageClient.getErrorCode());

 

map.put("resCode", storageClient.getErrorCode());

 

map.put("resMsg", "无法找到存储器服务");

 

return map;

 

}else{

 

logger.info("存储器数量: " + storageServers.length);

 

for (int k = 0; k

 

logger.info("当前文件:"+ k + 1 + ". " + "当前ip和端口" + storageServers[k].getInetSocketAddress().getAddress().getHostAddress() + ":" + storageServers[k].getInetSocketAddress().getPort());

 

}

 

}

 

// 开始时间

 

long startTime = System.currentTimeMillis();

 

// 文件上传返回结果

 

String[] results = storageClient.upload_file(file_buff, prefix, meta_list);

 

logger.info("上传耗费时间: " + (System.currentTimeMillis() - startTime) + " ms");

 

if (results == null){

 

logger.info("上传失败:" + storageClient.getErrorCode());

 

map.put("resCode", storageClient.getErrorCode());

 

map.put("resMsg", "上传失败");

 

return map;

 

}

 

//返回结果赋值给组

 

group_name = results[0];

 

String remote_filename = results[1];

 

logger.info("组名: " + group_name + ", 文件路径: " + remote_filename);

 

logger.info(storageClient.get_file_info(group_name, remote_filename).toString());

 

//根据跟踪器,组和文件路径查找跟踪服务器

 

ServerInfo[] servers = trackerClient.getFetchStorages(trackerServer, group_name, remote_filename);

 

if (servers == null){

 

logger.info("无法找到跟踪器服务:" + storageClient.getErrorCode());

 

map.put("resCode", trackerClient.getErrorCode());

 

map.put("resMsg", "无法找到跟踪器服务");

 

return map;

 

} else {

 

logger.info("跟踪服务器数量: " + servers.length);

 

for (int k = 0; k

 

logger.info("当前文件:"+ k + 1 + ". " + "当前ip和端口" + servers[k].getIpAddr() + ":" + servers[k].getPort());

 

}

 

}

 

map.put("resCode", "0000");//代表上传成功

 

map.put("resMsg", remote_filename);

 

logger.info("上传成功");

 

trackerServer.close();

 

return map;

 

} catch (Exception e) {

 

e.printStackTrace();

 

map.put("resCode", "9999");

 

map.put("resMsg", "文件服务器连接异常");

 

}

 

return map;

 

}

 

3) 获取文件信息

通过传入组名和服务器保存的文件名称获取远程文件信息

	/**

 

* @Description:获取文件信息

 

* @author: jhy

 

* @date: 2017年10月31日 上午9:56:33

 

* @param:group_name:组名

 

* @param:remote_filename 文件名称

 

*/

 

public static Map getFileInfo(String group_name, String remote_filename) {

 

Map map = new HashMap();

 

try {

 

// 初始化fastDfs

 

Map initMap = FastDfsUtil.init();

 

StorageClient storageClient = (StorageClient) initMap.get("storageClient");

 

FileInfo fi = storageClient.get_file_info(group_name, remote_filename);

 

String sourceIpAddr = fi.getSourceIpAddr();

 

long size = fi.getFileSize();

 

logger.info("ip地址:" + sourceIpAddr + ",文件大小:" + size);

 

map.put("resCode", "0000");//代表下载成功

 

map.put("resMsg", fi);

 

logger.info("获取文件信息成功");

 

return map;

 

} catch (Exception e) {

 

e.printStackTrace();

 

}

 

return null;

 

}

 

4) 下载文件

通过组名和文件名下载服务器的文件。

 /**

 

* @Description:下载文件

 

* @author: jhy

 

* @date: 2017年10月31日 上午9:56:33

 

* @param:group_name:组名

 

* @param:remote_filename 文件名称

 

*/

 

public static Map download(String group_name, String remote_filename) {

 

Map map = new HashMap();

 

try {

 

// 初始化fastDfs

 

Map initMap = FastDfsUtil.init();

 

StorageClient storageClient = (StorageClient) initMap.get("storageClient");

 

byte[] b = storageClient.download_file(group_name, remote_filename);

 

logger.info("下载字节b:" + b);

 

if (b != null) {

 

map.put("resCode", "0000");//代表下载成功

 

map.put("resMsg", b);

 

logger.info("下载成功");

 

}else {

 

map.put("resCode", "9999");//代表下载失败

 

map.put("resMsg", b);

 

logger.info("下载失败");

 

}

 

return map;

 

} catch (Exception e) {

 

e.printStackTrace();

 

}

 

return null;

 

}

 

5) 测试

	 /**

 

* @Description:测试

 

* @author: jhy

 

* @date: 2017年10月25日 上午11:04:39

 

*/

 

public static void main(String[] args) {

 

// 上传

 

// File file = new File("E:\\pic.png");

 

// FastDfsUtil.upload(file,"E:\\pic.png");

 

// 下载

 

FastDfsUtil.download("group1", "M00/00/01/pqYBZVofaPeANx_UAACnTf3PBis648.png");

 

}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值