Java高级架构之FastDFS分布式文件集群详解
fastdfs简介fastdfs是一款开源的轻量级分布式文件系统,使用c实现,支持linux、bsd等unix-like操作系统。值得注意的是,fastdfs并不是通用的文件系统,只能通过专用的api访问。
fastdfs为互联网应用量身定做,解决了大容量文件存储的问题,fastdfs追求高性能和高扩展性。fastdfs的主要概念:
tracker-server:跟踪服务器。用于跟踪文件,主要起调度作用。在内存中记录了所有存储组和存储服务器的状态信息,是客户端和数据存储的主要枢纽。相比gfs更为精简,因为不记录文件索引。
storage-server: 存储服务器。用于存储文件。直接使用操作系统的文件系统来管理和组织文件。
group: 组,卷。多个服务器存在一个组中,在一个组中的服务器存储的文件是完全相同的,并且同一个组的服务器地位是对等的。对于文件的操作可以在任意一个组中的服务器上进行。
metadata: 元数据。以键值对的方式存储,用于存储文件的相关信息。
各大存储系统的对比
话说没有对比就没有伤害,fastdfs也不是万能的,需要根据业务来选择适合的存储系统。
存储系统适合存储的文件类型文件分布情况系统性能复杂度fuse(用户文件系统)posix()备份机制通讯协议接口社区情况实现语言fastdfs4kb至500mb将小文件合并存储很高简单不支持不支持组内冗余备份http api国内用户ctfs所有文件小文件合并以块组织分片-复杂不支持不支持块存储多份,主辅灾备http api少c++mfs大于64k分片存储master节点占用内存较高-支持支持多点备份,动态冗余使用fuse挂载较多perlhdfs大文件大文件分片块存储-简单支持支持多副本原生api较多javaceph对象大文件osd一主多从-复杂支持支持多副本原生api较少c++mogilefs海量小图片-高复杂支持不支持动态冗余原生api文档少perlclusterfs大文件--简单支持支持--多cgithub项目主页:https://github.com/happyfish100/fastdfs
fastdfs客户端与服务器端交互原理
fastdfs+nginx整合
架构图
安装fastdfs
mkdir /source
cd /source
yum install -y gcc gcc-c++ make cmake wget libevent
wget https://github.com/happyfish100/libfastcommon/archive/v1.0.35.tar.gz
wget https://github.com/happyfish100/fastdfs/archive/v5.10.tar.gz
tar -zxvf v1.0.35.tar.gz
tar -zxvf v5.10.tar.gz
cd libfastcommon-1.0.35
./make.sh
./make.sh install
ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
cd ../
cd fastdfs-5.10/
./make.sh
./make.sh install
cd ../
rm -rf libfastcommon-1.0.35
rm -rf fastdfs-5.10
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
mkdir -p /data/fdfs/tracker
mkdir -p /data/fdfs/storage
ln -s /usr/bin/stop.sh /usr/local/bin/stop.sh
ln -s /usr/bin/restart.sh /usr/local/bin/restart.sh
修改配置文件
修改跟踪器配置文件:
base_path=/data/fdfs/tracker
修改存储器配置文件:
base_path=/data/fdfs/storage
store_path0=/data/fdfs/storage
tracker_server=192.168.80.3:22122
修改客户端配置文件:
base_path=/data/fdfs/client
tracker_server=192.168.80.3:22122
启动
/etc/init.d/fdfs_trackerd start
/etc/init.d/fdfs_storaged start
netstat -tunlap | grep :22122
tcp 0 0 0.0.0.0:22122 0.0.0.0:* listen 7247/fdfs_trackerd
tcp 0 0 192.168.80.3:22122 192.168.80.3:39318 established 7247/fdfs_trackerd
tcp 0 0 192.168.80.3:39318 192.168.80.3:22122 established 7444/fdfs_storaged
启动后要查看状态, 出现 active (exited) 字样可以尝试重启服务。
测试
/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /source/fastdfs_v5.05.tar.gz
group1/m00/00/00/wkhqa1ysjsgapjxbaavfol7fju4.tar.gz
文件存储在:
ll /data/fdfs/storage/data/00/00/wkhqa1ysjsgapjxbaavfol7fju4.tar.gz
安装nginx并配置模块
# 安装nginx需要的pcre(perl兼容正则表达式)库,允许nginx使用rewrite模块提供url重写功能。
yum install pcre pcre-devel perl-extutils-embed -y
# 安装openssl-devel,允许nginx提供https服务。
yum install openssl-devel -y
# 下载软件包
cd /source
wget http://59.80.44.46/nginx.org/download/nginx-1.14.2.tar.gz
wget http://nchc.dl.sourceforge.net/project/fastdfs/fastdfs%20nginx%20module%20source%20code/fastdfs-nginx-module_v1.16.tar.gz
# 解压软件包
tar xvf nginx-1.14.2.tar.gz
tar xvf fastdfs-nginx-module_v1.16.tar.gz
# 创建必要的软连接
ln -s /usr/include/fastdfs/ /usr/local/include/fastdfs
ln -s /usr/include/fastcommon/ /usr/local/include/fastcommon
cp fastdfs/conf/http.conf /etc/fdfs/
cp fastdfs/conf/mime.types /etc/fdfs/
cp fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
mkdir -p /data/fdfs/fastdfs-nginx-module
修改配置文件 /etc/fdfs/mod_fastdfs.conf :
connect_timeout=10
base_path=/data/fdfs/fastdfs-nginx-module
# 配置服务器的地址
tracker_server=192.168.80.3:22122
url_have_group_name = true
store_path0=/data/fdfs/storage
mkdir /applications
mkdir /tmp/nginx
useradd nginx -s /sbin/nologin -m
cd nginx-1.14.2
./configure \
--user=nginx \
--group=nginx \
--prefix=/applications/nginx-1.14.2 \
--with-http_ssl_module \
--with-http_gzip_static_module \
--http-client-body-temp-path=/tmp/nginx/client \
--http-proxy-temp-path=/tmp/nginx/proxy \
--http-fastcgi-temp-path=/tmp/nginx/cgi \
--with-poll_module \
--with-file-aio \
--with-http_realip_module \
--with-http_addition_module \
--with-http_random_index_module \
--with-pcre \
--with-http_stub_status_module \
--with-stream \
--add-module=/source/fastdfs-nginx-module/src
make
make install
ln -s /applications/nginx-1.14.2/ /applications/nginx
chown -r nginx.nginx /applications/nginx
chown -r nginx.nginx /applications/nginx-1.14.2/
chown -r nginx.nginx /tmp/nginx/
修改配置文件 /applications/nginx/conf/nginx.conf , 在http区块添加:
server {
listen 8000;
server_name media;
location / {
roothtml;
index index.html index.htm;
}
# 拦截文件请求,转发到下面的模块
location ~/group {
ngx_fastdfs_module;
}
error_page500 502 503 504 /50x.html;
location = /50x.html {
roothtml;
}
}
测试配置文件正确性并启动:
/applications/nginx/sbin/nginx -t
/applications/nginx/sbin/nginx
删除临时文件:
rm -rf fastdfs
rm -rf fastdfs-nginx-module
rm -rf libfastcommon-1.0.35
rm -rf nginx-1.14.2
测试nginx文件下载功能, 在浏览器输入: http://192.168.80.3:8000/group1/m00/00/00/wkhqa1ysjsgapjxbaavfol7fju4.tar.gz
一个nginx只能访问一个storage服务器的数据,所以多个storage服务器要配置多个nginx,然后将nginx按照请求路径中的组id(groupid)进行路由。
简单的启动停止服务的脚本:
# start-service
# usage: ./start-service
echo "============================================sync datetime==========================================="
ntpdate time7.aliyun.com
echo "===========================================getting status==========================================="
/etc/init.d/fdfs_trackerd status
/etc/init.d/fdfs_storaged status
echo "==========================================starting service=========================================="
/etc/init.d/fdfs_storaged start
/etc/init.d/fdfs_trackerd start
echo "===========================================getting status==========================================="
/etc/init.d/fdfs_trackerd status
/etc/init.d/fdfs_storaged status
echo "=========================================testing config file========================================"
/applications/nginx/sbin/nginx -t
echo "=========================================starting web server========================================"
/applications/nginx/sbin/nginx
echo "=======================================getting network status======================================="
sleep 5s
netstat -tunlap | grep :22122
netstat -tunlap | grep :8000
# stop-service
# usage: ./stop-service
echo "===========================================getting status==========================================="
/etc/init.d/fdfs_trackerd status
/etc/init.d/fdfs_storaged status
echo "==========================================stopping service=========================================="
/etc/init.d/fdfs_storaged stop
/etc/init.d/fdfs_trackerd stop
echo "========================================stopping web server========================================="
kill `cat /applications/nginx/logs/nginx.pid`
echo "===========================================getting status==========================================="
/etc/init.d/fdfs_trackerd status
/etc/init.d/fdfs_storaged status
echo "=======================================getting network status======================================="
sleep 5s
netstat -tunlap | grep :22122
netstat -tunlap | grep :8000
基于token的防盗链实现
fastdfs内置使用token的方式实现防盗链,token是带有时效性的,token中包含了文件id、时间戳ts和token。在fastdfs中使用url带上ts和token的方式请求资源。在fastdfs中提供了生成token的算法,扩展模块会对token进行验证。由于token的生成和校验都在服务器端,因此不会存在安全性问题。链接示例:
http://192.168.1.15:8080/group1/m01/01/01/wkgbd01c15nvku1caabaoecdfs466570.c?token=b32cd06a53dea4376e43d71cc882f9cb&ts=1297930137
在 /etc/fdfs/http.conf 中修改:
# 开启token校验
http.anti_steal.check_token=true
# token的声明周期为240秒
http.anti_steal.token_ttl=240
# 加密字符串,可以使用 openssl rand -base64 64 生成
http.anti_steal.secret_key=2scpwmpctxhblvoyb0jyuyqzytoofmfcbiye65n56ppyvwrntxzlidbpdvddljm8qhhkxsgwtcr+9vdg3yptkw
# token校验失败的时候返回的图片
http.anti_steal.token_check_fail=/data/fdfs/error.svg
使用java客户端验证:
将客户端安装到本地仓库:
git clone https://github.com/happyfish100/fastdfs-client-java.git
cd fastdfs-client-java
mvn clean install
使用maven创建一个普通的项目,在pom文件中添加依赖:
<dependencies>
<dependency>
<groupid>org.csource</groupid>
<artifactid>fastdfs-client-java</artifactid>
<version>1.27-snapshot</version>
</dependency>
</dependencies>
在resources目录下创建fastdfs配置文件 fastdfs-client.properties :
fastdfs.connect_timeout_in_seconds = 5
fastdfs.network_timeout_in_seconds = 30
fastdfs.charset = utf-8
fastdfs.http_anti_steal_token = true
fastdfs.http_secret_key = 2scpwmpctxhblvoyb0jyuyqzytoofmfcbiye65n56ppyvwrntxzlidbpdvddljm8qhhkxsgwtcr+9vdg3yptkw
fastdfs.http_tracker_http_port = 8080
fastdfs.tracker_servers = 192.168.80.3:22122
创建 com.bluemiaomiao.demo.java 类文件:
package com.bluemiaomiao;
import org.csource.common.myexception;
import org.csource.fastdfs.clientglobal;
import org.csource.fastdfs.protocommon;
import java.io.ioexception;
import java.security.nosuchalgorithmexception;
import java.util.properties;
public class demo {
public static void main(string[] args) throws ioexception, myexception, nosuchalgorithmexception {
// 加载配置文件
properties prop = new properties();
prop.load(demo.class.getresourceasstream("/fastdfs-client.properties"));
clientglobal.initbyproperties(prop);
// 显示初始化配置信息
system.out.println(clientglobal.configinfo());
// 使用文件上传工具返回的地址,一般情况下保存在数据库中
string remotefilename = "group1/m00/00/00/wkhqa1ysjsgapjxbaavfol7fju4.tar.gz";
// 获取当前时间戳
int ts = (int)(system.currenttimemillis()/1000);
// 获取token, 传入的文件id不要含有分组信息
string token = protocommon.gettoken("m00/00/00/wkhqa1ysjsgapjxbaavfol7fju4.tar.gz", ts, prop.getproperty("fastdfs.http_secret_key"));
// 使用浏览器访问返回的url
system.out.println("http://192.168.80.3:8000/" + remotefilename + "?token=" + token + "&ts=" + ts);
}
}
如果访问时显示防盗链图片,可能是测试客户端与服务器之间的之间有一定差距,两个主机之间不能有分钟级别的差距,可以使用如下方法同步服务器:
# 安装同步时间服务器的客户端, windows系统也需要与该服务器同步
# 控制面板->时钟和区域->设置日期和时间->internet时间->更改设置
yum install ntpdate
ntpdate time7.aliyun.com
整合fastdht实现数据去重
fastdht是分布式哈希系统(dht),使用berkeleydb做数据存储,使用libevent做网络io处理。依赖于libfastcommon组件。
下载
去oracle官方网站下载 berkeley db 数据库,去fastdfs的github主页下载fastdht的源码包。由于之前已经安装过linevent和libfastcommon,因此只需要安装数据库和fastdht即可。
安装配置数据库与fastdht
tar -xvf db-6.2.23.tar.gz
cd db-6.2.23/build_unix/
../dist/configure --prefix=/applications/db-6.2.23
cd ../../
rm -rf db-6.2.23
unzip fastdht-master.zip
cd fastdht-master
vim make.sh
修改第27行代码:
cflags='-wall -d_file_offset_bits=64 -d_gnu_source -i /applications/db-6.2.23/include/ -l /applications/db-6.2.23/lib/'
-i : 指定数据库提供的头文件目录
-l : 指定数据库提供的库文件目录
./make.sh
./make.sh install
cd ../
rm -rf fastdht-master
配置
mkdir /data/fdht
修改 /etc/fdht/fdht_client.conf 内容:
base_path=/data/fdht
#include /etc/fdht/fdht_servers.conf
修改 /etc/fdht/fdht_servers.conf 内容:
group0 = 192.168.80.3:11411
修改 /etc/fdht/fdhtd.conf 内容:
base_path=/data/fdht
#include /etc/fdht/fdht_servers.conf
修改 /etc/fdfs/storage.conf 内容:
check_file_duplicate=1
key_namespace=fastdfs
keep_alive=1
#include /etc/fdht/fdht_servers.conf
主要需要包含服务器端配置文件。
ln -s /applications/db-6.2.23/lib/libdb-6.2.so /usr/lib/libdb-6.2.so
ln -s /applications/db-6.2.23/lib/libdb-6.2.so /usr/lib64/libdb-6.2.so
启动并测试
fdhtd /etc/fdht/fdhtd.conf
重启使用:
fdhtd /etc/fdht/fdhtd.conf restart
查看结果:
netstat -tunlap | grep :11411
tcp 0 0 0.0.0.0:11411 0.0.0.0:* listen 20605/fdhtd
由于安装fastdht的时候关闭了fastdfs,因此需要启动fastdfs
./start-service
修改之前的 start-service 脚本, 在启动tracker和storage服务之前添加:
fdhtd /etc/fdht/fdhtd.conf
在查看tracker和ngixn网络状态之前添加:
netstat -tunlap | grep :11411
测试:
fdfs_upload_file /etc/fdfs/client.conf /source/db-6.2.23.tar.gz
group1/m00/00/00/wkhqa1yu2l6aptk-aqqolabfhaq.tar.gz
fdfs_upload_file /etc/fdfs/client.conf /source/db-6.2.23.tar.gz
group1/m00/00/00/wkhqa1yu2mkaomiiaqqolhuwxfw.tar.gz
ll /data/fdfs/storage/data/00/00/
total 45268
-rw-r--r-- 1 root root 44305964 apr 11 14:03 wkhqa1yu2l6am0aiaqqolkfbfuc.tar.gz
lrwxrwxrwx 1 root root 64 apr 11 14:03 wkhqa1yu2l6aptk-aqqolabfhaq.tar.gz -> /data/fdfs/storage/data/00/00/wkhqa1yu2l6am0aiaqqolkfbfuc.tar.gz
lrwxrwxrwx 1 root root 64 apr 11 14:03 wkhqa1yu2mkaomiiaqqolhuwxfw.tar.gz -> /data/fdfs/storage/data/00/00/wkhqa1yu2l6am0aiaqqolkfbfuc.tar.gz
自定义 fastdfs-spring-boot-starter
为了快速构建springboot项目,我们可以自定义一个场景启动器来解决。详细信息:https://github.com/bluemiaomiao/fastdfs-spring-boot-starter .
下面使用springboot构建一个示例项目:
添加依赖:
<dependency>
<groupid>com.bluemiaomiao</groupid>
<artifactid>fastdfs-spring-boot-starter</artifactid>
<version>1.0-snapshot</version>
</dependency>
在主配置类中添加注解:
@enablefastdfsclient
@springbootapplication
public class demoapplication {
@autowired
private fastdfsclientservice fastdfsclientservice;
public static void main(string[] args) {
springapplication.run(demoapplication.class, args);
}
}
此时将会自动初始化好全局客户端。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.51cto.com/xvjunjie/2377669
文档来源:服务器之家http://www.zzvips.com/article/180326.html
页:
[1]