FastDFS(Fast Distributed File System)是一款开源轻量级分布式文件系统。
Tracker Server作用是负载均衡和调度。文件上传时通过Tracker Server根据某些策略(压力/宕机等)找到适合的Storage Server提供文件上传服务。
FastDFS集群中的Tracker Server可以有多台。Tracker Server之间是平等关系同时提供服务,不存在单点故障;客户端请求Tracker Server采用轮询方式,如果请求的Tracker无法提供服务则换另外的Tracker。
Storage
Storage Server作用是文件存储。Storage Server使用操作系统的文件系统来管理文件。
Storage集群采用了分组存储方式,可以由一个或多个组构成,集群存储总容量为集群中所有组的存储容量之和。一个组由一台或多台存储服务器组成,组内的Storage Server之间是平等关系,不同组的Storage Server之间不会互相通信。同组内的Storage Server之间会相互连接进行文件同步,从而保证同组内每个Storage 上的文件完全一致。
一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务器能力(纵向扩容);当系统容量不足时,可以增加组来扩充存储容量(横向扩容)。
Storage Server会连接集群中所有的Tracker Server,定时向他们报告自己的状态,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。
客户端上传文件到存储服务器返回文件ID给客户端。文件ID是访问文件的索引信息。包括:组名/虚拟磁盘路径/数据两级目录/文件名
wget https://github.com/happyfish100/libfastcommon/archive/V1.0.38.tar.gz
wget https://github.com/happyfish100/fastdfs/archive/V5.11.tar.gz
修改相关参数:
# the base path to store data and log files
base_path=/home/fastdfs/tracker # 存储data和log的根路径,提前创建
# the tracker server port
port=22122 # 默认端口为22122
# HTTP port on this tracker server
http.server_port=80 # http端口(需要与nginx相同)
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
可能遇到的报错:
/usr/bin/fdfs_trackerd: error while loading shared libraries: libfastcommon.so: cannot open shared object file: No such file or directory
解决方案:建立libfastcommon.so软链接
ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
base_path=/home/fastdfs/storage # 存储data和log的根路径,提前创建
port=23000 # storage默认23000,同一个组的端口号必须一致
group_name=group1 # 默认组名,根据实际情况修改
store_path_count=1 # 存储路径个数,需要和store_path个数匹配
store_path0=/home/fastdfs/storage # 如果为空,则使用base_path
tracker_server=10.0.192.55:22122 # 配置该storage监听的tracker的ip和port
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
/usr/bin/fdfs_monitor /etc/fdfs/storage.conf
点我!nginx已经安装
FastDFS 通过 Tracker 服务器,将文件放在 Storage 服务器存储,但是同组存储服务器之间需要进入文件复制,有同步延迟的问题。假设 Tracker 服务器将文件上传到了 10.0.192.55,上传成功后文件 ID 已经返回给客户端。此时 FastDFS 存储集群机制会将这个文件同步到同组存储10.0.192.64,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 10.0.192.64 上取文件,就会出现文件无法访问的错误。而 fastdfs-nginx-module 可以重定向文件连接到源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。(解压后的 fastdfs-nginx-module 在 nginx 安装时使用)
wget https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.20.tar.gz
[root@localhost nginx-1.14.0]# make
出现异常: /usr/include/fastdfs/trunk_shared.h:18:20: 错误:base64.h:没有那个文件或目录
解决方案:
① 编辑 fastdfs-nginx-module-1.20/src/config 文件
vim fastdfs-nginx-module-1.20/src/config
② 修改文件内容为:
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
location ~/M00 {
root /home/fastdfs/storage/data;
ngx_fastdfs_module;
index index.html index.htm;
}
cd /usr/local/fastDFS/fastdfs-5.11/conf/
cp mime.types http.conf /etc/fdfs/
集群:
java工具类:
package com.edu.x.modules.util;
import org.csource.common.MyException;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.StorageClient1;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
/**
* fast文件上传工具类
*
*
* @author yongzhen
* @date 2018/12/20-11:05
*/
public class FastDFSUtil {
private static Logger logger = LoggerFactory.getLogger(FastDFSUtil.class);
/**
* 上传文件的方法
*
* @param byteFile 文件字节流
* @param expandName 文件拓展名
*
* @return
*/
public static String uploadFile(byte[] byteFile, String expandName) {
String filePath = null;
try {
// 初始化客户端配置信息
ClientGlobal.initByProperties("com/edu/x/config/fdfs_client.properties");
// 创建tracker客户端
TrackerClient trackerClient = new TrackerClient();
TrackerServer trackerServer = trackerClient.getConnection();
String storageServerIp = getStorageServerIp(trackerClient, trackerServer);
logger.info("获取文件服务器IP:" + storageServerIp);
StorageServer storageServer = null;
// 创建storage客户端
StorageClient1 client = new StorageClient1(trackerServer, storageServer);
// 文件元信息
// NameValuePair[] metaList = new NameValuePair[2];
// metaList[0] = new NameValuePair("source", "OA");
// metaList[1] = new NameValuePair("author", "yangyongzhen");
//利用字节流上传文件
String fileId = client.upload_file1(byteFile, expandName, null);
logger.info("upload success. file id is: " + fileId);
filePath = storageServerIp + File.separator + fileId;
return filePath;
} catch (IOException | MyException e) {
e.printStackTrace();
}
return filePath;
}
/**
* 获得可用的storage IP
*
* @param trackerClient
* @param trackerServer
*
* @return 返回storage IP
*/
public static String getStorageServerIp(TrackerClient trackerClient, TrackerServer trackerServer) {
String storageIp = null;
if (trackerClient != null && trackerServer != null) {
try {
StorageServer storageServer = trackerClient.getStoreStorage(trackerServer, "group1");
storageIp = storageServer.getSocket().getInetAddress().getHostAddress();
} catch (IOException e) {
e.printStackTrace();
}
}
return storageIp;
}
}
java配置文件:
#FastDFS配置(除了fastdfs.tracker_servers,其它配置项都是可选的)
fastdfs.connect_timeout_in_seconds=10
fastdfs.network_timeout_in_seconds=30
fastdfs.charset=UTF-8
fastdfs.http_anti_steal_token=false
fastdfs.http_secret_key=FastDFS1234567890
fastdfs.http_tracker_http_port=80
fastdfs.tracker_servers=10.0.192.55:22122
properties文件必须包含配置项 fastdfs.tracker_servers
例如:fastdfs.tracker_servers = 10.0.192.55:22122,10.0.192.64:22122
server的IP和端口用冒号':'分隔,server之间用逗号','分隔