分布式文件存储--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