FastDFS分布式存储

什么是FastDFS

FastDFS是一个开源的轻量级分布式文件系统。它解决了大量数据存储和负载均衡等问题。适合存储一些视频、音频、图片、文档,允许单个文件的大小为4kb~500MB,在UC基于FastDFS开发向用户提供了:网盘、社区、广告和应用下载等业务的存储服务。

支持Linux和FreeBSD等UNIX系统类google FS,不是通用的文件系统,只能通过专有API访问,目前提供了C、Java和PHP API互为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性,FastDFS可以看做是基于文件的key value pair存储系统,称作分布式文件存储服务更为合适。

FastDFS相关概念

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

1、client:客服端,负责进行文件存储和上传等操作

2、tracker server:跟踪服务器,管理后端存储节点,对来自客户端的请求进行识别并制定对应的后端节点给予响应。起负载均衡的作用。在内存中记录集群中所有存储组和存储服务器的状态信息,是客户端和数据服务器交互的枢纽。占用内存量很少。

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

3、storage server:存储节点,负责响应文件存储、下载、查看,以组或者卷为单位,一个group包含多台storage机器,数据互为备份,相同组的storage数据是完全相同的,所以相同组之间的storage配置尽量相同,以免造成存储空间的浪费

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

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

文件上传流程

fastdfs_upload

当客户端发出上传数据的请求时,tracker会返回storage服务器的ip和端口,客户端根据返回的ip和端口请求对应的storage上传文件,storage接收到请求后,将文件写入磁盘,并生成file_id,返回给客户端,客户端保存相关信息(file_id包括上传文件在storage所在的路径以及文件名)

FastDFS选择机制

1、选择tracker server

当集群中不止一个tracker server时,由于tracker之间是完全对等的关系,客户端在upload文件时可以任意选择一个tracker。 选择存储的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、生成file_id

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

5、生成文件名

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

文件下载流程

fastdfs_down

客户端下载是必须使用上传是返回的file_id来进行指定文件的下载,发出请求后,tracker会查询对应group的storage的ip以及端口返回给客户端,然后客户端使用file_id与storage直接请求,然后由storage返回文件给客户端。

由于group内的文件同步时在后台异步进行的,所以有可能出现在读到时候,文件还没有同步到某些storage server上,为了尽量避免访问到这样的storage,tracker按照如下规则选择group内可读的storage:

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

FastDFS整体架构图

1、每个小组的节点之间的数据完全相同,互为备份

2、各个小组的数据没有重复,加起来是整体架构存储的所有数据

FastDFSzheng

部署FastDFS环境

实验环境

主机IP 服务 备注
192.168.1.1 Client/Nginx 可联网
192.168.1.4 tracker server1 可联网
192.168.1.5 tracker server2 可联网
192.168.1.6 storage group1-1/Nginx 可联网
192.168.1.7 storage group1-2/Nginx 可联网
192.168.1.8 storage group2-1/Nginx 可联网
192.168.1.9 storage group2-2/Nginx 可联网

实验步骤

安装FastDFS

每台主机进行网络对时,在Xshell连接下,可以同步操作,如果主机间时间不同步,后续操作,可能会出现一些错误

以下操作是在所有主机中进行操作的

ntpdate ntp.ntsc.ac.cn

创建FastDFS的数据和日志所在目录,yuqing是阿里开发本服务的大佬,所以这样命名,在配置文件中默认指了这个路径,所以需要创建

mkdir -p /home/yuqing/fastdfs

解决依赖关系

yum -y install libtool autoconf automake pcre-devel zlib-devel openssl-devel

解压FastDFS包

tar -zxf fastdfs.tar.gz -C /usr/local/src
cd /usr/local/src
ls
# libfastcommon是fastdfs的lib库,fastdfs是主程序
# fastdfs-nginx-module存放了与nginx相连接的模块,后面会用到
fastdfs  fastdfs-nginx-module  libfastcommon

安装FastDFS的lib库

cd /usr/local/src/libfastcommon/
./make.sh && ./make.sh install

安装FastDFS主程序

cd ../fastdfs
./make.sh && ./make.sh install

将配置文件示例复制为可使用配置文件

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
cp /usr/local/src/fastdfs/conf/http.conf /etc/fdfs
cp /usr/local/src/fastdfs/conf/mime.types /etc/fdfs

