好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java高级架构之FastDFS分布式文件集群详解

fastdfs简介

fastdfs是一款开源的轻量级 分布式 文件系统,使用c实现,支持linux、bsd等unix-like操作系统。值得注意的是,fastdfs并不是通用的文件系统,只能通过专用的api访问。

fastdfs为互联网应用量身定做,解决了大容量文件存储的问题,fastdfs追求高性能和高扩展性。fastdfs的主要概念:

tracker-server:跟踪服务器。用于跟踪文件,主要起调度作用。在内存中记录了所有存储组和存储服务器的状态信息,是客户端和数据存储的主要枢纽。相比gfs更为精简,因为不记录文件索引。

storage-server: 存储服务器。用于存储文件。直接使用操作系统的文件系统来管理和组织文件。

group: 组,卷。多个服务器存在一个组中,在一个组中的服务器存储的文件是完全相同的,并且同一个组的服务器地位是对等的。对于文件的操作可以在任意一个组中的服务器上进行。

metadata: 元数据。以键值对的方式存储,用于存储文件的相关信息。

各大存储系统的对比

话说没有对比就没有伤害,fastdfs也不是万能的,需要根据业务来选择适合的存储系统。

 

存储系统 适合存储的文件类型 文件分布情况 系统性能 复杂度 fuse(用户文件系统) posix() 备份机制 通讯协议接口 社区情况 实现语言
fastdfs 4kb至500mb 将小文件合并存储 很高 简单 不支持 不支持 组内冗余备份 http api 国内用户 c
tfs 所有文件 小文件合并以块组织分片 - 复杂 不支持 不支持 块存储多份,主辅灾备 http api c++
mfs 大于64k 分片存储 master节点占用内存较高 - 支持 支持 多点备份,动态冗余 使用fuse挂载 较多 perl
hdfs 大文件 大文件分片块存储 - 简单 支持 支持 多副本 原生api 较多 java
ceph 对象大文件 osd一主多从 - 复杂 支持 支持 多副本 原生api 较少 c++
mogilefs 海量小图片 - 复杂 支持 不支持 动态冗余 原生api 文档少 perl
clusterfs 大文件 - - 简单 支持 支持 - - c

 

github项目主页: https://github测试数据/happyfish100/fastdfs

fastdfs客户端与服务器端交互原理

fastdfs+nginx整合

架构图

安装fastdfs

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

mkdir /source

cd /source

yum install -y gcc gcc-c++ make cmake wget libevent

wget https: //github测试数据/happyfish100/libfastcommon/archive/v1.0.35.tar.gz

wget https: //github测试数据/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

修改配置文件

修改跟踪器配置文件:

?

1

base_path=/data/fdfs/tracker

修改存储器配置文件:

?

1

2

3

base_path=/data/fdfs/storage

store_path0=/data/fdfs/storage

tracker_server= 192.168 . 80.3 : 22122

修改客户端配置文件:

?

1

2

base_path=/data/fdfs/client

tracker_server= 192.168 . 80.3 : 22122

启动

?

1

2

/etc/init.d/fdfs_trackerd start

/etc/init.d/fdfs_storaged start

?

1

2

3

4

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) 字样可以尝试重启服务。

测试

?

1

2

/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /source/fastdfs_v5. 05 .tar.gz

group1/m00/ 00 / 00 /wkhqa1ysjsgapjxbaavfol7fju4.tar.gz

文件存储在:

?

1

ll /data/fdfs/storage/data/ 00 / 00 /wkhqa1ysjsgapjxbaavfol7fju4.tar.gz

安装nginx并配置模块

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

# 安装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 :

?

1

2

3

4

5

6

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

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区块添加:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

server {

     listen    8000 ;

     server_name media;

 

     location / {

       root  html;

       index index.html index.htm;

     }

 

     # 拦截文件请求,转发到下面的模块

     location ~/group[ 0 - 9 ] {

       ngx_fastdfs_module;

     }

 

     error_page  500 502 503 504 /50x.html;

     location = /50x.html {

       root  html;

     }

   }

测试配置文件正确性并启动:

?

1

2

/applications/nginx/sbin/nginx -t

/applications/nginx/sbin/nginx

删除临时文件:

?

1

2

3

4

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)进行路由。

简单的启动停止服务的脚本:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

# start-service

# usage: ./start-service

echo "============================================sync datetime==========================================="

