搭建高可用分布式系统FastDFS

本文详细介绍了FastDFS的原理、架构及如何在Linux环境下搭建FastDFS集群,包括TrackerServer、StorageServer的安装配置,以及Nginx的集成,最后演示了Java客户端的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

FastDFS介绍

简介

FastDFS是一个开源的轻量级分布式文件系统。它解决了大数据量存储和负载均衡等问题。特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务,如相册网站、视频网站等等。在UC基于FastDFS开发向用户提供了:网盘,社区,广告和应用下载等业务的存储服务。

FastDFS是一款开源的轻量级分布式文件系统纯C实现,支持Linux、FreeBSD等UNIX系统类google FS,不是通用的文件系统,只能通过专有API访问,目前提供了C、Java和PHP API为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性FastDFS可以看做是基于文件的key value pair存储系统,称作分布式文件存储服务更为合适。FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

FastDFS架构

fastdfs archect

Tracker相当于FastDFS的大脑,不论是上传还是下载都是通过tracker来分配资源;客户端一般可以使用ngnix等静态服务器来调用或者做一部分的缓存;存储服务器内部分为卷(或者叫做组),卷于卷之间是平行的关系,可以根据资源的使用情况随时增加,卷内服务器文件相互同步备份,以达到容灾的目的。

FastDFS服务端有三个角色:跟踪服务器(tracker server)、存储服务器(storage server)和客户端(client)。

tracker server:跟踪服务器,主要做调度工作,起负载均衡的作用。在内存中记录集群中所有存储组和存储服务器的状态信息,是客户端和数据服务器交互的枢纽。相比GFS中的master更为精简,不记录文件索引信息,占用的内存量很少。

Tracker是FastDFS的协调者,负责管理所有的storage server和group,每个storage在启动后会连接Tracker,告知自己所属的group等信息,并保持周期性的心跳,tracker根据storage的心跳信息,建立group==>[storage server list]的映射表。

Tracker需要管理的元信息很少,会全部存储在内存中;另外tracker上的元信息都是由storage汇报的信息生成的,本身不需要持久化任何数据,这样使得tracker非常容易扩展,直接增加tracker机器即可扩展为tracker cluster来服务,cluster里每个tracker之间是完全对等的,所有的tracker都接受stroage的心跳信息,生成元数据信息来提供读写服务。

storage server:存储服务器(又称:存储节点或数据服务器),文件和文件属性(meta data)都保存到存储服务器上。Storage server直接利用OS的文件系统调用管理文件。

Storage server(后简称storage)以组(卷,group或volume)为单位组织,一个group内包含多台storage机器,数据互为备份,存储空间以group内容量最小的storage为准,所以建议group内的多个storage尽量配置相同,以免造成存储空间的浪费。

以group为单位组织存储能方便的进行应用隔离、负载均衡、副本数定制(group内storage server数量即为该group的副本数),比如将不同应用数据存到不同的group就能隔离应用数据,同时还可根据应用的访问特性来将应用分配到不同的group来做负载均衡;缺点是group的容量受单机存储容量的限制,同时当group内有机器坏掉时,数据恢复只能依赖group内地其他机器,使得恢复时间会很长。

group内每个storage的存储依赖于本地文件系统,storage可配置多个数据存储目录,比如有10块磁盘,分别挂载在 /data/disk1-/data/disk10,则可将这10个目录都配置为storage的数据存储目录。

storage接受到写文件请求时,会根据配置好的规则(后面会介绍),选择其中一个存储目录来存储文件。为了避免单个目录下的文件数太多,在storage第一次启动时,会在每个数据存储目录里创建2级子目录,每级256个,总共65536个文件,新写的文件会以hash的方式被路由到其中某个子目录下,然后将文件数据直接作为一个本地文件存储到该目录中。

client:客户端,作为业务请求的发起方,通过专有接口,使用TCP/IP协议与跟踪器服务器或存储节点进行数据交互。FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。

另外两个概念:

group :组, 也可称为卷。 同组内服务器上的文件是完全相同的 ,同一组内的storage server之间是对等的, 文件上传、 删除等操作可以在任意一台storage server上进行 。

meta data :文件相关属性,键值对( Key Value Pair) 方式,如:width=1024,heigth=768 。

FastDFS存储策略

为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。

在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。

tracker server会在内存中保存storage分组及各个组下的storage server,并将连接过自己的storage server及其分组保存到文件中,以便下次重启服务时能直接从本地磁盘中获得storage相关信息。storage server会在内存中记录本组的所有服务器,并将服务器信息记录到文件中。tracker server和storage server之间相互同步storage server列表:

  • 如果一个组内增加了新的storage server或者storage server的状态发生了改变,tracker server都会将storage server列表同步给该组内的所有storage server。以新增storage server为例,因为新加入的storage server主动连接tracker server,tracker server发现有新的storage server加入,就会将该组内所有的storage server返回给新加入的storage server,并重新将该组的storage server列表返回给该组内的其他storage server;
  • 如果新增加一台tracker server,storage server连接该tracker server,发现该tracker server返回的本组storage server列表比本机记录的要少,就会将该tracker server上没有的storage server同步给该tracker server。