安装nginx

在storage的四台服务器上拖入nginx-1.17.8.tar.gz包,安装nginx

在FastDFS中有一个ngx_http_fastdfs_module.c模块,来连接nginx与FastDFS,在安装时会加入模块

192.168.1.6、192.168.1.7、192.168.1.8、192.168.1.9执行以下操作

tar zxf nginx-1.17.8.tar.gz -C /usr/src
cd /usr/src/nginx-1.17.8/

./configure --prefix=/usr/local/nginx \
--user=nginx --group=nginx \
--with-http_stub_status_module \
--add-module=/usr/local/src/fastdfs-nginx-module/src/

make && make install
useradd -M -s /sbin/nologin nginx
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin
cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/

client也需要安装nginx,只需要简单安装即可

192.168.1.1执行以下操作

tar zxf nginx-1.17.8.tar.gz -C /usr/src
cd /usr/src/nginx-1.17.8/
./configure --prefix=/usr/local/nginx --user=nginx --group=nginx
make && make install
useradd -M -s /sbin/nologin nginx
ln -s /usr/local/nginx/sbin/nginx /usr/local/sbin

在client添加反向代理

vim /usr/local/nginx/conf/nginx.conf
# server{}上面http{}下面添加不同组的storage的ip
    upstream storage_group1 {
        server 192.168.1.6:8888 max_fails=2 fail_timeout=30s;
        server 192.168.1.7:8888 max_fails=2 fail_timeout=30s;
    }
    upstream storage_group2 {
        server 192.168.1.8:8888 max_fails=2 fail_timeout=30s;
        server 192.168.1.9:8888 max_fails=2 fail_timeout=30s;
    }
# 在server里面添加
        location ~/group1/ {
            proxy_pass http://storage_group1;
        }
        location ~/group2/ {
            proxy_pass http://storage_group2;
        }

调整配置文件

修改client主机的clien.conf配置文件

vim /etc/fdfs/client.conf
# 添加两台tracker的ip地址
tracker_server=192.168.1.4:22122
tracker_server=192.168.1.5:22122

修改tracker(192.168.1.4)主机的tracker.conf配置文件

vim /etc/fdfs/tracker.conf
# 修改为本机ip
bind_addr=192.168.1.4
# 可以设置允许那些主机使用,没有做任何更改
allow_hosts=*

修改tracker(192.168.1.5)主机的tracker.conf配置文件

vim /etc/fdfs/tracker.conf
# 修改为本机ip
bind_addr=192.168.1.5

修改storage1-1(192.168.1.6)主机的storage.conf配置文件

vim /etc/fdfs/storage.conf
# 组号要与1-2的相同
group_name=group1
# 修改为本机ip
bind_addr=192.168.1.6
# 修改为两台tacker的ip
tracker_server=192.168.1.4:22122
tracker_server=192.168.1.5:22122
# 注意fastdfs规定nginx的端口号为8888,一会需要修改nginx端口号
http.server_port=8888

修改storage1-2(192.168.1.7)主机的storage.conf配置文件

vim /etc/fdfs/storage.conf
# 组号要与1-1的相同
group_name=group1
# 修改为本机ip
bind_addr=192.168.1.7
# 修改为两台tacker的ip
tracker_server=192.168.1.4:22122
tracker_server=192.168.1.5:22122

修改storage2-1(192.168.1.8)主机的storage.conf配置文件

vim /etc/fdfs/storage.conf
# 组号要与2-2的相同,不能与1-1和1-2的group号相同
group_name=group2
# 修改为本机ip
bind_addr=192.168.1.8
# 修改为两台tacker的ip
tracker_server=192.168.1.4:22122
tracker_server=192.168.1.5:22122

修改storage2-2(192.168.1.9)主机的storage.conf配置文件

vim /etc/fdfs/storage.conf
# 组号要与2-1的相同,不能与1-1和1-2的group号相同
group_name=group2
# 修改为本机ip
bind_addr=192.168.1.9
# 修改为两台tacker的ip
tracker_server=192.168.1.4:22122
tracker_server=192.168.1.5:22122

修改storage四台主机的mod_fastdfs.conf配置文件

四台只有group_name的设置有一些区别,在哪个组改为哪个即可,可以使用scp直接传文件,修改一处即可

