FastDFS 分布式存储集群部署

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。

FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

环境准备

系统系统 centos7.4
六台服务器:
tracker:192.168.53.85-86
storage:192.168.53.72-75

架构图

安装Fastdfs

yum -y install gcc gcc-c++ libstdc++-devel pcre-devel zlib-devel wget make
yum -y groupinstall 'Development Tools'

 

下载解压 

wget -O libfastcommon-1.0.39.zip https://github.com/happyfish100/libfastcommon/archive/V1.0.39.zip
wget -O /usr/local/src/fastdfs-5.11.zip https://github.com/happyfish100/fastdfs/archive/V5.11.zip
unzip libfastcommon-1.0.39.zip
unzip fastdfs-5.11.zip

 

安装
安装FastDFS必须先安装libfastcommon类库,否则会导致报错

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

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

安装好之后,在/usr/bin目录下,可以看fdfs开头的命令工具

FastDFS安装完成之后,所有配置文件在/etc/fdfs目录下,tracker需要tracker.conf配置文件,storage需要storage.conf配置文件。

配置tracker(85/86)

mkdir -pv /data/fastdfs
chown -R fastdfs.fastdfs /data/fastdfs/

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

vi tracker.conf

disabled=false    #启用配置文件
port=22122        #设置tracker的端口号
base_path=/data/fastdfs #设置tracker的数据文件和日志目录(需手动创建)

connect_timeout=30      #连接超时时间30S
network_timeout=60      #网络超时时间60S 
max_connections=256     #最大并发连接数
work_threads=4          #工作线程数,最好和cpu核数保持一致
store_lookup=0          #选择上传文件模式 0代表group轮询 1指定特定group 2选择空间最大的group
#store_group=           #上传文件组,如果模式为1,则必须设置成核特定group一致的组名
store_server=0          #选择存储服务器上传文件 0代表轮询,1根据通过IP第的顺序 2通过优先级
store_path=0            #选择哪块存储盘上传文件 0代表轮询,2代表优先最大存储空间盘(路径)
download_server=0       #选择哪台存储服务器下载文件0代表轮询,1代表当前文件上传的源服务器
reserved_storage_space = 10% #系统保留存储空间10%

启动tracker

/etc/init.d/fdfs_trackerd start

没有报错,查看端口22122是否开始监听,确认启动是否成功。

ss -tunlp | grep fdfs
tcp LISTEN 0 128 *:22122 *:* users:(("fdfs_trackerd",pid=3678,fd=5))

 

查看tracker日志

tail /data/fastdfs/logs/trackerd.log
#内容
2018-10-11 19:04:28] INFO - FastDFS v5.11, base_path=/data/fastdfs, run_by_group=fastdfs, run_by_user=fastdfs ...
...

配置storage(72/73/74/75)

将存储节点分为两个组
group1 (72、73)
group2 (74、75)

创建存储目录和配置文件

mkdir -pv /data/fastdfs
chown -R fastdfs.fastdfs /data/fastdfs

cd /etc/fdfs
cp storage.conf.sample storage.conf

vi /etc/fdfs/storage.conf

group_name=group1                # 组名(第一组为group1,第二组为group2,依次类推...)
base_path=/data/fastdfs          # 数据和日志文件存储根目录
store_path0=/data/fastdfs        #第一个存储目录,第二个存储目录起名为:store_path1=xxx,其它存储目录名依次类推...
store_path_count=1               # 存储路径个数,需要和store_path个数匹配
tracker_server=192.168.53.85:22122       # tracker服务器IP和端口
tracker_server=192.168.53.86:22122       # tracker服务器IP和端口

 

启动Storage

启动storage,会根据配置文件的设置自动创建多级存储目录,查看端口23000是否开始监听,确认启动是否成功。

fdfs_storaged /etc/fdfs/storage.conf start 
netstat -unltp | grep fdfs
tcp        0      0 0.0.0.0:23000           0.0.0.0:*               LISTEN      8753/fdfs_storaged

 

也可以查看storage的日志是否启动成功。

tail /data/fastdfs/logs/storaged.log

 