FastDFS工作流程

上传机制

fastdfs upload

从中可以看到,Client想上传图片,它先向Tracker进行询问,Tracker查看一下登记信息之后,告诉Client哪个storage当前空闲,Tracker会把IP和端口号都返回给Client,Client在拿到IP和端口号之后,便不再需要通过Tracker,直接便向Storage进行上传图片,Storage在保存图片的同时,会向Tracker进行汇报,告诉Tracker它当前是否还留有剩余空间,以及剩余空间大小。汇报完之后,Storage将服务器上存储图片的地址返回给Client,Client可以拿着这个地址进行访问图片。说得更加细致一点,客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名,如下所示:

组名:文件上传后所在的storage组名称,在文件上传成功后由storage服务器返回,需要客户端自行保存。
虚拟磁盘路径:storage配置的虚拟路径,与磁盘选项store_path*对应。如果配置了store_path0则是M00,如果配置了store_path1则是M01,以此类推。
数据两级目录:storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。

内部流程如下:

1、选择tracker server

当集群中不止一个tracker server时,由于tracker之间是完全对等的关系,客户端在upload文件时可以任意选择一个trakcer。 选择存储的group 当tracker接收到upload file的请求时,会为该文件分配一个可以存储该文件的group,支持如下选择group的规则:

  • Round robin,所有的group间轮询
  • Specified group,指定某一个确定的group
  • Load balance,剩余存储空间多多group优先

2、选择storage server

当选定group后,tracker会在group内选择一个storage server给客户端,支持如下选择storage的规则:

  • Round robin,在group内的所有storage间轮询
  • First server ordered by ip,按ip排序
  • First server ordered by priority,按优先级排序(优先级在storage上配置)

3、选择storage path

当分配好storage server后,客户端将向storage发送写文件请求,storage将会为文件分配一个数据存储目录,支持如下规则:

  • Round robin,多个存储目录间轮询
  • 剩余存储空间最多的优先

4、生成Fileid

选定存储目录之后,storage会为文件生一个Fileid,由storage server ip、文件创建时间、文件大小、文件crc32和一个随机数拼接而成,然后将这个二进制串进行base64编码,转换为可打印的字符串。 选择两级目录 当选定存储目录之后,storage会为文件分配一个fileid,每个存储目录下有两级256*256的子目录,storage会按文件fileid进行两次hash(猜测),路由到其中一个子目录,然后将文件以fileid为文件名存储到该子目录下。

5、生成文件名

当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名,文件名由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。

文件同步机制

客户端将一个文件上传到一台Storage server后,文件上传工作就结束了。由该Storage server根据binlog中的上传记录将这个文件同步到同组的其他Storage server。这样的文件同步方式是异步方式,异步方式带来了文件同步延迟的问题。新上传文件后,在尚未被同步过去的Storage server上访问该文件,会出现找不到文件的现象。FastDFS是如何解决文件同步延迟这个问题的呢? 文件的访问分为两种情况:文件更新和文件下载。文件更新包括设置文件附加属性和删除文件。文件的附加属性包括文件大小、图片宽度、图片高度等。FastDFS中,文件更新操作都会优先选择源Storage server,也就是该文件被上传到的那台Storage server。这样的做法不仅避免了文件同步延迟的问题,而且有效地避免了在多台Storage server上更新同一文件可能引起的时序错乱的问题。 那么文件下载是如何解决文件同步延迟这个问题的呢? 要回答这个问题,需要先了解文件名中包含了什么样的信息。Storage server生成的文件名中,包含了源Storage server的IP地址和文件创建时间等字段。文件创建时间为UNIX时间戳,后面称为文件时间戳。从文件名或文件ID中,可以反解出这两个字段。 然后我们再来看一下,Tracker server是如何准确地知道一个文件已被同步到一台Storage server上的。前面已经讲过,文件同步采用主动推送的方式。另外,每台storage server都会定时向tracker server报告它向同组的其他storage server同步到的文件时间戳。当tracker server收到一台storage server的文件同步报告后,它会依次找出该组内各个storage server(后称作为S)被同步到的文件时间戳最小值,作为S的一个属性记录到内存中。

