编程开源技术交流,分享技术与知识

网站首页 > 开源技术 正文

【开源组件】FastDFS集群搭建与实战

wxchong 2024-08-16 05:50:38 开源技术 17 ℃ 0 评论

FastDFS是一个轻量级的分布式文件系统,在实际生产环境往往以集群的形式部署,保证了服务的高可用。本文重点阐述FastDFS集群的搭建和项目实战。

工作流程

上传流程图

下载流程图

基本概念可参考作者上篇文章:FastDFS极速入门

底层原理

  • FastDFS不会对文件进行分块存储,直接保存到Storage服务上,这也是不适合超大文件存储的原因,官方建议(4K~500M),优点:简介高效。
  • FastDFS采用分组存储方式,同一组可以包括多个Storage Server,其中一个Storage接收到上传的文件,会同步文件到同组其他Storage Server。
  • 一个组的存储容量为组内Storage Server容量最小的那个。优点:组内服务压力较大时可以增加Storage Server来缓解压力;系统容量不足时增加组来获得更大的存储空间。
  • 文件上传成功返回的文件ID由组名,磁盘目录和文件名构成。

集群服务器规划

  • 系统环境:centos 7.3
  • 跟踪服务器1(Tracker):192.168.72.135
  • 跟踪服务器2(Tracker):192.168.72.136
  • 存储服务器1(Storage):192.168.72.135---(group1)
  • 存储服务器2(Storage):192.168.72.136---(group1)
  • 存储服务器3(Storage):192.168.72.137---(group2)

由于电脑性能有限,但要模拟多group,只虚拟了3个节点,对group1做了两个节点来备份数据,group2为单节点,生产环境要每个组至少两个节点来保证高可用。

安装包

  • fastdfs-5.11.tar.gz
  • fastdfs-nginx-module-master.zip
  • libfastcommon-1.0.36.tar.gz
  • nginx-1.8.1.tar.gz

集群部署

Tracker和Storage部署

  • 1:节点1,节2,节点3分别安装FastDFS,具体安装参考上篇文章:FastDFS极速入门
  • 2:分别关闭三个节点的防火墙,或者配置防火墙开放端口,关闭防火墙: systemctl stop firewalld
  • 3:修改节点1的tracker.conf配置文件:
  • >mkdir /data/fdfs-tracker
  • >vi /etc/fdfs/tracker.conf
  • 把base_path修改为:base_path=/data/fdfs-tracker
  • 4:修改节点2的tracker.conf配置文件:同上
  • 5:修改节点1的storage.conf配置文件:
  • > mkdir /data/fdfs-storage/base
  • > mkdir /data/fdfs-storage/storage0
  • >vi /etc/fdfs/storage.conf
  • 把group_name修改为:group_name=group1
  • 把base_path修改为:base_path=/data/fdfs-storage/base
  • 把store_path0修改为:store_path0=/data/fdfs-storage/storage0
  • 把tracker_server修改两个tracker节点地址:
  • tracker_server=192.168.72.135:22122
  • tracker_server=192.168.72.136:22122
  • 6:修改节点2的storage.conf配置文件,同步骤5。
  • 7:修改节点3的storage.conf配置文件,
  • 把group_name修改为:group_name=group2
  • 其他同步骤5。
  • 8:节点1,节点2上启动tracker服务
  • >service fdfs_trackerd start
  • 9:节点1,节点2和节点3上启动storage服务
  • >service fdfs_storaged start

Tracker和Storage安装完成,可以使用FastDFS自带的客户端进行上传下载测试,具体操作方法,参考上篇

fastdfs-nginx-module和nginx安装

  • 所有节点安装fastdfs-nginx-module模块
  • fastdfs-nginx-module模块作用:
  • 文件上传到组内一个storage存储后,storage服务会吧文件同步到组内其他storage,这就存在时间延时问题,如果此时客户端通过nginx访问到还未同步完成的组内其他storage会导致文件不存在无法访问错误,fastdfs-nginx-module可以解决该问题的发生,通过重定向到源storage节点来获取文件。
  • root目录解压fastdfs-nginx-module:
  • >unzip fastdfs-nginx-module.zip
  • 安装依赖包:
  • >yum install gcc gcc-c++ make automake autoconf libtool pcre* zlib openssl openssl-devel
  • 安装nginx
  • >tar -zxvf nginx-1.8.1.tar.gz
  • >cd nginx-1.8.1
  • >./configure --prefix=/opt/nginx --add-module=/roo/fastdfs-nginx-module/src
  • >make && make install
  • 复制fastdfs-nginx-module中配置文件到/etc/fdfs目录,并修改配置文件:
  • >cp /root/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs
  • >vi /etc/fdfs/mod_fastdfs.conf
  • tracker_server修改为:
  • tracker_server=192.168.72.135:22122
  • tracker_server=192.168.72.136:22122
  • group_name修改为:
  • 节点1:group_name=group1
  • 节点2:group_name=group1
  • 节点3:group_name=group2
  • url_have_group_name修改为:
  • url_have_group_name = true
  • 复制FastDFS部分配置文件到/etc/fdfs目录:
  • > cd /root/fastdfs-5.1/conf
  • >cp http.conf mime.types /etc/fdfs/
  • 修改nginx.conf配置文件:

  • 启动nginx:
  • >./nginx -c conf/nginx.conf

