前言
传统 web 站点部署大部分都是基于动静分离的方式,静态图片存放于一台 nfs 存储。但是这种架构有一个问题就是 nfs 存储是单点,而且如果图片量过大的时候,则 nfs 会成为性能短板。基于此可以采用分布式存储的替代方案来替代 nfs。
fastdfs 不但可以存储图片,还可以存储其他非结构化数据,其特性是可以存放海量的中小容量文件,而且性能和容量也不会成为瓶颈。
fastdfs 架构
fastdfs 基于如下两个组件组成:
- tracker 节点:存储数据的元数据节点,此节点存放的是所有数据的元数据,如数据路径,保存时间等信息。其信息是 storage 节点定时上传到 tracker 节点的。
- storage 节点:用于存放数据,storage 节点的特点是两个或多个节点为一组构成一个集群,类似于镜像集群,数据只存放于两台上任意一台,而另一台则自动从另一台同步数据,保证数据为双份或多份。
架构图:
fastdfs 访问步骤
上传文件步骤
- 客户端上传文件请求,请求到到 tracker 节点;
- tracker 节点基于内部算法选择合适的 storage 节点发送给客户端;
- 客户端访问指定的 storage 节点,然后保存到指定 storage 上;
访问文件步骤 - 客户端发起请求到 tracker 节点;
- tracker 节点基于请求文件路径可以得出文件存放在哪个 storage 节点上,因为请求文件名是包含路由信息的;
- tracker 节点返回 storage 节点信息给 client,client 访问 storage 节点拿到数据;
实验配置
此处采用 4 台服务器进行配置,一台既为 tracker 节点,也为 storage 节点,其余 3 台都为 storage 节点。
下载源码包制作成 rpm 包
安装的话可以通过编译安装,不过此处因为要安装 4 台服务器,所以我从 github 克隆下来源码制作成源码包进行分发安装,提高效率。
-
github 克隆源码包,因为 fastdfs 依赖于 libevent,所以需要首先安装 libevent。
git clone https://github.com/happyfish100/libfastcommon.git git clone https://github.com/happyfish100/fastdfs.git
-
修改下载先来的源码包目录名,加上版本号,版本号可以从目录内的 spec 文件内查看到,并且制作成.tar.gz 格式的包
mv libfastcommon libfastcommon-1.0.36 tar zcf libfastcommon libfastcommon-1.0.36.tar.gz libfastcommon libfastcommon-1.0.36/* mv fastdfs fastdfs fastdfs fastdfs-5.0.11 tar zcf fastdfs-5.0.11.tar.gz fastdfs-5.0.11/*
-
安装 development tools 编译包,然后创建 rpmbuild 目录,并把相应 tar.gz 包和 spec 文件拷贝到相应目录进行 rpm 包制作
mkdir /root/rpmbuild/{SOURCES,SPECS} mv libfastcommon libfastcommon-1.0.36.tar.gz /root/rpmbuild/SOURCES/ mv /root/libfastcommon-1.0.36/libfastcommon.spec /root/rpmbuild/SPECS/ mv fastdfs-5.0.11.tar.gz /root/rpmbuild/SOURCES/ mv /root/fastdfs-5.0.11/fastdfs.spec /rpm/rpmbuild/SPECS/
-
进入/root/rpmbuild/SPECS/目录,进行 rpm 包制作
rpmbuild -bb libfastcommon.spec rpmbuild -bb fastdfs.spec
-
制作完成之后会在 rpmbuild 目录下生成一些目录,如下:
其中 RPMS 目录为制作好的源码包
-
先安装 libfastcommon,因为 fastdfs 依赖它,然后再安装 fastdfs 即可,然后拷贝到其他服务器进行安装。
配置 tracker 节点
安装完成之后会在/etc 目录下生成 fdfs 目录,其中文件如下,其中为各种配置文件:
配置 tracker.conf
base_path=/data/fastdfs #修改工作路径为自己创建路径
port=22122 #监听端口为221222端口#
# the method of selecting group to upload files #指定文件上传方式时上传到哪个组#
# 0: round robin #轮询选择#
# 1: specify group #指定组#
# 2: load balance, select the max free space group to upload file #根据负载,哪个组剩余空间最大上传到哪个组#
store_lookup=2
# which group to upload file #如果指定组,此处指定上传到哪个组#
# when store_lookup set to 1, must set store_group to the group name
store_group=group2
# which storage server to upload file #上传到组内哪个服务器#
# 0: round robin (default) #轮询#
# 1: the first server order by ip address #ip小的服务器#
# 2: the first server order by priority (the minimal) #根据服务器优先级#
# Note: if use_trunk_file set to true, must set store_server to 1 or 2
store_server=0
# which path(means disk or mount point) of the storage server to upload file #上传到服务器哪个硬盘#
# 0: round robin #轮询#
# 2: load balance, select the max free space path to upload file #根据剩余空间#
store_path=0
# which storage server to download file #从组内哪个服务器请求数据#
# 0: round robin (default) #轮询#
# 1: the source storage server which the current file uploaded to #最开始上传到哪个服务器#
download_server=0
其他参数无需过多修改。
配置 storage 节点
-
四台服务器都需要配置 storage 节点,修改/etc/fdfs/storage.conf 文件
group_name=group1 #指定组名,此处四台服务器,两台为group1,两台为group2,组成镜像组# port=23000 #指定工作端口# store_path_count=1 #指定数据存储路径,如果有多个则按照实际数量写,此处只有一个,则写1# store_path0=/data/storage #数据存储路径# tracker_server=192.168.11.200:22122 #tracker节点ip和端口# upload_priority=10 #数据上传优先级#
-
配置完成启动服务,tracker 服务器需要启动两个服务,storage 服务器只需要启动 storage 服务:
service fdfs_storaged start service fdfs_trackerd start
-
storage 服务器启动之后会在指定存储目录创建多级文件夹,上传的数据就是根据文件名 hash 值选择相应文件夹进行存放的,如下:
上传文件进行测试
-
上传文件需要配置一个节点为 client 节点,此处配置 tracker 节点也为 client 节点,修改/etc/fdfs/client.conf 配置文件,只需修改如下两项即可:
base_path=/data/fastdfs #client日志存储路径# tracker_server=192.168.11.200:22122 #tracker节点ip和端口#
-
上传文件,下图表示上传成功,并显示上传之后的文件名:
-
可以通过 fdfs_file_info 命令查看文件存储在哪里,下图表示存储在 ip 为 203 的节点上:
-
因为 203 和 204 服务器互为镜像,所以 204 节点此时在相同的目录下也会存在此文件。
编译安装 nginx,通过 http 发布文件
-
在文件存在相应服务器编译安装 nginx,需要给 nginx 打上 fastdfs-nginx-module 的补丁;
-
下载 fastdfs-nginx-module,从 https://github.com/happyfish100/fastdfs-nginx-module.git 通过 git clone 即可克隆下来;
-
下载 nginx 源码包进行编译
./configure --prefix=/usr --sbin-path=/usr/sbin/nginx --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --pid-path=/var/run/nginx/nginx.pid --lock-path=/var/lock/nginx.lock --user=nginx --group=nginx --with-http_ssl_module --with-http_flv_module --with-http_stub_status_module --with-http_gzip_static_module --http-client-body-temp-path=/var/tmp/nginx/client/ --http-proxy-temp-path=/var/tmp/nginx/proxy/ --http-fastcgi-temp-path=/var/tmp/nginx/fcgi/ --http-uwsgi-temp-path=/var/tmp/nginx/uwsgi --http-scgi-temp-path=/var/tmp/nginx/scgi --with-pcre --with-debug --add-module=../fastdfs-nginx-module/src/
-
在/usr/lib/systemd/system/路径下创建 nginx.service 文件
[Unit] Description=nginx server after=network.target remote-fs.target nss-lookup.target [service] type=forking pidfile=/run/nginx.pid execstartpre=/usr/bin/rm -rf /run/nginx.pid execstartpre=/usr/sbin/nginx -t execstart=/usr/bin/nginx execreload=/bin/kill -s HUP $MAINPID killsignal=SIGQUIT timeoutstopsec=5 killmode=process privatetmp=true [install] wantedby=multi-user.target
-
把 fastdfs-nginx-module 中的 mod_fastdfs.conf 拷贝到/etc/fdfs/路径下,并修改配置
base_path=/data/fastdfs #指定工作目录# tracker_server=192.168.11.200:22122 #指定tracker的ip地址# group_name=group2 #指定当前服务器所属组# url_have_group_name = false #此项如果为true,则访问文件需要在前面添加group信息,否则直接写M00即可# store_path0=/data/storage #指定存储路径# log_filename=/data/fastdfs/logs/mod_fastdfs.log #指定log日志文件路径#
-
编辑/etc/nginx/nginx.conf 文件,添加如下内容
location /M00 { alias /data/storage/data; ngx_fastdfs_module; }
-
启动 nginx,然后访问指定文件,如 group2/M00/00/00/wKgLy1ltrLCAZ4TOAA6q2wjnW8s371.jpg 文件,可以看到访问成功。
总结
现在文件只是能够分布式上传到不同的服务器节点了,但是如果要访问的话还需要在本地安装 nginx,不过 nginx 需要打 fastdfs-nginx-module 补丁才能使用。编译成功之后本地配置 nginx 的反向代理到指定的工作目录即可通过 nginx 访问到指定资源。不过生产环境中 fastdfs 中文件的上传下载都是通过前端的程序来自动写入和请求的。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于