FastDFS对文件同步延迟问题的解决方案 下面我们来看一下FastDFS采取的解决方法。 一个最简单的解决办法,和文件更新一样,优先选择源Storage server下载文件即可。这可以在Tracker server的配置文件中设置,对应的参数名为download_server。 另外一种选择Storage server的方法是轮流选择(round-robin)。当Client询问Tracker server有哪些Storage server可以下载指定文件时,Tracker server返回满足如下四个条件之一的Storage server: 1、该文件上传到的源Storage server,文件直接上传到该服务器上的; 2、文件创建时间戳 < Storage server被同步到的文件时间戳,这意味着当前文件已经被同步过来了; 3、文件创建时间戳=Storage server被同步到的文件时间戳,且(当前时间—文件创建时间戳) > 一个文件同步完成需要的最大时间(如5分钟); 4、(当前时间—文件创建时间戳) > 文件同步延迟阈值,比如我们把阈值设置为1天,表示文件同步在一天内肯定可以完成。

storage server有7个状态,如下: FDFS_STORAGE_STATUS_INIT :初始化,尚未得到同步已有数据的源服务器 FDFS_STORAGE_STATUS_WAIT_SYNC :等待同步,已得到同步已有数据的源服务器 FDFS_STORAGE_STATUS_SYNCING :同步中 FDFS_STORAGE_STATUS_DELETED :已删除,该服务器从本组中摘除(注:本状态的功能尚未实现) FDFS_STORAGE_STATUS_OFFLINE :离线 FDFS_STORAGE_STATUS_ONLINE :在线,尚不能提供服务 FDFS_STORAGE_STATUS_ACTIVE :在线,可以提供服务 当storage server的状态为FDFS_STORAGE_STATUS_ONLINE时,当该storage server向tracker server发起一次heart beat时,tracker server将其状态更改为FDFS_STORAGE_STATUS_ACTIVE。

组内新增加一台storage server A时,由系统自动完成已有数据同步,处理逻辑如下: storage server A连接tracker server,tracker server将storage server A的状态设置为FDFS_STORAGE_STATUS_INIT。storage server A询问追加同步的源服务器和追加同步截至时间点,如果该组内只有storage server A或该组内已成功上传的文件数为0,则没有数据需要同步,storage server A就可以提供在线服务,此时tracker将其状态设置为FDFS_STORAGE_STATUS_ONLINE,否则tracker server将其状态设置为FDFS_STORAGE_STATUS_WAIT_SYNC,进入第二步的处理;

  • 假设tracker server分配向storage server A同步已有数据的源storage server为B。同组的storage server和tracker server通讯得知新增了storage server A,将启动同步线程,并向tracker server询问向storage server A追加同步的源服务器和截至时间点。storage server B将把截至时间点之前的所有数据同步给storage server A;而其余的storage server从截至时间点之后进行正常同步,只把源头数据同步给storage server A。到了截至时间点之后,storage server B对storage server A的同步将由追加同步切换为正常同步,只同步源头数据;
  • storage server B向storage server A同步完所有数据,暂时没有数据要同步时,storage server B请求tracker server将storage server A的状态设置为FDFS_STORAGE_STATUS_ONLINE;
  • 当storage server A向tracker server发起heart beat时,tracker server将其状态更改为FDFS_STORAGE_STATUS_ACTIVE。

下载机制

客户端带上文件名信息请求Tracker服务获取到存储服务器的ip地址和端口,然后客户端根据返回的IP地址和端口号请求下载文件,存储服务器接收到请求后返回文件给客户端。 fastdfs download

跟upload file一样,在download file时客户端可以选择任意tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。由于group内的文件同步时在后台异步进行的,所以有可能出现在读到时候,文件还没有同步到某些storage server上,为了尽量避免访问到这样的storage,tracker按照如下规则选择group内可读的storage。

  • 该文件上传到的源头storage - 源头storage只要存活着,肯定包含这个文件,源头的地址被编码在文件名中。
  • 文件创建时间戳==storage被同步到的时间戳 且(当前时间-文件创建时间戳) > 文件同步最大时间(如5分钟) - 文件创建后,认为经过最大同步时间后,肯定已经同步到其他storage了。
  • 文件创建时间戳 < storage被同步到的时间戳。 - 同步时间戳之前的文件确定已经同步了
  • (当前时间-文件创建时间戳) > 同步延迟阀值(如一天)。 - 经过同步延迟阈值时间,认为文件肯定已经同步了。

搭建高可用FastDFS环境

一、安装FastDFS

0、服务器规划

跟踪服务器(Tracker Server):172.16.16.193

存储服务器(Storage Server):172.16.16.216 ,172.16.16.212

nginx:172.16.16.212,172.16.16.216

操作系统:CentOS6.5

用户:root

数据存储目录:/home/fastdfs

1、安装所需的依赖包

# yum install make cmake gcc gcc-c++

2、下载安装 libfastcommon

libfastcommon是从 FastDFS 和 FastDHT 中提取出来的公共 C 函数库,基础环境,安装即可 。 ①下载libfastcommon

# wget https://github.com/happyfish100/libfastcommon/archive/V1.0.7.tar.gz

② 解压