到此FastDFS集群已经搭建完成,文件上传后可以通过任意storage节点上的nginx来获得文件

实战

  • FastDFS提供了C,PHP和java客户端,选用java客户端来进行实战。
  • 创建maven工程,pom.xml文件添加依赖:
<dependency>
 <groupId>net.oschina.zcx7878</groupId>
 <artifactId>fastdfs-client-java</artifactId>
 <version>1.27.0.0</version>
</dependency>

添加配置文件

  • src/main/resoureces目录下添加fdfs_clent.conf配置文件,内容如下:
connect_timeout = 60
network_timeout = 60
charset = UTF-8
http.tracker_http_port = 8080
http.anti_steal_token = no
#tracker服务地址
tracker_server = 192.168.72.135:22122
tracker_server = 192.168.72.136:22122

创建FdfsClient类

  • 静态代码块:
 private static StorageClient1 storageClient1 = null;
 private static String trackerServerUrl = null;
 //初始化FastDFS Client
 static{
 try{
 ClientGlobal.init("src/main/resources/fdfs_client.conf");
 TrackerClient trackerClient = new TrackerClient(ClientGlobal.g_tracker_group);
 TrackerServer trackerServer = trackerClient.getConnection();
 if (trackerServer == null){
 System.out.println("getConnect return null");
 }
 trackerServerUrl = trackerServer.getInetSocketAddress().getHostString();
 System.out.println("trackerServerUrl" + trackerServerUrl);
 StorageServer storageServer = trackerClient.getStoreStorage(trackerServer);
 if (storageServer == null){
 System.out.println("getStoreStorage return null");
 }
 storageClient1 = new StorageClient1(trackerServer,storageServer);
 }catch (Exception e){
 e.printStackTrace();
 }
 }

文件上传

 public static String uploadFile(File file, String fileExt, Map<String,String> metaList) {
 try {
 byte[] buff = FileUtils.getFileByte(file);
 NameValuePair[] nameValuePairs = null;
 if (metaList != null) {
 nameValuePairs = new NameValuePair[metaList.size()];
 int index = 0;
 for (Iterator<Map.Entry<String,String>> iterator = metaList.entrySet().iterator(); iterator.hasNext();) {
 Map.Entry<String,String> entry = iterator.next();
 String name = entry.getKey();
 String value = entry.getValue();
 nameValuePairs[index++] = new NameValuePair(name,value);
 }
 }
 return "http://"+ trackerServerUrl + "/" + storageClient1.upload_file1(buff, fileExt, nameValuePairs);
 } catch (Exception e) {
 e.printStackTrace();
 }
 return null;
 }

文件下载

 public static int downloadFile(String fileId, String filePath,String fileName) {
 FileOutputStream fos = null;
 try {
 byte[] content = storageClient1.download_file1(fileId);
 FileUtils.getFile(content, filePath, fileName);
 return 0;
 } catch (Exception e) {
 e.printStackTrace();
 } finally {
 if (fos != null) {
 try {
 fos.close();
 } catch (IOException e) {
 e.printStackTrace();
 }
 }
 }
 return -1;
 }

获得文件属性

 public static Map<String,String> getFileMetadata(String fileId) {
 try {
 NameValuePair[] metaList = storageClient1.get_metadata1(fileId);
 if (metaList != null) {
 HashMap<String,String> map = new HashMap<String, String>();
 for (NameValuePair metaItem : metaList) {
 map.put(metaItem.getName(),metaItem.getValue());
 }
 return map;
 }
 } catch (Exception e) {
 e.printStackTrace();
 }
 return null;
 }

文件删除

 public static int deleteFile(String fileId) {
 try {
 return storageClient1.delete_file1(fileId);
 } catch (Exception e) {
 e.printStackTrace();
 }
 return -1;
 }

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表