参考文档:
http://joelhy.github.io/2015/01/27/FastDFS-v5-06-deploy/
https://github.com/happyfish100
在一个网站的架构中存储是非常重要的一环,相比较于结构化的数据可以存储在mysql等结构化数据库中,但图片,影像等非结构化的数据很难存放在结构化的数据库当中,这时候就需要分布式文件系统来存放这类数据。
fastDFS:
Tracker:调度器,负责维持集群的信息,例如各group及其内部的storage node,这些信息也是storage node报告所生成;每个storage node会周期性向tracker发心跳信息;
storage server:以group为单位进行组织,任何一个storage server都应该属于某个group,一个group应该包含多个storage server;在同一个group内部,各storage server的数据互相冗余;
在fastDFS中Tracker将storage node生成的元数据报告存放在内存中,storage存放真正的数据。用户向Tracker请求存放或查找文件,Tracker将文件的元数据信息发送给用户,用户再向真正数据所在的节点发出请求。
文件名
group/M00/00/00/FILE_ID
- group:表示哪个组
- M00:表示组内的哪个设备
- 后面的两位十六进制数是由源头storage server ip、创建时的时间戳、大小、文件的校验码和一个随机数进行hash计算后生成;取前面两位做二级目录。
- FILE_ID:对前面的hash结果基于base64进行文本编码,转换为可打印字符;
文件同步:
每个storage server在文件存储完成后,会将其信息存于binlog, binlog不包含数据,仅包含文件名等元数据信息;binlog可用于同步;
上传和下载文件时的步骤
Upload File:
1、由client发起上传连接请求;
2、由tracker查找可用的storage server;
3、找到可用的storage server后,将其(ip:port)返回给client;
4、上传文件(文件的属性信息和文件内容);
5、生成文件的fid,将client提交的内容写入选定位置;
6、返回fid;
7、同步 存储文件信息至同组中的其它节点;
Download File:
客户端上传文件完成后,会收到storage server返回的FID,而后再次用到时,client会可根据此文件发出请求;
1、client向tracker发请求;
2、tracker根据文件名定位到group,并返回此group内的某一个storage server的信息(ip:port)给client;
3、client向得到的ip:port发请求;
4、storage server查找文件,并返回其内容给client;
挑选机制:
tracker如何挑选组:
1、rr
2、指定组
3、基于可用空间进行均衡,可用空间大者胜出;
如何在组中挑选storage server:
1、rr;
2、以ip为次序,找第一个;
3、以优先级为序,找第一个;
如何选择磁盘(存储路径):
1、rr;
2、剩余可用空间大者优先;
下面就让我们开始实验吧,使用3个节点,一个做Tracker另外两个做storage存储
#获取源码
git clone https://github.com/happyfish100/libfastcommon.git
git clone https://github.com/happyfish100/fastdfs.git
#编译安装
cd ~/fdfs/libfastcommon && ./make.sh && ./make.sh install
cd ~/fdfs/fastdfs && ./make.sh && ./make.sh install
配置Tracker跟踪器
修改配置文件
mkdir -p /data/fastdfs
cd /etc/fdfs
cp tracker.conf.sample tracker.conf
cp /root/fdfs/fastdfs/conf/http.conf .
cp /root/fdfs/fastdfs/conf/mime.types .
sed -i 's:base_path=.*:base_path=/data/fastdfs:g' tracker.conf
sed -i 's:http.server_port=.*:http.server_port=80:g' tracker.conf
配置unit文件
bash -c 'cat > /usr/lib/systemd/system/fdfs_trackerd.service << EOF
[Unit]
Description=fastdfs tracker server
After=network.target
[Service]
Type=forking
PIDFile=/data/fastdfs/data/fdfs_trackerd.pid
ExecStart=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf
ExecReload=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart
ExecStop=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf stop
[Install]
WantedBy=multi-user.target
EOF'
systemctl enable fdfs_trackerd.service
systemctl start fdfs_trackerd.service
安装并启动nginx
yum install -y nginx
systemctl start nginx
配置反向代理,在http上下文中添加
upstream fdfs {
server 192.168.31.201:80;
server 192.168.31.203:80;
}
在server上下文中添加
location /M00 {
proxy_pass http://fdfs;
}
配置Storage存储节点
修改配置文件
mkdir -p /data/fastdfs
cd /etc/fdfs
cp storage.conf.sample storage.conf
cp /root/fdfs/fastdfs/conf/http.conf .
cp /root/fdfs/fastdfs/conf/mime.types .
sed -i 's:base_path=.*:base_path=/data/fastdfs:g' storage.conf
sed -i 's:store_path0=.*:store_path0=/data/fastdfs:g' storage.conf
sed -i 's/tracker_server=.*/tracker_server=192.168.31.200:22122/g' storage.conf
sed -i 's:http.server_port=.*:http.server_port=80:g' storage.conf
配置unit文件
bash -c 'cat > /usr/lib/systemd/system/fdfs_storaged.service << EOF
[Unit]
Description=fastdfs storage server
After=network.target
[Service]
Type=forking
PIDFile=/data/fastdfs/data/fdfs_storaged.pid
ExecStart=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf
ExecReload=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart
ExecStop=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf stop
[Install]
WantedBy=multi-user.target
EOF'
systemctl enable fdfs_storaged.service
systemctl start fdfs_storaged.service
查看日志信息是否配置成功
tail /data/fastdfs/logs/storaged.log
tracker_client_thread.c, line: 310, successfully connect to tracker server 192.168.31.200:22122, as a tracker client, my ip is 192.168.31.201
storage_sync.c, line: 2733, successfully connect to storage server 192.168.31.203:23000
配置client客户端
客户端主机上也需要安装fastDFS,然后执行以下操作
mkdir -p /data/fastdfs
cd /etc/fdfs
cp client.conf.sample client.conf
sed -i 's:base_path=.*:base_path=/data/fastdfs:g' client.conf
sed -i 's/tracker_server=.*/tracker_server=192.168.31.200:22122/g' client.conf
接下来我们就可以开始测试了
上传测试
fdfs_upload_file /etc/fdfs/client.conf /usr/share/pixmaps/faces/flower.jpg
group1/M00/00/00/wKgfyVwfaMqALJmFAAAN9Ntu140990.jpg
查看文件信息
fdfs_file_info /etc/fdfs/client.conf group1/M00/00/00/wKgfyVwfaMqALJmFAAAN9Ntu140990.jpg
source storage id: 0
source ip address: 192.168.31.201
file create timestamp: 2018-12-23 18:51:54
file size: 3572
file crc32: 3681474445 (0xDB6ED78D)
下载测试
fdfs_download_file /etc/fdfs/client.conf group1/M00/00/00/wKgfyVwfaMqALJmFAAAN9Ntu140990.jpg
fastdfs-nginx-module 安装配置
同组之间的服务器复制文件有延迟的问题,假设Tracker服务器将文件上传到了192.168.31.201,文件ID已经返回客户端,后台将这个文件复制到同组的192.168.31.203上,如果复制还没有完成,客户端就用这个ID在203上取文件,肯定会出错。fastdfs-nginx-module模块可以重定向连接到源服务器取文件,避免客户端由于复制延迟的问题,出现错误。
fastdfs-nginx-module模块只需要安装到storage上。
下载nginx源码,fastDFS模块,安装依赖包
curl -O http://nginx.org/download/nginx-1.12.2.tar.gz
yum install -y redhat-rpm-config pcre-devel openssl-devel libxml2-devel \
libxslt-devel gd-devel perl-ExtUtils-Embed GeoIP-devel gperftools \
gperftools-devel
重新编译nginx
cd /root/fdfs/
git clone https://github.com/happyfish100/fastdfs-nginx-module.git
cd /root/rpm/nginx-1.12.2/
tar xvf nginx-1.12.2.tar.gz
cd nginx-1.12.2
mv /usr/sbin/nginx /usr/sbin/nginx.`date +'%Y%m%d'`
./configure --prefix=/usr/share/nginx --sbin-path=/usr/sbin/nginx --modules-path=/usr/lib64/nginx/modules --conf-path=/etc/nginx/nginx.conf --error-log-path=/var/log/nginx/error.log --http-log-path=/var/log/nginx/access.log --http-client-body-temp-path=/var/lib/nginx/tmp/client_body --http-proxy-temp-path=/var/lib/nginx/tmp/proxy --http-fastcgi-temp-path=/var/lib/nginx/tmp/fastcgi --http-uwsgi-temp-path=/var/lib/nginx/tmp/uwsgi --http-scgi-temp-path=/var/lib/nginx/tmp/scgi --pid-path=/run/nginx.pid --lock-path=/run/lock/subsys/nginx --user=nginx --group=nginx --with-file-aio --with-ipv6 --with-http_auth_request_module --with-http_ssl_module --with-http_v2_module --with-http_realip_module --with-http_addition_module --with-http_xslt_module=dynamic --with-http_image_filter_module=dynamic --with-http_geoip_module=dynamic --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-http_gzip_static_module --with-http_random_index_module --with-http_secure_link_module --with-http_degradation_module --with-http_slice_module --with-http_stub_status_module --with-http_perl_module=dynamic --with-mail=dynamic --with-mail_ssl_module --with-pcre --with-pcre-jit --with-stream=dynamic --with-stream_ssl_module --with-google_perftools_module --with-debug --with-cc-opt='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches -specs=/usr/lib/rpm/redhat/redhat-hardened-cc1 -m64 -mtune=generic' --with-ld-opt='-Wl,-z,relro -specs=/usr/lib/rpm/redhat/redhat-hardened-ld -Wl,-E' --add-module=/root/fdfs/fastdfs-nginx-module/src
make
cp objs/nginx /usr/sbin/nginx
#注意:如果是make install就是覆盖安装了
fast模块的配置
cp /root/fdfs/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/
touch /data/fastdfs/logs/mod_fastdfs.log
chown nginx:nginx /data/fastdfs/logs/mod_fastdfs.log
sed -i 's@base_path=.*@base_path=/data/fastdfs@g' /etc/fdfs/mod_fastdfs.conf
sed -i 's@tracker_server=.*@tracker_server=192.168.31.200:22122@g' /etc/fdfs/mod_fastdfs.conf
sed -i 's@store_path0=.*@store_path0=/data/fastdfs@g' /etc/fdfs/mod_fastdfs.conf
sed -i 's@log_filename=.*@log_filename=/data/fastdfs/logs/mod_fastdfs.log@g' /etc/fdfs/mod_fastdfs.conf
Storage服务器的nginx配置
添加
location /M00 {
alias /data/fastdfs/data;
ngx_fastdfs_module;
}
测试
http://192.168.31.200/M00/00/00/wKgfyVwfaMqALJmFAAAN9Ntu140990.jpg