# tar -zxvf V1.0.7
# cd libfastcommon-1.0.7

③ 编译、安装

# ./make.sh
# ./make.sh install

④ libfastcommon.so 安装到了/usr/lib64/libfastcommon.so,但是FastDFS主程序设置的lib目录是/usr/local/lib,所以需要创建软链接。

# ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
# ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
# ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
# ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so 

3、下载安装FastDFS

① 下载FastDFS

# wget https://github.com/happyfish100/fastdfs/archive/V5.05.tar.gz

② 解压

# cd ~
# tar -zxvf V5.05
# cd fastdfs-5.05

③ 编译、安装

# ./make.sh
# ./make.sh install

④ 默认安装方式安装后的相应文件与目录

A、服务脚本:
/etc/init.d/fdfs_storaged
/etc/init.d/fdfs_tracker
B、配置文件:
/etc/fdfs/client.conf.sample 改名成 client.conf
/etc/fdfs/storage.conf.sample 改名成 storage.conf
/etc/fdfs/tracker.conf.sample 改名成 tracker.conf
C、命令工具在 /usr/bin/ 目录下:
fdfs_appender_test
fdfs_appender_test1
fdfs_append_file
fdfs_crc32
fdfs_delete_file
fdfs_download_file
fdfs_file_info
fdfs_monitor
fdfs_storaged
fdfs_test
fdfs_test1
fdfs_trackerd
fdfs_upload_appender
fdfs_upload_file
stop.sh
restart.sh

⑤ FastDFS 服务脚本设置的 bin 目录是 /usr/local/bin, 但实际命令安装在 /usr/bin/ 下。

两种方式: 1)修改FastDFS 服务脚本中相应的命令路径,也就是把 /etc/init.d/fdfs_storaged 和 /etc/init.d/fdfs_trackerd 两个脚本中的 /usr/local/bin 修改成 /usr/bin。(本人采用的这种方式)

2)建立/usr/bin 到 /usr/local/bin 的软链接

4、配置FastDFS跟踪器(Tracker)

① 进入 /etc/fdfs,复制 FastDFS 跟踪器样例配置文件 tracker.conf.sample,并重命名为 tracker.conf。

# cd /etc/fdfs
# cp tracker.conf.sample tracker.conf
# vi tracker.conf

② 编辑tracker.conf ,其它的默认即可。

# 配置文件是否不生效,false 为生效
disabled=false

# 提供服务的端口
port=22122

# Tracker 数据和日志目录地址(根目录必须存在,子目录会自动创建)
base_path=/home/fastdfs/tracker

# HTTP 服务端口
http.server_port=80

这个http.server_port=80 指的是在tracker服务器上启动http服务进程,如:apache或者nginx 启动时所监听的端口,如果没有启动可以不用管。

③ 创建tracker基础数据目录,即base_path对应的目录

# mkdir -p /home/fastdfs/tracker

④ 防火墙中打开跟踪端口(默认的22122)

# vi /etc/sysconfig/iptables
添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22122 -j ACCEPT
重启防火墙:
# service iptables restart

⑤ 启动Tracker 初次成功启动,会在 /home/fdfsdfs/tracker/ (配置的base_path)下创建 data、logs 两个目录。

可以用这种方式启动
# /etc/init.d/fdfs_trackerd start

也可以用这种方式启动,前提是上面创建了软链接,后面都用这种方式
# service fdfs_trackerd start

查看 FastDFS Tracker 是否已成功启动 ,22122端口正在被监听,则算是Tracker服务安装成功。

# netstat -unltp|grep fdfs

关闭Tracker命令:

# service fdfs_trackerd stop

⑥ 设置Tracker开机启动

# chkconfig fdfs_trackerd on

或者:
# vi /etc/rc.d/rc.local
加入配置:
/etc/init.d/fdfs_trackerd start 

⑦ tracker server 目录及文件结构 Tracker服务启动成功后,会在base_path下创建data、logs两个目录。目录结构如下:

${base_path}
  |__data
  |   |__storage_groups.dat:存储分组信息
  |   |__storage_servers.dat:存储服务器列表
  |__logs
  |   |__trackerd.log: tracker server 日志文件 

5、配置 FastDFS 存储 (Storage)

① 进入 /etc/fdfs 目录,复制 FastDFS 存储器样例配置文件 storage.conf.sample,并重命名为 storage.conf

# cd /etc/fdfs
# cp storage.conf.sample storage.conf
# vi storage.con

② 编辑storage.conf 标记的需要修改,其它的默认即可。

# 配置文件是否不生效,false 为生效
disabled=false 

# 指定此 storage server 所在 组(卷)
group_name=group1

# storage server 服务端口
port=23000

# 心跳间隔时间,单位为秒 (这里是指主动向 tracker server 发送心跳)
heart_beat_interval=30 

