目录
前言
简介
可 以 跳 过 简 介 部 分 , 直 接 跳 至 安 装 步 骤 \color{red}{可以跳过简介部分,直接跳至安装步骤} 可以跳过简介部分,直接跳至安装步骤
1. 介绍
技术论坛:http://bbs.chinaunix.net/forum-240-1.html
资源地址:https://sourceforge.net/projects/fastdfs/
源码资源:https://github.com/happyflsh100 注,该链接或许失效了
FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网、视频网等等。
粗略介绍,具体可参考百度百科:链接
2. 术语介绍
TrackerServer
:跟踪服务器,主要做调度工作,在访问上起负载均衡的作用,记录storage Server的状态StorageServer
:存储服务器,文件盒meta data都保存到存储服务器上group
:组,也称为卷(等同于window上的C盘)。同组内服务器上的文件是完全相同的文件标识
:包括两部分:组名和文件名(包含路径)meta data
:文件相关属性,键值对(key value pair)方式,如:width=1024,height=768
3. 同步机制
同一组内的storage Server之间是对等的,文件上传,删除等操作可以在任意一台storage Server 上进行;
文件同步只在同组内的storage Server之间进行,采用push方式,即源服务器同步给目标服务器;
源头数据才需要同步,备份数据不需要再次同步,否则就构成环路了;
上述第二条规则有个例外,就是新增一台storage Server时,由已有的一台storage Server将已有的所有数据(包括源头数据和备份数据)同步给该新增服务器
4. FastDFS运行时目录结构
4.1 Tracker Server目录
${base_path}
|__data
| |__storage_groups.dat:存储分组信息
| |__storage_servers.dat:存储服务器列表
|__logs
|__trackerd.log:tracker server日志文件
4.2 storageServer目录
${base_path}
|__data
| |__.data_init_flag:当前storage server 初始化信息
| |__storage_stat.dat:当前storage server统计信息
| |__sync:存放数据同步相关文件
| | |__binlog.index:当前的binlog文件索引号
| | |__binlog.###:存放更新操作记录(日志)
| | |__${ip_addr}_${port}.mark:存放同步的完成情况
| |
| |__一级目录:256个存放数据文件的目录,如:00, 1F
| |__二级目录:256个存放数据文件的目录
|__logs
|__storaged.log:storage server日志文件
5. 同其它文件存储的简单对比
5.1 FastDFS和集中存储方式对比
指标 | FastDFS | NFS | 集中存储设备如:NetApp、NAS |
---|---|---|---|
线性扩容性 | 高 | 高 | 差 |
文件高并发访问性能 | 高 | 高 | 差 |
文件访问方式 | 专用API | POSIX | POSIX |
硬件成本 | 较低 | 中等 | 高 |
相同内文件只保存一份 | 支持 | 不支持 | 不支持 |
5.2 FastDFS和mogileFS对比
指标 | FastDFS | mogileFS |
---|---|---|
系统简洁性 | 简洁 只有两个角色:tracker和storage | 一般 有三个角色:tracker、storage 和存储文件信息的mysql db |
系统性能 | 很高(没有使用数据库,文件同步直接点对点,不经过tracker中转) | 高(是哟给你mysql来存储文件索引信息,文件同步通过tracker调度和中转) |
系统稳定性 | 高(C语言开发,可以支持高并发和高负载) | 一般(peri语言开发,高并发和高负载支持一般) |
RAID方式 | 分组(组内冗余),灵活性大 | 动态冗余,灵活性一般 |
通讯协议 | 专用协议,下载文件支持HTTP | HTTP |
技术文档 | 较详细 | 较少 |
文件附加属性 meta data | 支持 | 支持 |
相同内容文件支保存一份 | 支持 | 不支持 |
下载文件支持文件偏移量 | 支持 | 不支持 |
安装FastDFS
1. 下载所需的安装包并上传到服务器上
2. 安装各种所需工具命令包/依赖
2.1 安装GCC依赖
编译器
sudo yum -y install gcc
2.2 安装unzip工具
unzip工具可以帮我们对压缩包进行解压
sudo yum install -y unzip zip
2.3 安装libevent
sudo yum -y install libevent
- 或许会出现以下问题,不过可以不用理会,具体原因没有深究,不过不影响
2.3 安装Nginx所需依赖
sudo yum -y install pcre pcre-devel zlib zlib-devel openssl openssl-devel
2.4 安装libfastcommon-master
- 这个没有yum包,只能通过解压安装
- 解压上传的
libfastcommon-master.zip
tar -xvf libfastcommon-master.zip
- 若上述命令不生效,则使用如下命令
unzip libfastcommon-master.zip
- 进入解压完成的目录中
cd libfastcommon-master
- 编译并且安装
sudo ./make.sh
sudo ./makesh install
目前为止,依赖已安装完毕,接下来安装FastDFS >>>
3. 安装FastDFS
3.1 编译安装
- 解压
tar -xvf FastDFS_v5.08.tar.gz
- 进入目录
cd FastDFS
- 编译并安装
sudo ./make.sh
sudo ./make.sh install
- 校验安装结果
- 安装完成,我们应该能在/etc/init.d/目录,通过命令ll /etc/init.d/ | grep fdfs看到FastDFS提供的启动脚本:
其中:
fdfs_trackerd
是tracker启动脚本fdfs_storaged
是storage启动脚本
- 我们可以在 /etc/fdfs目录,通过命令查看到以下配置文件模板:
其中:
tarcker.conf.sample
是tracker的配置文件模板storage.conf.sample
是storage的配置文件模板client.conf.sample
是客户端的配置文件模板
3.2 启动tracker
FastDFS的tracker和storage在刚刚的安装过程中,都已经被安装了,因此我们安装这两种角色的方式是一样的。不同的是,两种需要不同的配置文件。
要启动tracker,就修改刚刚看到的tarcker.conf
,并且启动fdfs_trackerd
脚本即可。
- 编辑tracker配置
首先将模板文件进行复制和重命名:
sudo cp tracker.conf.sample tracker.conf
sudo vim tracker.conf
打开tracker.conf
,修改base_path
配置:
base_path=/leyou/fdfs/tracker # tracker的数据和日志存放目录
- 创建目录
刚配置的目录不可能存在,需要创建
sudo mkdir -p /leyou/fdfs/tracker
- 启动tracker
我们可以使用 sh /etc/init.d/fdfs_trackerd 启动,不过安装过程中,fdfs已经被设置为系统服务,我们可以采用熟悉的服务启动方式:
sudo service fdfs_trackerd start # 启动fdfs_trackerd服务,停止用stop
另外,我们可以通过以下命令,设置tracker开机启动:
sudo chkconfig fdfs_trackerd on
3.2 启动storage
要启动tracker,就修改刚刚看到的storage.conf
,并且启动fdfs_storage
脚本即可。
- 编辑storage配置
首先我们将模板文件进行赋值和重命名:
sudo cp storage.conf.sample storage.conf
sudo vim storage.conf
打开storage.conf
,修改base_path
配置:
base_path=/leyou/fdfs/storage # storage的数据和日志存放目录
store_path0=/leyou/fdfs/storage # storage的上传文件存放路径
tracker_server=192.168.xxx.xxx:22122 # tracker的地址, 该ip是服务器ip地址,端口可随意命名
- 创建目录
sudo mkdir -p /leyou/fdfs/storage
- 启动storage
我们可以使用 sh /etc/init.d/fdfs_storaged 启动,同样我们可以用服务启动方式:
sudo service fdfs_storaged start # 启动fdfs_storaged服务,停止用stop
另外,我们可以通过以下命令,设置tracker开机启动:
sudo chkconfig fdfs_storaged on
最后,通过ps -ef | grep fdfs 查看进程:
3.3 还需要更改一处配置(client.conf)
- 模板文件进行赋值和重命名:
sudo cp client.conf.sample client.conf
sudo vim client.conf
- 打开
client.conf
,修改配置:
base_path=/leyou/fdfs/storage # storage的数据和日志存放目录
store_path0=/leyou/fdfs/storage # storage的上传文件存放路径
tracker_server=192.168.xxx.xxx:22122 # tracker的地址, 该ip是服务器ip地址,端口可随意命名
4. 安装Nginx及FastDFS模块
4.1 FastDFS的Nginx模块
- 解压
tar -xvf fastdfs-nginx-module_v1.16.tar.gz
- 配置config文件
# 进入配置目录
cd /home/leyou/fdfs/fastdfs-nginx-module/src/
# 修改配置
vim config
# 执行下面命令(将配置中的/usr/local改为/usr):
:%s+/usr/local/+/usr/+g
- 配置mod_fastdfs.conf
# 将src目录下的mod_fastdfs.conf复制到 /etc/fdfs目录:
sudo cp mod_fastdfs.conf /etc/fdfs/
# 编辑该文件
sudo vim /etc/fdfs/mod_fastdfs.cof
- 修改一下配置:
connect_timeout=10 # 客户端访问文件连接超时时长(单位:秒)
tracker_server=192.168.xxx.xxx:22122 # tracker服务IP和端口
url_have_group_name=true # 访问链接前缀加上组名
store_path0=/leyou/fdfs/storage # 文件存储路径
- 复制 FastDFS的部分配置文件到/etc/fdfs目录
cd /home/leyou/fdfs/FastDFS/conf/
cp http.conf mime.types /etc/fdfs/
4.2 安装Nginx
- 解压
tar -xvf nginx-1.10.0.tar.gz
- 配置
sudo ./configure --prefix=/opt/nginx --sbin-path=/usr/bin/nginx --add-module=/home/leyou/fdfs/fastdfs-nginx-module/src
- 编译安装
sudo make && sudo make install
- 配置nginx整合fastdfs-module模块
我们需要修改nginx配置文件,在/opt/nginx/config/nginx.conf文件中:
sudo vim /opt/nginx/conf/nginx.conf
- 将文件中,原来的
server 80{ ...}
部分代码替换为如下代码:
server {
listen 80;
server_name image.taotao.com;
# 监听域名中带有group的,交给FastDFS模块处理
location ~/group([0-9])/ {
ngx_fastdfs_module;
}
location / {
root html;
index index.html index.htm;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
- 启动
nginx # 启动
nginx -s stop # 停止
nginx -s reload # 重新加载配置
- 设置nginx开机启动(非必要)
创建一个开机启动的脚本:
vim /etc/init.d/nginx
添加以下内容:
#!/bin/sh
#
# nginx - this script starts and stops the nginx daemon
#
# chkconfig: - 85 15
# description: NGINX is an HTTP(S) server, HTTP(S) reverse \
# proxy and IMAP/POP3 proxy server
# processname: nginx
# config: /etc/nginx/nginx.conf
# config: /etc/sysconfig/nginx
# pidfile: /var/run/nginx.pid
# Source function library.
. /etc/rc.d/init.d/functions
# Source networking configuration.
. /etc/sysconfig/network
# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0
nginx="/usr/bin/nginx"
prog=$(basename $nginx)
NGINX_CONF_FILE="/opt/nginx/conf/nginx.conf"
[ -f /etc/sysconfig/nginx ] && . /etc/sysconfig/nginx
lockfile=/var/lock/subsys/nginx
make_dirs() {
# make required directories
user=`$nginx -V 2>&1 | grep "configure arguments:.*--user=" | sed 's/[^*]*--user=\([^ ]*\).*/\1/g' -`
if [ -n "$user" ]; then
if [ -z "`grep $user /etc/passwd`" ]; then
useradd -M -s /bin/nologin $user
fi
options=`$nginx -V 2>&1 | grep 'configure arguments:'`
for opt in $options; do
if [ `echo $opt | grep '.*-temp-path'` ]; then
value=`echo $opt | cut -d "=" -f 2`
if [ ! -d "$value" ]; then
# echo "creating" $value
mkdir -p $value && chown -R $user $value
fi
fi
done
fi
}
start() {
[ -x $nginx ] || exit 5
[ -f $NGINX_CONF_FILE ] || exit 6
make_dirs
echo -n $"Starting $prog: "
daemon $nginx -c $NGINX_CONF_FILE
retval=$?
echo
[ $retval -eq 0 ] && touch $lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
killproc $prog -QUIT
retval=$?
echo
[ $retval -eq 0 ] && rm -f $lockfile
return $retval
}
restart() {
configtest || return $?
stop
sleep 1
start
}
reload() {
configtest || return $?
echo -n $"Reloading $prog: "
killproc $nginx -HUP
RETVAL=$?
echo
}
force_reload() {
restart
}
configtest() {
$nginx -t -c $NGINX_CONF_FILE
}
rh_status() {
status $prog
}
rh_status_q() {
rh_status >/dev/null 2>&1
}
case "$1" in
start)
rh_status_q && exit 0
$1
;;
stop)
rh_status_q || exit 0
$1
;;
restart|configtest)
$1
;;
reload)
rh_status_q || exit 7
$1
;;
force-reload)
force_reload
;;
status)
rh_status
;;
condrestart|try-restart)
rh_status_q || exit 0
;;
*)
echo $"Usage: $0 {start|stop|status|restart|condrestart|try-restart|reload|force-reload|configtest}"
exit 2
esac
- 修改文件权限,并加入服务列表
# 修改权限
chmod 777 /etc/init.d/nginx
# 添加到服务列表
chkconfig --add /etc/init.d/nginx
- 设置开机启动
chkconfig nginx on
5. 测试
5.1 基于服务器上测试
/usr/bin/fdfs_test /etc/fdfs/client.conf upload /home/logo.jpg
5.2 springboot进行测试
创建springboot项目,百度
- 引入jar包
<dependency>
<groupId>com.github.tobato</groupId>
<artifactId>fastdfs-client</artifactId>
<version>1.26.1-RELEASE</version>
</dependency>
- 配置文件
fdfs:
connect-timeout: 600
so-timeout: 2500
thumb-image:
height: 60
width: 60
tracker-list:
- 192.168.xxx.xxx:22122
- 配置类
@Configuration
@Import(FdfsClientConfig.class)
// 解决jmx重复注册bean的问题
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
public class FastdfsImporter {
// 导入依赖组件
}
- 上传接口
@PostMapping("image")
public String uploadImage(@RequestParam("file") MultipartFile file) {
//保存图片
try {
String extensionName = StringUtils.substringAfterLast(file.getOriginalFilename(), ".");
StorePath storePath = storageClient.uploadFile(file.getInputStream(), file.getSize(), extensionName, null);
//返回保存图片的完整url
return storePath.getFullPath();
} catch (IOException e) {
throw new RuntimeException();
}
}
- 成功后返回:
- 生成文件名
当文件存储到某个子目录后,即认为该文件存储成功,接下来会为给该文件生成一个文件名,文件名由group名称/存储目录/两级目录/file_id.后缀名 拼接而成。 group
:组名/卷名。文件上传成功以后所在的storage组名称,由storage服务返回。M00
:虚拟磁盘路径。与storage配置文件中磁盘选项store_path*
对应。如果配置了storage_path0
则是M00
,如果配置了store_path1
则是M01
,以此类推。比如:store_path = /fastdfs/storage/store
,M00
则表示:/fastdfs/storage/store/data
。/00/00
:数据两级目录。storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。.jpg的前缀
:file_id,由storage server IP、文件创建时间、文件大小、文件crc32和一个随记数组成,然后将这个二进制串进行base64编码,转换为字符串。返回的这一串数字就是文件名
:
6. 问题
6.1 本地上传测试不成功如图
- 修改
/etc/fdfs/client.conf
配置文件,查看3.4
步
6.2 查看nginx是否安装成功
6.3 本地上使用访问虚拟机上图片,成功后
6.4 如不能访问,或连接不上,测试需要开放端口或关闭防火墙,如:22122,80,23000
- 命令
# 查看防火墙状态
systemctl status firewalld
# 关闭防火墙
systemctl firewalld stop
# 对外开放某个端口
firewall-cmd --zone=public --add-port=80/tcp --permanent
参考资料
防火墙命令文章
FastDFS+阿里OOS文章
网路上的项目