验证storage是否登记到tracker服务器

可以在任一存储节点上使用如下命令查看集群的状态信息

fdfs_monitor /etc/fdfs/storage.conf

如果出现ip_addr = Active, 则表明storage服务器已经登记到tracker服务器,如下:

Storage 1:
 id = 192.168.53.72
 ip_addr = 192.168.53.72 (localhost) ACTIVE

在storage上安装nginx

安装

注意:fastdfs-nginx-module模块需要安装到每台storage上。

cd /usr/local/src
wget http://nginx.org/download/nginx-1.14.0.tar.gz
wget -O fastdfs-nginx-module_v1.20.zip https://github.com/happyfish100/fastdfs-nginx-module/archive/V1.20.zip
unzip fastdfs-nginx-module_v1.20.zip 
tar xf nginx-1.14.0.tar.gz

 

安装nginx的时候,添加 fastdfs-nginx-module-master模块,如: ./configure –add-module=../fastdfs-nginx-module/src/

cd /usr/local/src/nginx-1.14.0
./configure --prefix=/usr/local/nginx --add-module=../fastdfs-nginx-module-1.20/src
make && make install

 

解决报错
https://github.com/happyfish100/fastdfs-nginx-module/issues/31

/usr/include/fastdfs/fdfs_define.h:15:27: fatal error: common_define.h: No such file or directory
修改fastdfs-nginx-module-1.20/src/config文件,修改如下:
ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"
CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
然后重新configure make make install,就可以了

快速脚本:
sed -i 's#ngx_module_incs=.*#ngx_module_incs="/usr/include/fastdfs /usr/include/fastcommon/"#' ../fastdfs-nginx-module-1.20/src/config 
sed -i 's#CORE_INCS=.*#CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"#' ../fastdfs-nginx-module-1.20/src/config

 

配置

配置fastdfs-nginx-module

进入fastdfs-nginx-module的src目录,将md_fastdfs.conf配置文件拷贝到/etc/fdfs/目录中

cd /usr/local/src/fastdfs-nginx-module-1.20/src/
cp mod_fastdfs.conf /etc/fdfs/

配置 mod_fastdfs.conf
一般只需改动以下几个参数即可:

vim /etc/fdfs/mod_fastdfs.conf

base_path=/data/fastdfs           #保存日志目录
tracker_server=192.168.53.85:22122
tracker_server=192.168.53.86:22122 
storage_server_port=23000         #storage服务器的端口号
group_name=group1                 #当前服务器的group名 第一组group1、第二组group2
url_have_group_name = true        #文件url中是否有group名
store_path_count=1                #存储路径个数,需要和store_path个数匹配
store_path0=/data/fastdfs         #存储路径
group_count = 2                   #设置组的个数

在末尾增加3个组的具体信息:

[group1]
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/data/fastdfs

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

 

建立M00至存储目录的符号连接。

ln -sv /data/fastdfs/data /data/fastdfs/data/M00

 

配置nginx 
编辑/usr/local/nginx/conf配置文件目录下的nginx.conf,设置添加storage信息并保存。

vim /usr/local/nginx/conf/nginx.conf

server {
    listen 8080;  #与/etc/fdfs/storage.conf 中的 http.server_port=8888 相对应
    server_name _;

    location ~/group[0-9]/M00 {
        root /data/fastdfs/data;
        ngx_fastdfs_module;
    }
}

 

复制fastdfs中的http.conf、mime.types文件到/etc/fdfs

cp /usr/local/src/fastdfs-5.11/conf/{http.conf,mime.types} /etc/fdfs/

至此,nginx以及FastDFS插件模块设置完成。

运行

运行nginx之前,先要把防火墙中对应的端口打开(本例中为8080)。

iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
/etc/init.d/iptables save

 

启动nginx,确认启动是否成功。(查看是否对应端口8080是否开始监听)

/usr/local/nginx/sbin/nginx
  ngx_http_fastdfs_set pid=12768

netstat -unltp | grep nginx
  tcp        0      0 0.0.0.0:8080                0.0.0.0:*                   LISTEN      12769/nginx

 