# Storage 数据和日志目录地址(根目录必须存在,子目录会自动生成)
base_path=/home/fastdfs/storage  --需要修改,默认也可--

# 存放文件时 storage server 支持多个路径。这里配置存放文件的基路径数目,通常只配一个目录。
store_path_count=1


# 逐一配置 store_path_count 个路径,索引号基于 0。
# 如果不配置 store_path0,那它就和 base_path 对应的路径一样。
store_path0=/home/fastdfs/file  --需要修改,默认也可--

# FastDFS 存储文件时,采用了两级目录。这里配置存放文件的目录个数。 
# 如果本参数只为 N(如: 256),那么 storage server 在初次运行时,会在 store_path 下自动创建 N * N 个存放文件的子目录。
subdir_count_per_path=256

# tracker_server 的列表 ,会主动连接 tracker_server
# 有多个 tracker server 时,每个 tracker server 写一行
tracker_server=172.16.16.193:22122  --需要修改--

# 允许系统同步的时间段 (默认是全天) 。一般用于避免高峰同步产生一些问题而设定。
sync_start_time=00:00
sync_end_time=23:59
# 访问端口
http.server_port=80  --需要修改,对应tracker配置的http端口--

③ 创建Storage基础数据目录,对应上述配置文件所配置的目录

# 这是配置的base_path路径
# mkdir -p /home/fastdfs/storage

# 这是配置的store_path0路径
# mkdir -p /home/fastdfs/file

④ 防火墙中打开存储器端口(默认的 23000)

# vi /etc/sysconfig/iptables

添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 23000 -j ACCEPT

重启防火墙:
# service iptables restart

⑤ 启动 Storage 启动Storage前确保Tracker是启动的。初次启动成功,会在 /home/fastdfs/storage 目录下创建 data、 logs 两个目录。

可以用这种方式启动
# /etc/init.d/fdfs_storaged start

也可以用这种方式,后面都用这种
# service fdfs_storaged start

查看 Storage 是否成功启动,23000 端口正在被监听,就算 Storage 启动成功。

# netstat -unltp|grep fdfs

关闭Storage命令:

# service fdfs_storaged stop

查看Storage和Tracker是否在通信:

/usr/bin/fdfs_monitor /etc/fdfs/storage.conf

⑥ 设置 Storage 开机启动

# chkconfig fdfs_storaged on

或者:
# vi /etc/rc.d/rc.local
加入配置:
/etc/init.d/fdfs_storaged start

⑦ Storage 目录 Tracker,Storage 启动成功后,在base_path 下创建了data、logs目录,记录着 Storage Server 的信息。 在 store_path0 目录下,创建了N*N个子目录:

6、文件上传测试

① 修改 Tracker 服务器中的客户端配置文件

# cd /etc/fdfs
# cp client.conf.sample client.conf
# vi client.conf

修改如下配置即可,其它默认。

# Client 的数据和日志目录
base_path=/home/fastdfs/client

# Tracker端口
tracker_server=172.16.16.193:22122

创建配置的目录

# mkdir -p /home/fastdfs/client

② 上传测试 准备一张图片test.jpg,在linux内部执行如下命令上传 test.jpg 图片

# /usr/bin/fdfs_upload_file /etc/fdfs/client.conf hz-map.jpg

上传成功后返回文件ID号:group1/M00/00/00/rBAQ2FzGjjCAVxnnAAH2JBb_rb4948.jpg

返回的文件ID由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。

查看目录下文件

7、查看FastDFS的Stroage节点情况

查看FastDFS Tracker及Storage节点

fdfs_monitor /etc/fdfs/client.conf | grep ACTIVE
        ip_addr = 10.1.8.45  ACTIVE
        ip_addr = 10.1.8.46  ACTIVE
        ip_addr = 10.1.8.54  ACTIVE
        ip_addr = 10.1.8.55  ACTIVE

删除Storage节点

删除Storage节点及删除后重新加入(通过fdfs_monitor删除)

# 停止某个storage节点
/etc/init.d/fdfs_storage stop
 
fdfs_monitor /etc/fdfs/client.conf delete group1 10.1.8.x
 
# 查看集群情况 fdfs_monitor /etc/fdfs/client.conf 可以到对应的storage节点状态为DELETED
fdfs_monitor /etc/fdfs/client.conf

二、安装Nginx

上面将文件上传成功了,但我们无法下载。因此安装Nginx作为服务器以支持Http方式访问文件。同时,后面安装FastDFS的Nginx模块也需要Nginx环境。

Nginx只需要安装到StorageServer所在的服务器即可,用于访问文件。我这里由于是单机,TrackerServer和StorageServer在一台服务器上。

1、安装nginx所需环境

① gcc 安装 前面已安装 ② PCRE pcre-devel 安装

# yum install -y pcre pcre-devel

③ zlib 安装

# yum install -y zlib zlib-devel