vim /etc/fdfs/mod_fastdfs.conf
# 修改
base_path=/home/yuqing/fastdfs
# 修改为两台tacker的ip
tracker_server=192.168.1.4:22122
tracker_server=192.168.1.5:22122

# 哪台主机所在哪个组就改为哪个组号
group_name=group1
# 存储数据的id编号,加入group的组号
url_have_group_name = true
# 更改为组的个数,一共有几个就写几个
group_count = 2
# 取消注释
# 这部分是storage会使用到的模块,所以需要有两个group的信息
[group1]
group_name=group1
storage_server_port=23000
store_path_count=1    # 存储路径个数,存储路径只有一个,改为1即可
store_path0=/home/yuqing/fastdfs

[group2]
group_name=group2
storage_server_port=23000
store_path_count=1
store_path0=/home/yuqing/fastdfs

修改storage四台主机的nginx文件,四台主机完全一样,所以修改一台scp即可

vim /usr/local/nginx/conf/nginx.conf
# 在http模块中添加一个新的server模块
    server {
        listen 8888;
        server_name localhost;

        location ~/group[0-9]/M00/ {  # 通过匹配group的标识
            ngx_fastdfs_module;  # 匹配这个fastdfs模块
        }
    }

scp /usr/local/nginx/conf/nginx.conf 192.168.1.7:/usr/local/nginx/conf/
scp /usr/local/nginx/conf/nginx.conf 192.168.1.8:/usr/local/nginx/conf/
scp /usr/local/nginx/conf/nginx.conf 192.168.1.9:/usr/local/nginx/conf/

启动服务

四台storage启动nginx

nginx -t
nginx

四台storage启动storage

/etc/init.d/fdfs_storaged start
Reloading systemd:                                         [  确定  ]
Starting fdfs_storaged (via systemctl):                    [  确定  ]

启动两台tracker

/etc/init.d/fdfs_trackerd start 
Reloading systemd:                                         [  确定  ]
Starting fdfs_trackerd (via systemctl):                    [  确定  ]

client只需要启动nginx即可

nginx -t
nginx

放行防火墙端口或者关闭防火墙

firewall-cmd --add-port=80/tcp
firewall-cmd --add-port=8888/tcp
firewall-cmd --add-port=23000/tcp
firewall-cmd --add-port=22122/tcp

验证

fastdfs常用操作指令

每个操作指定client配置文件是因为需要去连接到tracker去连接存储节点

上传,随便找一张图片做示例,命名为1.jpg

fdfs_upload_file /etc/fdfs/client.conf /root/1.jpg
# 指定client.conf是因为里面写了关于tracker的位置
# /root/1.jpg是指定要上传的文件
# 报错为以下,关闭防火墙即可
[2020-03-04 12:00:49] ERROR - file: connection_pool.c, line: 130, connect to 192.168.1.5:22122 fail, errno: 113, error info: No route to host
# 正确执行完成后,返回存储路径及file_ID
group2/M00/00/00/wKgBCF5fKHCAHzKeAACGCKJq85Q948.jpg
# 它会存储在/home/yuqing/fastdfs/data/00/00/file_ID

以上表示上传成功,可以看到返回信息中,是存储在了group2中,所以在group2的两台主机都能找到该数据,数据存放在/home/yuqing/fdfs/目录中,根据返回信息的路径可以查看该数据

cd /home/yuqing/fastdfs/data/00/00/
ls
wKgBCF5fKHCAHzKeAACGCKJq85Q948.jpg

查看,访问client的ip加上传成功后的file_ID路径即可

http://192.168.1.1/group2/M00/00/00/wKgBCF5fKHCAHzKeAACGCKJq85Q948.jpg

下载

fdfs_download_file /etc/fdfs/client.conf \
group2/M00/00/00/wKgBCF5fKHCAHzKeAACGCKJq85Q948.jpg \
/root/2.jpg

删除

fdfs_delete_file /etc/fdfs/client.conf \
group2/M00/00/00/wKgBCF5fKHCAHzKeAACGCKJq85Q948.jpg

评论




正在载入...
PoweredHexo
HostedAliyun
DNSAliyun
ThemeVolantis
UV
PV
BY-NC-SA 4.0