赞
踩
FastDFS所需软件:
链接: https://pan.baidu.com/s/15Lm9qWxmoyY1Mqz9pdCG9w 提取码: 99bg
分布式文件系统解决了海量文件存储及传输访问的瓶颈问题,对海量视频的管理、对海量图片的管理等。
分布式文件系统(Distributed File System)是指文件系统管理的物理存储资源不一定直接连接在本地节点上, 而是通过计算机网络与节点相连。
存在问题
分布式文件系统是面对互联网的需求而产生,互联网时代对海量数据如何存储?
靠简单的增加硬盘的个数已经满足 不了我们的要求,因为硬盘传输速度有限但是数据在急剧增长,
另外我们还要要做好数据备份、数据安全等。
解决办法
采用分布式文件系统可以将多个地点的文件系统通过网络连接起来
组成一个文件系统网络,结点之间通过网络进 行通信
一台文件系统的存储和传输能力有限,我们让文件在多台计算机上存储,通过多台计算共同传输
示例图
好处
一台计算机的文件系统处理能力扩充到多台计算机同时处理
一台计算机挂了还有另外副本计算机提供数据。
每台计算机可以放在不同的地域,这样用户就可以就近访问,提高访问速度
简介
FastDFS是用c语言编写的一款开源的分布式文件系统,它是由淘宝资深架构师余庆编写并开源。
FastDFS专为互联 网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,
使用FastDFS很 容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务
为什么要使用fastDFS
通用分布式文件系统
NFS、GFS都是通用的分布式文件系统
通用的分布式文件系统的优点的是开发体验好,但是系统复杂 性高、性能一般
|
专用分布式文件系统
专用的分布式文件系统虽然开发体验性差,但是系统复杂性低并且性能高。
fastDFS非常适合 存储图片等那些小文件,fastDFS不对文件进行分块,
所以它就没有分块合并的开销,fastDFS网络通信采用 socket,通信速度很快
FastDFS架构包括 Tracker server和Storageserver。
客户端请求Tracker server进行文件上传、下载,通过Tracker server调度最终由Storage server完成文件上传和下载。
结构图
作用:
- Tracker Server作用是负载均衡和调度,
- 通过Tracker server在文件上传时可以根据一些策略找到Storage server提 供文件上传服务。
- 可以将tracker称为追踪服务器或调度服务器。
集群:
FastDFS集群中的Tracker server可以有多台
Tracker server之间是相互平等关系同时提供服务.
客户端请求Tracker server采用轮询方式,如果请求的tracker无法提供服务则换另一个tracker。
作用:
Storage Server作用是文件存储,客户端上传的文件最终存储在Storage服务器上
集群
Storage集群采用了分组存储方式。storage集群由一个或多个组构成,集群存储总容量为集群中所有组的存储容 量之和
一个组由一台或多台存储服务器组成,组内的Storage server之间是平等关系,
不同组的Storage server 之间不会相互通信
同组内的Storage server之间会相互连接进行文件同步,从而保证同组内每个storage上的文件 完全一致的
一个组的存储容量为该组内的存储服务器容量最小的那个
采用分组存储方式的好处
灵活、可控性较强。比如上传文件时,可以由客户端直接指定上传到的组也可以由 tracker进行调度选择。
一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务能力(纵向 扩容)
当系统容量不足时,可以增加组来扩充存储容量(横向扩容)。
Storage状态收集
Storage server会连接集群中所有的Tracker server,定时向他们报告自己的状态,
包括磁盘剩余空间、文件同步 状况、文件上传下载次数等统计信息。
FastDFS是 C 语言开发,建议在 linux 上运行
安装 FastDFS需要先将官网下载的源码进行编译,编译依赖 gcc 环境
yum install gcc-c++
FastDFS依赖libevent库
yum -y install libevent
libfastcommon 是 FastDFS 官方提供的,libfastcommon 包含了 FastDFS 运行所需要的一些基础库
将libfastcommonV1.0.7.tar.gz拷贝至/usr/local/下
解压libfastcommonV1.0.7.tar.gz
tar -zxvf libfastcommonV1.0.7.tar.gz
执行以下命令
cd libfastcommon-1.0.7
./make.sh
./make.sh install
libfastcommon安装好后会自动将库文件拷贝至/usr/lib64下
由于FastDFS程序引用usr/lib目录
所以需要将/usr/lib64下的库文件拷贝至/usr/lib下。
ll /usr/lib64/
上传 libevent到服务器中
执行以下命令
解压
tar -zxvf libevent-2.0.15-stable.tar.gz
进入 libevent目录
cd libevent-2.0.15-stable/
执行
第一步: ./configure
第二步:make && make install
第三步:ln -s /usr/local/lib/libevent-2.0.so.5 /usr/lib/libevent-2.0.so.5
将FastDFS_v5.05.tar.gz拷贝至/usr/local/下
解压:
tar -zxvf FastDFS_v5.05.tar.gz
进入FastDFS目录
cd FastDFS
执行以下命令
./make.sh
./make.sh install
安装成功将安装目录下的conf下的文件拷贝到/etc/fdfs/下
cp -ri conf/* /etc/fdfs
进入/etc/fdfs目录
cd /etc/fdfs
修改tracker.conf
vim tracker.conf
base_path=/home/fastdfs
http.server_port=80
创建目录
mkdir -p /home/fastdfs
启动
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
查看是否启动
ps aux|grep dfs
执行 修改配置文件
vim storage.conf
- group_name=group1
- base_path=/home/yuqing/FastDFS改为:base_path=/home/fastdfs
- store_path0=/home/fastdfs/fdfs_storage
- tracker_server=192.168.0.108:22122 #配置 tracker服务器:IP如果有多个则配置多个tracke
- http.server_port=80
创建文件夹:
mkdir -p /home/fastdfs/fdfs_storage
启动
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
流程图
文件信息
客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。
文件索引信息 包括:组名,虚拟磁盘路径,数据两级目录,文件名
mvn install:install-file -DgroupId=org.csource.fastdfs -DartifactId=fastdfs -Dversion=1.2 -Dpackaging=jar -Dfile=fastdfs_client_v1.20.jar
<dependency>
<groupId>org.csource.fastdfs</groupId>
<artifactId>fastdfs</artifactId>
<version>1.2</version>
</dependency>
# connect timeout in seconds # default value is 30s connect_timeout=30 # network timeout in seconds # default value is 30s network_timeout=60 # the base path to store log files base_path=/home/fastdfs # tracker_server can ocur more than once, and tracker_server format is # "host:port", host can be hostname or ip address tracker_server=192.168.0.108:22122 #standard log level as syslog, case insensitive, value list: ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level=info # if use connection pool # default value is false # since V4.05 use_connection_pool = false # connections whose the idle time exceeds this time will be closed # unit: second # default value is 3600 # since V4.05 connection_pool_max_idle_time = 3600 # if load FastDFS parameters from tracker server # since V4.05 # default value is false load_fdfs_parameters_from_tracker=false # if use storage ID instead of IP address # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # default value is false # since V4.05 use_storage_id = false # specify storage ids filename, can use relative or absolute path # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # since V4.05 storage_ids_filename = storage_ids.conf #HTTP settings http.tracker_server_port=80 #use "#include" directive to include HTTP other settiongs ##include http.conf
public static void main(String[] args) throws Exception { //1. 加载配置文件 ClientGlobal.init("src/main/resources/fdfs_client.conf"); //2. 创建管理端对象 TrackerClient trackerClient = new TrackerClient(); //3. 通过管理端对象获取连接 TrackerServer connection = trackerClient.getConnection(); //4. 创建存储端对象 StorageClient1 storageClient = new StorageClient1(connection, null); //创建文件属性信息对象数组 NameValuePair[] meta_list = new NameValuePair[3]; meta_list[0] = new NameValuePair("fileName","time"); meta_list[1] = new NameValuePair("ExtName","jpg"); meta_list[2] = new NameValuePair("zuozhe","joker"); //5. 上传文件 String path = storageClient.upload_file1("C:\\Users\\Joker_DJ\\Pictures\\timg.jpg", "jpg", meta_list); System.out.println("======" + path); }
启动测试
查看文件存放目录
cd /home/fastdfs/fdfs_storage/data/00/00
在storage server上安装nginx的目的是对外通过http访问storage server 上的文件
使用 nginx 的模块 FastDFS-nginx-module 的作用是通过 http 方式访问 storage 中的文件
将 FastDFS-nginx-module_v1.16.tar.gz上到usr/local下
解压
tar -zxvf fastdfs-nginx-module_v1.16.tar.gz
进入src目录
cd fastdfs-nginx-module/src
修改config文件将/usr/local/路径改为/usr/
vim config
将FastDFS-nginx-module/src下的mod_FastDFS.conf拷贝至/etc/fdfs/下
cp mod_fastdfs.conf /etc/fdfs/
修改mod_fastdfs.conf
vim /etc/fdfs/mod_fastdfs.conf
- base_path=/home/fastdfs
- tracker_server=192.168.0.108:22122
- url_have_group_name=true
- store_path0=/home/fastdfs/fdfs_storage
esc后保存并退出 :wq
将libfdfsclient.so拷贝至/usr/lib下
cp /usr/lib64/libfdfsclient.so /usr/lib/
复制 FastDFS的部分配置文件到/etc/fdfs目录
cd /usr/local/FastDFS/conf/
cp http.conf mime.types /etc/fdfs/
将nginx-1.8.1.tar.gz拷贝到/usr/local下
解压nginx-1.8.1.tar.gz
tar -zxvf nginx-1.8.1.tar.gz
依赖包
sudo yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel
进入nginx目录
cd nginx-1.8.1/
执行配置
./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/usr/local/fastdfs-nginx-module/src
在 nginx-1.8.1目录下依次执行
make
make install
useradd -s /sbin/nologin -M nginx
id nginx
启动ngnix
nginx
停止nginx
nginx -s stop
重新加载配置
nginx -s reload
查看是否启动
ps -ef|grep nginx
修改配置文件
vim /opt/nginx/conf/nginx.conf
# 监听域名中带有group的,交给FastDFS模块处理
location ~/group([0-9])/ {
ngx_fastdfs_module;
}
重新加载配置
nginx -s reload
查看是否生效
在主机通过ip地址访问nginx
http://192.168.0.108
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
nginx
http://192.168.0.108/group1/M00/00/00/wKgAbF8pL5KAUR9AAABCFe5hWE4513.jpg
虚拟机每次启动之后都要重新启动FastDFS和nginx,比较麻烦所以增加开机自启
在centos7 /etc/rc.d/rc.local 文件的权限被降低了,所以给rc.local文件增加可执行的权限
执行命令:chmod +x /etc/rc.d/rc.local
编辑 /etc/rc.d/rc.local文件,增加启动项
编写上传按钮事件
注意开启SpringMVC的媒体解析器
<!-- 配置多媒体解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<!-- 设定文件上传的最大值5MB,5*1024*1024 -->
<property name="maxUploadSize" value="5242880"></property>
</bean>
<dependency>
<groupId>org.csource.fastdfs</groupId>
<artifactId>fastdfs</artifactId>
<version>1.2</version>
</dependency>
FILE_SERVER_URL=http://192.168.0.108/
新建fastDFS配置文件夹
fdfs_client.conf
# connect timeout in seconds # default value is 30s connect_timeout=30 # network timeout in seconds # default value is 30s network_timeout=60 # the base path to store log files base_path=/home/fastdfs # tracker_server can ocur more than once, and tracker_server format is # "host:port", host can be hostname or ip address tracker_server=192.168.0.108:22122 #standard log level as syslog, case insensitive, value list: ### emerg for emergency ### alert ### crit for critical ### error ### warn for warning ### notice ### info ### debug log_level=info # if use connection pool # default value is false # since V4.05 use_connection_pool = false # connections whose the idle time exceeds this time will be closed # unit: second # default value is 3600 # since V4.05 connection_pool_max_idle_time = 3600 # if load FastDFS parameters from tracker server # since V4.05 # default value is false load_fdfs_parameters_from_tracker=false # if use storage ID instead of IP address # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # default value is false # since V4.05 use_storage_id = false # specify storage ids filename, can use relative or absolute path # same as tracker.conf # valid only when load_fdfs_parameters_from_tracker is false # since V4.05 storage_ids_filename = storage_ids.conf #HTTP settings http.tracker_server_port=80 #use "#include" directive to include HTTP other settiongs ##include http.conf
<context:property-placeholder location="classpath:config/application.properties" />
import org.apache.commons.io.FilenameUtils; import org.csource.common.NameValuePair; import org.csource.fastdfs.*; import java.io.IOException; public class FastDFSClient { private TrackerClient trackerClient = null; private TrackerServer trackerServer = null; private StorageServer storageServer = null; private StorageClient1 storageClient = null; public FastDFSClient(String conf) throws Exception { if (conf.contains("classpath:")) { conf = conf.replace("classpath:", this.getClass().getResource("/").getPath()); } ClientGlobal.init(conf); trackerClient = new TrackerClient(); trackerServer = trackerClient.getConnection(); storageServer = null; storageClient = new StorageClient1(trackerServer, storageServer); } /** * @param file 文件二进制 * @param fileName 文件名 * @param fileSize 文件大小 * @return * @throws Exception */ public String uploadFile(byte[] file, String fileName, long fileSize) throws Exception { NameValuePair[] metas = new NameValuePair[3]; metas[0] = new NameValuePair("fileName", fileName); metas[1] = new NameValuePair("fileSize", String.valueOf(fileSize)); metas[2] = new NameValuePair("fileExt", FilenameUtils.getExtension(fileName)); String result = storageClient.upload_file1(file, FilenameUtils.getExtension(fileName), metas); return result; } /** * * @param storagePath 文件的全部路径 如:group1/M00/00/00/wKgRsVjtwpSAXGwkAAAweEAzRjw471.jpg * @return -1失败,0成功 * @throws Exception */ public Integer delete_file(String storagePath){ int result=-1; try { result = storageClient.delete_file1(storagePath); } catch (Exception e) { e.printStackTrace(); } return result; } }
@RestController @RequestMapping("/upload") public class UploadController { @Value("${FILE_SERVER_URL}") private String FILE_SERVER; @RequestMapping("/uploadFile") public Result uploadFile(MultipartFile file) throws Exception { try { FastDFSClient fastDFS = new FastDFSClient("classpath:fastDFS/fdfs_client.conf"); //上传文件返回文件保存的路径和文件名 String path = fastDFS.uploadFile(file.getBytes(), file.getOriginalFilename(), file.getSize()); /** 保存数据库... */ //拼接上服务器的地址返回给前端 return new Result(true, FILE_SERVER + path); } catch (Exception e) { e.printStackTrace(); return new Result(false, "上传失败!"); } } }
/*删除图片*/ @RequestMapping("/delteImage") public Result delteImage(String url){ try { String path = url.substring(FILE_SERVER.length()); FastDFSClient fastDFS =new FastDFSClient("classpath:fastDFS/fdfs_client.conf"); Integer integer = fastDFS.delete_file(path); if (integer == 0){ return new Result(true, "删除成功"); }else { return new Result(false, "删除失败"); } } catch (Exception e) { return new Result(false, "删除失败"); } }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。