④ OpenSSL 安装

# yum install -y openssl openssl-devel

2、安装Nginx

① 下载nginx

# wget -c https://nginx.org/download/nginx-1.9.9.tar.gz

② 解压

# tar -zxvf nginx-1.9.9.tar.gz
# cd nginx-1.9.9

③ 使用默认配置

# ./configure

④ 编译、安装

# make
# make install

⑤ 启动nginx

# /usr/local/nginx/sbin/nginx

其它命令

# /usr/local/nginx/sbin/nginx -s stop
# /usr/local/nginx/sbin/nginx -s quit
# /usr/local/nginx/sbin/nginx -s reload

⑥ 设置开机启动

# vi /etc/rc.local
添加一行:
/usr/local/nginx/sbin/nginx

⑦ 查看nginx的版本及模块

/usr/local/nginx/sbin/nginx -V

⑧ 防火墙中打开Nginx端口(默认的 80)

# vi /etc/sysconfig/iptables
添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT
重启防火墙:
# service iptables restart

3、访问文件

① 修改nginx.conf

# vi /usr/local/nginx/conf/nginx.conf

添加如下行,将 /group1/M00 映射到 /home/fastdfs/file/data
location /group1/M00 {
    alias /home/fastdfs/file/data;
}

# 重启nginx
# /usr/local/nginx/sbin/nginx -s reload

② 在浏览器访问之前上传的图片、成功。

http://172.16.16.212:80/group1/M00/00/00/rBAQ2FzGjjCAVxnnAAH2JBb_rb4948.jpg

如果端口冲突需要修改端口,如81

三、FastDFS 配置 Nginx 模块

1、fastdfs-nginx-module模块原理

在大多数业务场景中,往往需要为FastDFS存储的文件提供http下载服务,而尽管FastDFS在其storage及tracker都内置了http服务, 但性能表现却不尽如人意; 因此可以引入基于当前主流web服务器的扩展模块(包括nginx/apache),其用意在于利用web服务器直接对本机storage数据文件提供http服务,以提高文件下载的性能。

说明: 在每一台storage服务器主机上部署Nginx及FastDFS扩展模块,由Nginx模块对storage存储的文件提供http下载服务, 仅当当前storage节点找不到文件时会向源storage主机发起redirect或proxy动作。 注:图中的tracker可能为多个tracker组成的集群;且当前FastDFS的Nginx扩展模块支持单机多个group的情况

说明: 在每一台storage服务器主机上部署Nginx及FastDFS扩展模块,由Nginx模块对storage存储的文件提供http下载服务, 仅当当前storage节点找不到文件时会向源storage主机发起redirect或proxy动作。 注:图中的tracker可能为多个tracker组成的集群;且当前FastDFS的Nginx扩展模块支持单机多个group的情况

几个概念

storage_id:指storage server的id,从FastDFS4.x版本开始,tracker可以对storage定义一组ip到id的映射,以id的形式对storage进行管理。而文件名写入的不再是storage的ip而是id,这样的方式对于数据迁移十分有利。 storage_sync_file_max_delay:指storage节点同步一个文件最大的时间延迟,是一个阈值;如果当前时间与文件创建时间的差距超过该值则认为同步已经完成。 anti_steal_token:指文件ID防盗链的方式,FastDFS采用token认证的方式进行文件防盗链检查。

fastdfs-nginx-module配置文件

目标文件:/etc/fdfs/mod_fastdfs.conf

一些重要参数:

group_count           //group个数
url_have_group_name   //url中是否包含group
group.store_path      //group对应的存储路径
connect_timeout       //连接超时
network_timeout       //接收或发送超时
response_mode         //响应模式,proxy或redirect
load_fdfs_parameters_from_tracker //是否从tracker下载服务端配置

根据load_fdfs_parameters_from_tracker参数确定是否从tracker获取server端的配置信息

  • load_fdfs_parameters_from_tracker=true:
  1. 调用fdfs_load_tracker_group_ex解析tracker连接配置 ;
  2. 调用fdfs_get_ini_context_from_tracker连接tracker获取配置信息;
  3. 获取storage_sync_file_max_delay阈值
  4. 获取use_storage_id
  5. 如果use_storage_id为true,则连接tracker获取storage_ids映射表(调用方法:fdfs_get_storage_ids_from_tracker_group)
  • load_fdfs_parameters_from_tracker=false:
  1. 从mod_fastdfs.conf加载所需配置:storage_sync_file_max_delay、use_storage_id;
  2. 如果use_storage_id为true,则根据storage_ids_filename获取storage_ids映射表(调用方法:fdfs_load_storage_ids_from_file)

2、安装配置Nginx模块