可以打开浏览器,直接访问
http://192.168.53.72:8080
查看到欢迎页则说明,nginx运行成功。之后依次在其它storage上全部安装上nginx并确认运行正常。

将nginx设置为开机启动:

vim /etc/rc.d/rc.local

将运行命令行添加进文件:/usr/local/nginx/sbin/nginx

在tracker上安装nginx

在tracker上安装的nginx主要为了提供http访问的反向代理、负载均衡以及缓存服务。

安装

wget https://github.com/FRiCKLE/ngx_cache_purge/archive/2.3.tar.gz

tar xf nginx-1.14.0.tar.gz
cd /usr/local/src/nginx-1.14.0 
./configure --prefix=/usr/local/nginx --add-module=../ngx_cache_purge-2.3/
make && make install

 

配置

编辑/usr/local/nginx/conf配置文件目录下的nginx.conf,设置负载均衡

vim /usr/local/nginx/conf/nginx.conf

user  root;   #root防止404错误
worker_processes  4;    #根据CPU核心数而定

#error_log  logs/error.log;
#error_log  logs/error.log  notice;
#error_log  logs/error.log  info;
#pid        logs/nginx.pid;

events {
    worker_connections  65535;        #最大链接数
    use epoll;                        #新版本的Linux可使用epoll加快处理性能
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
    #                  '$status $body_bytes_sent "$http_referer" '
    #                  '"$http_user_agent" "$http_x_forwarded_for"';

    #access_log  logs/access.log  main;

    sendfile        on;
    tcp_nopush     on;

    #keepalive_timeout  0;
    keepalive_timeout  65;

    gzip  on;

    #设置缓存
    server_names_hash_bucket_size 128;
    client_header_buffer_size 32k;
    large_client_header_buffers 4 32k;
    client_max_body_size 300m;
    proxy_redirect off;
    proxy_set_header Host $http_host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
    proxy_connect_timeout 90;
    proxy_send_timeout 90;
    proxy_read_timeout 90;
    proxy_buffer_size 16k;
    proxy_buffers 4 64k;
    proxy_busy_buffers_size 128k;
    proxy_temp_file_write_size 128k; #设置缓存存储路径、存储方式、分配内存大小、磁盘最大空间、缓存期限 
    proxy_temp_path /data/fastdfs/cache/nginx/proxy_cache/tmp;
    proxy_cache_path /data/fastdfs/cache/nginx/proxy_cache levels=1:2 keys_zone=http-cache:200m inactive=1d max_size=30g;

    #设置group1的服务器
    upstream fdfs_group1 {
        server 192.168.53.72:8080 weight=1 max_fails=2 fail_timeout=30s;
        server 192.168.53.73:8080 weight=1 max_fails=2 fail_timeout=30s;
    }
    #设置group2的服务器
    upstream fdfs_group2 {
        server 192.168.53.74:8080 weight=1 max_fails=2 fail_timeout=30s;
        server 192.168.53.75:8080 weight=1 max_fails=2 fail_timeout=30s;
    }

server {
    listen       80;
    server_name localhost;

    location / {
        root   html;
        index  index.html index.htm;
    }

    #error_page  404              /404.html;

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }

   #设置group1的负载均衡参数
    location /group1/M00 {
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
        proxy_cache http-cache;
        proxy_cache_key $uri$is_args$args;
        proxy_cache_valid  200 304 12h;
        proxy_pass http://fdfs_group1;
        expires 30d;
    }

    #设置group2的负载均衡参数
    location /group2/M00 {
        proxy_next_upstream http_502 http_504 error timeout invalid_header;
        proxy_cache http-cache;
        proxy_cache_key $uri$is_args$args;
        proxy_cache_valid  200 304 12h;
        proxy_pass http://fdfs_group2;
        expires 30d;
    }
    
    #设置清除缓存的访问权限
    location ~/purge(/.*) {
        allow 127.0.0.1;
        deny all;
        proxy_cache_purge http-cache $1$is_args$args;
    }
}