ntpdate time7.aliyun测试数据

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

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

# 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 中修改:

?

1

2

3

4

5

6

7

8

# 开启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客户端验证:

将客户端安装到本地仓库:

?

1

2

3

git clone https: //github测试数据/happyfish100/fastdfs-client-java.git

cd fastdfs-client-java

mvn clean install

使用maven创建一个普通的项目,在pom文件中添加依赖:

?

1

2

3

4

5

6

7

<dependencies>

   <dependency>

     <groupid>org.csource</groupid>

     <artifactid>fastdfs-client-java</artifactid>

     <version> 1.27 -snapshot</version>

   </dependency>

</dependencies>

在resources目录下创建fastdfs配置文件 fastdfs-client.properties :

?

1

2

3

4

5

6

7

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 类文件:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

package com.bluemiaomiao;

 

import org.csource测试数据mon.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);

   }

}

如果访问时显示防盗链图片,可能是测试客户端与服务器之间的之间有一定差距,两个主机之间不能有分钟级别的差距,可以使用如下方法同步服务器:

?

1

2

3

4

# 安装同步时间服务器的客户端, windows系统也需要与该服务器同步

# 控制面板->时钟和区域->设置日期和时间->internet时间->更改设置

yum install ntpdate

ntpdate time7.aliyun测试数据

整合fastdht实现数据去重

fastdht是分布式哈希系统(dht),使用berkeleydb做数据存储,使用libevent做网络io处理。依赖于libfastcommon组件。

下载

去oracle官方网站下载 berkeley db 数据库,去fastdfs的github主页下载fastdht的源码包。由于之前已经安装过linevent和libfastcommon,因此只需要安装数据库和fastdht即可。

安装配置数据库与fastdht

?

1

2

3

4

5

6

7

8

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行代码:

?

1

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 : 指定数据库提供的库文件目录

?

1

2

3

4

./make.sh

./make.sh install

cd

rm -rf fastdht-master

配置

?

1

mkdir /data/fdht

修改 /etc/fdht/fdht_client.conf 内容:

?

1

2

base_path=/data/fdht

#include /etc/fdht/fdht_servers.conf

修改 /etc/fdht/fdht_servers.conf 内容:

?

1

group0 = 192.168 . 80.3 : 11411

修改 /etc/fdht/fdhtd.conf 内容:

?

1

2

base_path=/data/fdht

#include /etc/fdht/fdht_servers.conf

修改 /etc/fdfs/storage.conf 内容:

?

1

2

3

4

check_file_duplicate= 1

key_namespace=fastdfs

keep_alive= 1

#include /etc/fdht/fdht_servers.conf

主要需要包含服务器端配置文件。

?

1

2

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

启动并测试

?

1

fdhtd /etc/fdht/fdhtd.conf

重启使用:

?

1

fdhtd /etc/fdht/fdhtd.conf restart

查看结果:

?

1

2

netstat -tunlap | grep : 11411

tcp    0    0 0.0 . 0.0 : 11411       0.0 . 0.0 :*        listen   20605 /fdhtd

由于安装fastdht的时候关闭了fastdfs,因此需要启动fastdfs

?

1

./start-service

修改之前的 start-service 脚本, 在启动tracker和storage服务之前添加:

?

1

fdhtd /etc/fdht/fdhtd.conf

在查看tracker和ngixn网络状态之前添加:

?

1

netstat -tunlap | grep : 11411

测试:

?

1

2

3

4

5

6

7

8

9

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测试数据/bluemiaomiao/fastdfs-spring-boot-starter  .

下面使用springboot构建一个示例项目:

添加依赖:

?

1

2

3

4

5

<dependency>

   <groupid>com.bluemiaomiao</groupid>

   <artifactid>fastdfs-spring-boot-starter</artifactid>

   <version> 1.0 -snapshot</version>

</dependency>

在主配置类中添加注解:

?

1

2

3

4

5

6

7

8

9

10

11

@enablefastdfsclient

@springbootapplication

public class demoapplication {

 

@autowired

private fastdfsclientservice fastdfsclientservice;

 

public static void main(string[] args) {

   springapplication.run(demoapplication. class , args);

}

}

此时将会自动初始化好全局客户端。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.51cto测试数据/xvjunjie/2377669

查看更多关于Java高级架构之FastDFS分布式文件集群详解的详细内容...

  阅读:14次