① fastdfs-nginx-module 模块说明 FastDFS 通过 Tracker 服务器,将文件放在 Storage 服务器存储, 但是同组存储服务器之间需要进行文件复制, 有同步延迟的问题。 假设 Tracker 服务器将文件上传到了 172.16.16.193,上传成功后文件 ID已经返回给客户端。 此时 FastDFS 存储集群机制会将这个文件同步到同组存储 172.16.16.212,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 172.16.16.212 上取文件,就会出现文件无法访问的错误。 而 fastdfs-nginx-module 可以重定向文件链接到源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。

② 下载 fastdfs-nginx-module、解压

# 这里为啥这么长一串呢,因为最新版的master与当前nginx有些版本问题。
# wget https://github.com/happyfish100/fastdfs-nginx-module/archive/5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip

# 解压
# unzip 5e5f3566bbfa57418b5506aaefbe107a42c9fcb1.zip

# 重命名
# mv fastdfs-nginx-module-5e5f3566bbfa57418b5506aaefbe107a42c9fcb1  fastdfs-nginx-module-master

③ 配置Nginx 在nginx中添加模块

# 先停掉nginx服务
# /usr/local/nginx/sbin/nginx -s stop

进入解压包目录
# cd ~/nginx-1.9.9/

# 添加模块
# ./configure --add-module=../fastdfs-nginx-module-master/src

重新编译、安装
# make && make install

④ 查看Nginx的模块

# /usr/local/nginx/sbin/nginx -V

有下面这个就说明添加模块成功

添加模块

⑤ 复制 fastdfs-nginx-module 源码中的配置文件到/etc/fdfs 目录, 并修改

# cd ~/fastdfs-nginx-module-master/src
# cp mod_fastdfs.conf /etc/fdfs/
# vi /etc/fdfs/mod_fastdfs.conf 

修改如下配置,其它默认

# 连接超时时间
connect_timeout=10  --根据需要修改--

# Tracker Server
tracker_server=172.16.16.193:22122  --修改为自己的ip--

# StorageServer 默认端口
storage_server_port=23000

# 如果文件ID的uri中包含/group**,则要设置为true
url_have_group_name = true   --需要修改--

# Storage 配置的store_path0路径,必须和storage.conf中的一致
store_path0=/home/fastdfs/file  --需要修改--

⑥ 复制 FastDFS 的部分配置文件到/etc/fdfs 目录

# cd ~/fastdfs-5.05/conf/

# cp anti-steal.jpg http.conf mime.types /etc/fdfs/

⑦ 配置nginx,修改nginx.conf

# vi /usr/local/nginx/conf/nginx.conf

在80端口下添加fastdfs-nginx模块

location ~/group([0-9])/M00 {
    ngx_fastdfs_module;
}

注意: listen 80 端口值是要与 /etc/fdfs/storage.conf 中的 http.server_port=80 (前面改成80了)相对应。如果改成其它端口,则需要统一,同时在防火墙中打开该端口。 location 的配置,如果有多个group则配置location ~/group([0-9])/M00 ,没有则不用配group。

⑧ 在/home/fastdfs/file 文件存储目录下创建软连接,将其链接到实际存放数据的目录,这一步可以省略。

# ln -s /home/fastdfs/file/data/ /home/fastdfs/file/data/M00/ 

⑩ 在地址栏访问。 能下载文件就算安装成功。注意和第三点中直接使用nginx路由访问不同的是,这里配置 fastdfs-nginx-module 模块,可以重定向文件链接到源服务器取文件。

http://172.16.16.212/group1/M00/00/00/wKgCfVseZceAd9P1AAO9QRktgHc307.jpg

最终部署结构图:可以按照下面的结构搭建环境。

部署结构

3、处理流程

初始化流程

流程1

流程说明:

  • 从配置文件mod_fastdfs.conf读取配置
  • 配置项load_fdfs_parameters_from_tracker,确定是否从tracker中读取配置
  • 完成初始化

下载流程

下载流程

流程说明:

  • 从trackr读取元数据
  • 判断是否是本地storage server,如果是则读取返回。否则根据处理模式是重定向或者代理模式进行不同的处理
  • 重定向,则从源storage下载图片返回给客户单;代理模式则进行跳转。

处理模式(response_mode)

  • 代理模式(proxy)

  • 重定向模式(redirect)

    如果配置为redirect模式,直接重定向到源storage server IP对应的URL;否则为proxy模式,调用FastDFS client API从源storage server IP获取该文件并返回给客户端

四、Java客户端

前面文件系统平台搭建好了,现在就要写客户端代码在系统中实现上传下载。

1、首先需要搭建 FastDFS 客户端Java开发环境

① 项目中使用maven进行依赖管理,可以在pom.xml中引入如下依赖即可:

<dependency>
   <groupId>net.oschina.zcx7878</groupId>
   <artifactId>fastdfs-client-java</artifactId>
   <version>1.27.0.0</version>
</dependency>

② 引入配置文件

#################### FastDFS-Client Start ####################