建立缓存目录

mkdir -p /data/fastdfs/cache/nginx/proxy_cache/tmp

 

至此,nginx设置完成。

运行

运行nginx之前,先要把防火墙中对应的端口打开(本例中为8080)

iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 8080 -j ACCEPT
/etc/init.d/iptables save

 

启动nginx,确认启动是否成功。(查看是否对应端口8080是否开始监听)

/usr/local/nginx/sbin/nginx
 ngx_http_fastdfs_set pid=12768

[root@localhost ~]# netstat -unltp | grep nginx
 tcp 0 0 0.0.0.0:8080 0.0.0.0:* LISTEN 12769/nginx

 

也可查看nginx的日志是否启动成功或是否有错误。

配置client.conf文件。尝试上传一个文件到FastDFS,然后访问试试。

cp client.conf.sample  client.conf
vim /etc/fdfs/client.conf

 

修改以下参数:

base_path=/data/fastdfs                   #日志存放路径
tracker_server=192.168.53.85:22122         
tracker_server=192.168.53.86:22122 
http.tracker_server_port=8080

 

使用/usr/local/bin/fdfs_upload_file上传一个文件,程序会自动返回文件的URL。

fdfs_upload_file /etc/fdfs/client.conf /root/clara.jpg
 group1/M00/00/00/wKgKZVu_SraAMC-GAALOpyUcETI804.jpg

 

然后使用浏览器访问:

http://192.168.53.85/group1/M00/00/00/wKgKZVu_SraAMC-GAALOpyUcETI804.jpg

看有查看到图片,说明集群搭建成功!

报错解决

nginx日志报错 
在storage上配置nginx相关信息后启动nginx,查看日志发现报错:

tail /usr/local/nginx/logs/error.log
ngx_http_fastdfs_process_init pid=7526
[2018-10-12 09:47:12] ERROR - file: ini_file_reader.c, line: 824, include file "http.conf" not exists, line: "#include http.conf"
[2018-10-12 09:47:12] ERROR - file: ../fastdfs-nginx-module-1.20/src/common.c, line: 163, load conf file "/etc/fdfs/mod_fastdfs.conf" fail, ret code: 2
2018/10/12 09:47:12 [alert] 7525#0: worker process 7526 exited with fatal code 2 and cannot be respawned

 

解决:
复制fastdfs中的http.conf、mime.types文件到/etc/fdfs

cp /usr/local/src/fastdfs-5.11/conf/{http.conf,mime.types} /etc/fdfs/

查看日志,还报错 

cat /usr/local/nginx/logs/error.log
ngx_http_fastdfs_process_init pid=12813
[2018-10-12 14:05:33] ERROR - file: /usr/local/fastdfs-nginx-module/src/common.c, line: 180, config file: /etc/fdfs/mod_fastdfs.conf, you must set url_have_group_name to true to support multi-group!
2018-10-12 14:05:33 [alert] 12812#0: worker process 12813 exited with fatal code 2 and cannot be respawned

 

解决

vim  /etc/fdfs/mod_fastdfs.conf

#url_have_group_name=false
url_have_group_name=true

重启正常

测试图片无法访问 
搭建完成之后,访问http://192.168.53.85/group2/M00/00/00/wKg26VncfamAEqZ0AAu-4Kcs3QI677.jpg 地址图片总是报404无法找到,跟踪到storage服务器,查看nginx的error日志发现如下;

ERROR - file: /usr/local/fastdfs-nginx-module/src/common.c, line: 877, stat file: /root/fastdfs/data/00/00/wKg1Wlnchn2AOo0kAAu-4Kcs3QI239.jpg fail, errno: 13, error info: Permission denied

原因是nginx启动的时候默认会以nobody用户来启动,这样的话就权限访问/root/fastdfs/data的权限

修改这个问题有两个版本,第一个方案设置nginx以root身份启动,或者设置nobody用户权限可以访问/root/fastdfs/data地址。这里只展示第一种方案的修改

vim /usr/local/nginx/conf/nginx.conf

# 修改nobody为root
user root

发表评论