一、什么是 FastDFS?
FastDFS 是一个开源的轻量级分布式文件系统。它解决了大数据量存储和负载均衡等问 题。特别适合以中小文件(建议范围:文件大小为 4KB-500MB)为载体的在线服务,如 相册网站、视频网站等等。在 UC 基于 FastDFS 开发向用户提供了:网盘,社区,广告 和应用下载等业务的存储服务。
FastDFS 是一款开源的轻量级分布式文件系统纯 C 实现,支持 Linux、FreeBSD 等 UNIX 系统类 google FS,不是通用的文件系统,只能通过专有 API 访问,目前提供了 C、 Java 和 PHP API 为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高 扩展性 FastDFS 可以看做是基于文件的 key value pair 存储系统,称作分布式文件存 储服务更为合适。
FastDFS 服务端有三个角色:跟踪服务器(tracker)、存储服务器(storage)和客户 端(client)。
Tracker:跟踪服务器,主要做调度工作,起负载均衡的作用。在内存中记录集群中
所有存储组和存储服务器的状态信息,是客户端和数据服务器交互的枢纽。不记录文 件索引信息,占用的内存量很少。Tracker 是 FastDFS 的协调者,负责管理所有的 storage 和 group,每个 storage 在启 动后会连接 Tracker,告知自己所属的 group 等信息,并保持周期性的心跳,tracker 根据 storage 的心跳信息,建立 grou 与 storage 的映射表 。
group :组, 也可称为卷。 同组内服务器上的文件是完全相同的 ,同一组内的 storage 之间是对等的, 文件上传、 删除等操作可以在任意一台 storage 上进行 。
Storage:存储服务器(又称:存储节点或数据服务器),文件和文件属性(meta
data)都保存到存储服务器上。Storage 直接利用 OS 的文件系统调用管理文件。 Storage 以组(卷,group 或 volume)为单位组织,一个 group 内包含多台 storage 机 器,数据互为备份,存储空间以 group 内容量最小的 storage 为准,所以建议 group 内的多个 storage 尽量配置相同,以免造成存储空间的浪费。
client:客户端,作为业务请求的发起方,通过专有接口,使用 TCP/IP 协议与跟踪器
服务器或存储节点进行数据交互。FastDFS 向使用者提供基本文件访问接口,比如 upload、download、append、delete 等,以客户端库的方式提供给用户使用。
上传机制:
- 客户端想上传文件首相向 Tracker 发送请求获取 storage 的 IP 地址和端口
- Tracker 收到请求后查看 storage 剩余多少空间
- Storage 会将 IP 地址和端口返回给 Tracker
- Tracker 再将 IP 地址和端口返回给客户端
- 客户端得到 IP 地址和端口后便可以直接向 storage 直接上传文件
- storage 在保存图片的同时,会向 Tracker 进行汇报,告诉 Tracker 它当前是否还 留有剩余空间,以及剩余空间大小。
- 上传成功后,storage 会将上传成功生成的文件 ID 和保存位置一同返回给客户端,客 户端可通过此讯息的位置查看到文件
下载机制:
- 客户端通过上传得到的文件 ID 和保存位置向 Tracker 询问下载文件的 storage
- Tracker 查看 storage 得到空闲的 storage 信息
- Tracker 返回一台可用的 storage
- Client 直接和 storage 通讯完成文件下载
二、部署FastDFS
FastDFS 是一名叫余庆的国内工程师用 c 语言编写的一款开源的分布式文件系统 我们可以通过在 github 上通过他的地址 进行下载 需要的安装包。本次实验中我们需要的安装包有 libfastcommon ,FastDFS ,fastdfsnginx-module
环境如下:
由于我这个是test环境,所以什么都没有,刚开始需要安装git来获取命令
1、安装git(如果有可忽略):
[root@tracker1 ~]# yum -y install git
[root@tracker1 ~]# git config --global user.name test
[root@tracker1 ~]# git config --global user.email test@test.com
2、安装依赖 libfastcommon(不管是tracker还是storage或client都需要安装这个依赖)
#在github主页上复制下载地址
[root@tracker1 ~]# git clone https://github.com/happyfish100/libfastcommon.git
[root@tracker1 ~]# cd libfastcommon/
#由于作者已经写好了安装脚本,所以不需要像往常一样去进行安装,直接运行脚本即可
[root@tracker1 libfastcommon]# ./make.sh && ./make.sh install
3、安装DastDFS(不管是tracker还是storage或client都需要安装)
#安装方法基本上是大同小异
[root@tracker1 ~]# git clone https://github.com/happyfish100/fastdfs.git
[root@tracker1 ~]# cd fastdfs/
[root@tracker1 fastdfs]# ./make.sh && ./make.sh install
4、配置tracker1
[root@tracker1 fastdfs]# cd /etc/fdfs/
[root@tracker1 fdfs]# mkdir -p /data/tracker-fdfs
[root@tracker1 fdfs]# cp tracker.conf.sample tracker.conf
[root@tracker1 fdfs]# sed -i "s/bind_addr =/bind_addr =192.168.171.134/g" tracker.conf
[root@tracker1 fdfs]# sed -i "s/base_path = \/home\/yuqing\/fastdfs/base_path = \/data\/tracker-fdfs/g" tracker.conf
[root@tracker1 fdfs]# /etc/init.d/fdfs_trackerd start
Reloading systemd: [ OK ]
Starting fdfs_trackerd (via systemctl): [ OK ]
[root@tracker1 fdfs]# netstat -anput | grep 22122
tcp 0 0 192.168.171.134:22122 0.0.0.0:* LISTEN 41213/fdfs_trackerd
#tracker2配置相同,只需把监听IP更改即可
5、配置storage1
[root@storage1 ~]# cd /etc/fdfs/
[root@storage1 fdfs]# cp storage.conf.sample storage.conf
[root@storage1 fdfs]# sed -i "s/bind_addr =/bind_addr =192.168.171.140/g" storage.conf
[root@storage1 fdfs]# sed -i "s/base_path = \/home\/yuqing\/fastdfs/base_path = \/data\/storage-fdfs\/base/g" storage.conf
[root@storage1 fdfs]# sed -i "s/store_path0 = \/home\/yuqing\/fastdfs/store_path0 = \/data\/storage-fdfs\/store/g" storage.conf
[root@storage1 fdfs]# mkdir -p /data/storage-fdfs/base
[root@storage1 fdfs]# mkdir -p /data/storage-fdfs/store
[root@storage1 fdfs]# sed -i "s/tracker_server = 192.168.209.121:22122/tracker_server = 192.168.171.134:22122/g" storage.conf
[root@storage1 fdfs]# sed -i "s/tracker_server = 192.168.209.122:22122/tracker_server = 192.168.171.135:22122/g" storage.conf
[root@storage1 ~]# cd fastdfs/conf/
[root@storage1 conf]# cp mime.types http.conf /etc/fdfs/
#安装nginx模块,只需在storage上面部署即可
[root@storage1 ~]# git clone https://github.com/happyfish100/fastdfs-nginx-module.git
[root@storage1 ~]# cp fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
[root@storage1 ~]# vim /etc/fdfs/mod_fastdfs.conf
base_path=/data/storage-fdfs/store
tracker_server=192.168.171.134:22122
tracker_server=192.168.171.135:22122
storage_server_port=23000
group_name=group1
url_have_group_name = true
store_path0=/data/storage-fdfs/store
[root@storage1 ~]# yum -y install openssl-devel pcre-devel
[root@storage1 ~]# tar zxf nginx-1.14.0.tar.gz
[root@storage1 ~]# cd nginx-1.14.0/
[root@storage1 nginx-1.14.0]# ./configure --add-module=/root/fastdfs-nginx-module/src && make && make install
[root@storage1 nginx-1.14.0]# cd /usr/local/nginx/conf/
[root@storage1 conf]# vim nginx.conf
#找到server模块,在下方写入location
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location /group1/M00 {
root /data/storage-fdfs/store;
ngx_fastdfs_module;
}
[root@storage1 ~]# /usr/local/nginx/sbin/nginx # 启动服务
[root@storage1 fdfs]# /etc/init.d/fdfs_storaged start
Reloading systemd: [ 确定 ]
Starting fdfs_storaged (via systemctl): [ 确定 ]
[root@storage1 fdfs]# netstat -anput | grep 23000
tcp 0 0 192.168.171.140:23000 0.0.0.0:* LISTEN 54817/fdfs_storaged
[root@storage1 ~]# netstat -anput | grep 80
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 59420/nginx: master
tcp 0 0 192.168.171.140:23000 192.168.171.143:46280 ESTABLISHED 60985/fdfs_storaged
6、storage2配置
#之前的配置都相同
[root@storage2 ~]# scp root@192.168.171.140:/etc/fdfs/mod_fastdfs.conf /etc/fdfs/
[root@storage2 ~]# scp root@192.168.171.140:/etc/fdfs/storage.conf /etc/fdfs/
[root@storage2 ~]# vim /etc/fdfs/storage.conf
bind_addr =192.168.171.143
#安装nginx
[root@storage2 ~]# scp root@192.168.171.140:/usr/local/nginx/conf/nginx.conf /usr/local/nginx/conf/ # 将主配文件复制过来
[root@storage2 ~]# /etc/init.d/fdfs_storaged start
[root@storage2 ~]# /usr/local/nginx/sbin/nginx
[root@storage2 ~]# netstat -anput | grep 23000
[root@storage2 ~]# netstat -anput | grep 80
7、client端配置
[root@client ~]# cd /etc/fdfs/
[root@client fdfs]# cp client.conf.sample client.conf
[root@client fdfs]# mkdir -p /data/client
[root@client fdfs]# sed -i "s/base_path = \/home\/yuqing\/fastdfs/base_path = \/data\/client/g" client.conf
[root@client fdfs]# sed -i "s/tracker_server = 192.168.0.196:22122/tracker_server = 192.168.171.134:22122/g" client.conf
[root@client fdfs]# sed -i "s/tracker_server = 192.168.0.197:22122/tracker_server = 192.168.171.145:22122/g" client.conf
#下载一张图片用于测试
[root@client ~]# ls | grep test.jpg
test.jpg
[root@client ~]# fdfs_upload_file /etc/fdfs/client.conf test.jpg # 进行sha上传
group1/M00/00/00/wKirjF59zZmATNnrAAFEF6rSzeI733.jpg
#上述返回的信息,访问这张图片时会使用
#下方是在storage1上查看的,表示图片已经上传到了storage上
[root@storage1 /]# ls /data/storage-fdfs/store/data/00/00/
wKirjF59zZmATNnrAAFEF6rSzeI733.jpg
#那么怎么确定这张图片就是我们上传的那张图片,毕竟名称都是不一样的,可以使用md5sum来进行分析一波
[root@storage1 /]# cd /data/storage-fdfs/store/data/00/00/
[root@storage1 00]# md5sum wKirjF59zZmATNnrAAFEF6rSzeI733.jpg
369c05bf4fd335ea1a51838d209bf66a wKirjF59zZmATNnrAAFEF6rSzeI733.jpg
[root@client ~]# md5sum test.jpg
369c05bf4fd335ea1a51838d209bf66a test.jpg
#可以看到返回的信息识别码是一样的
[root@client ~]# fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/wKirjF59zZmATNnrAAFEF6rSzeI733.jpg b.jpg # 在终端上进行下载,如果最后不加上b.jpg的话,他下载下来名称是wkir.........那一串
[root@client ~]# ls | grep b.jpg
b.jpg
浏览器访问sttstorage上的nginx+上传图片时返回的ID
http://192.168.171.140/group1/M00/00/00/wKirjF59zZmATNnrAAFEF6rSzeI733.jpg
测试成功则访问到以下图片