# 文件服务器地址
file_server_addr=172.16.16.212:81
# 最大连接数 并发量较大的话可加大该连接数
max_storage_connection=8

## fastdfs为前缀的是FastDFS的配置
fastdfs.connect_timeout_in_seconds=10
fastdfs.network_timeout_in_seconds=30

fastdfs.charset=UTF-8

# token 防盗链功能
fastdfs.http_anti_steal_token=fasle
# 密钥
fastdfs.http_secret_key=HandFastDFSToken

# TrackerServer port
fastdfs.http_tracker_http_port=80

## Tracker Server, if more than one, separate with ","
# fastdfs.tracker_servers=10.0.11.201:22122,10.0.11.202:22122,10.0.11.203:22122
#fastdfs.tracker_servers=${tracker_server_addr}:22122
fastdfs.tracker_servers=172.16.16.193:22122

#################### FastDFS-Client End ####################

2、FastDFS整合SpringMVC+layui Demo

整合的Demo已同步到githup:https://github.com/yinZh0522/fastdfs-upload 修改conf.properties下的内容即可。

附录

redhat6.5 配置使用centos的yum源

新安装了redhat6.5安装后,登录系统,使用yum update 更新系统。提示:

This system is not registered to Red Hat Subscription Management. You can use subscription-manager to register.

无法更新。

redhat 默认自带的 yum 源需要注册,才能更新。我们想不花钱也可以更新,需要替换掉redhat的yum源。

1.检查是否安装yum包

查看RHEL是否安装了yum,若是安装了,那么又有哪些yum包:

`[root@localhost ~]# rpm -qa |grep yum``yum-metadata-parser-1.0-8.fc6``yum-3.0.1-5.el5``yum-rhn-plugin-0.4.3-1.el5``yum-updatesd-3.0.1-5.el`

2 删除redhat自带的yum包

卸载上面显示的所有yum包:

[root@localhost ~]# rpm -qa|grep yum|xargs rpm -e --nodeps(不检查依赖,直接删除rpm包)

再用

[root@localhost ~]# rpm -qa |grep yum

[root@localhost ~]#

查看,无信息显示表示已经卸载完成。

3.下载新的yum包。使用Centos6.5的yum包

# wget http://mirrors.163.com/centos/6/os/x86_64/Packages/yum-metadata-parser-1.1.2-16.el6.x86_64.rpm
# wget http://mirrors.163.com/centos/6/os/x86_64/Packages/yum-3.2.29-81.el6.centos.noarch.rpm
# wget http://mirrors.163.com/centos/6/os/x86_64/Packages/yum-plugin-fastestmirror-1.1.30-41.el6.noarch.rpm
# wget http://mirrors.163.com/centos/6/os/x86_64/Packages/python-urlgrabber-3.9.1-11.el6.noarch.rpm
# wget http://mirrors.163.com/centos/6/os/x86_64/Packages/python-iniparse-0.3.1-2.1.el6.noarch.rpm

安装yum软件包

注意:单个的安装包可能会依赖其它包(例如yum和yum-fastestmirror会相互依赖),所以我们可以把所有这些包放在一起,用一行命令将它们同时安装即可:

`rpm -ivh yum-metadata-parser-1.1.2-16.el6.i686.rpm yum-3.2.29-40.el6.centos.noarch.rpm yum-plugin-fastestmirror-1.1.30-14.el6.noarch.rpm`

yum-plugin-fastestmirror-1.1.30-41.el6.noarch.rpm yum-3.2.29-81.el6.centos.noarch.rpm 这两个要一起装

最后一步出现错误

error: Failed dependencies:
python-urlgrabber >= 3.9.1-10 is needed by yum-3.2.29-81.el6.centos.noarch
缺少python-urlgrabber包
#wget http://mirrors.163.com/centos/6/os/x86_64/Packages/python-urlgrabber-3.9.1-11.el6.noarch.rpm

#rpm -ivh --force python-urlgrabber-3.9.1-11.el6.noarch.rpm

重新安装yum

rpm -ivh yum-3.2.29-81.el6.centos.noarch.rpm yum-plugin-fastestmirror-1.1.30-41.el6.noarch.rpm 

4.更换yum源。使用163的源

# cd /etc/yum.repos.d/
# wget  http://mirrors.163.com/.help/CentOS6-Base-163.repo
# vi CentOS6-Base-163.repo

编辑文件,把文件里面的$全部替换为版本号,即(releasever全部替换为版本号,即6.5(:1,$s/$releasever/6.5然后按enter建) 最后保存!或者直接把下面的内存拷贝到CentOS6-Base-163.repo文件中即可(已经修改好)

5.清除原有缓存

yum clean all

重建缓存,以提高搜索安装软件的速度

yum makecache

6.更新系统

# yum update

转载于:https://my.oschina.net/socoolfj/blog/3045130

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值