fastdfs(二)Centos下双机配置

自己搭建了个环境,两台服务器,两台上都分别启动了一个storage和一个tracker节点,两个storage Server在同一个group下。这样两个服务器可以相互备份,不仅实现了读写的负载均衡,还实现了双击热备的效果。

安装fastdfs

两台centos主机IP分别是10.45.148.253和10.45.157.52

首先需要安装个公共库, wget https://github.com/happyfish100/libfastcommon/archive/V1.0.36.tar.gz,或者直接git clone https://github.com/happyfish100/libfastcommon.git。   进入文件夹后然后make,然后make install,从输出的log可以看出lib文件和头文件都在usr下

mkdir -p /usr/lib64
mkdir -p /usr/lib
install -m 755 libfastcommon.so /usr/lib64
install -m 755 libfastcommon.so /usr/lib
mkdir -p /usr/include/fastcommon
install -m 644 common_define.h hash.h chain.h logger.h base64.h shared_func.h pthread_func.h ini_file_reader.h _os_define.h sockopt.h sched_thread.h http_func.h md5.h local_ip_func.h avl_tree.h ioevent.h ioevent_loop.h fast_task_queue.h fast_timer.h process_ctrl.h fast_mblock.h connection_pool.h fast_mpool.h fast_allocator.h fast_buffer.h skiplist.h multi_skiplist.h flat_skiplist.h skiplist_common.h system_info.h fast_blocked_queue.h php7_ext_wrapper.h id_generator.h char_converter.h char_convert_loader.h /usr/include/fastcommon

从github上下载release的版本https://github.com/happyfish100/fastdfs/releases,或者直接git clone https://github.com/happyfish100/fastdfs.git 一样make & make install 下,速度非常快。

mkdir -p /usr/bin
mkdir -p /etc/fdfs
cp -f fdfs_trackerd /usr/bin
if [ ! -f /etc/fdfs/tracker.conf.sample ]; then cp -f ../conf/tracker.conf /etc/fdfs/tracker.conf.sample; fi
if [ ! -f /etc/fdfs/storage_ids.conf.sample ]; then cp -f ../conf/storage_ids.conf /etc/fdfs/storage_ids.conf.sample; fi
mkdir -p /usr/bin
mkdir -p /etc/fdfs
cp -f fdfs_storaged  /usr/bin
if [ ! -f /etc/fdfs/storage.conf.sample ]; then cp -f ../conf/storage.conf /etc/fdfs/storage.conf.sample; fi
mkdir -p /usr/bin
mkdir -p /etc/fdfs
mkdir -p /usr/lib64
mkdir -p /usr/lib
cp -f fdfs_monitor fdfs_test fdfs_test1 fdfs_crc32 fdfs_upload_file fdfs_download_file fdfs_delete_file fdfs_file_info fdfs_appender_test fdfs_appender_test1 fdfs_append_file fdfs_upload_appender /usr/bin
if [ 0 -eq 1 ]; then cp -f libfdfsclient.a /usr/lib64; cp -f libfdfsclient.a /usr/lib/;fi
if [ 1 -eq 1 ]; then cp -f libfdfsclient.so /usr/lib64; cp -f libfdfsclient.so /usr/lib/;fi
mkdir -p /usr/include/fastdfs
cp -f ../common/fdfs_define.h ../common/fdfs_global.h ../common/mime_file_parser.h ../common/fdfs_http_shared.h ../tracker/tracker_types.h ../tracker/tracker_proto.h ../tracker/fdfs_shared_func.h ../storage/trunk_mgr/trunk_shared.h tracker_client.h storage_client.h storage_client1.h client_func.h client_global.h fdfs_client.h /usr/include/fastdfs
if [ ! -f /etc/fdfs/client.conf.sample ]; then cp -f ../conf/client.conf /etc/fdfs/client.conf.sample; fi

这样就装完了,一共也就花了5分钟。

配置Tracker服务器

从安装时候输出的信息看,执行的bin文件在usr/bin下,配置文件在etc/fdfs下。
tracker和storage都需要一个data目录,先新建文件夹/work/fastdfs/data下新建storage、tracker文件夹。
然后配置tracker的配置文件

cp tracker.conf.sample tracker.conf

然后修改其中的base_path

# the base path to store data and log files
base_path=/work/fastdfs/data/tracker

这就配置完了,直接启动

fdfs_trackerd /etc/fdfs/tracker.conf start

检查是否正常启动

netstat -anp | grep fdfs
tcp        0      0 0.0.0.0:22122           0.0.0.0:*               LISTEN      5770/fdfs_trackerd

再看/work/fastdfs/data/tracker下有log和data两个文件夹,就是这么快。

配置Storage服务器

同样在etc下修改配置文件,其中tracker_server下可以增加多个地址,负载均衡用的

# the base path to store data and log files
base_path=/work/fastdfs/data/storage
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
store_path0=/work/fastdfs/data/storage

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=10.45.148.253:22122
tracker_server=10.45.157.52:22122

启动和检查

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

启动的时候发现错误”storage_ip_changed_dealer.c, line: 186, connect to tracker server 10.45.148.253:22122 fail, errno: 113, error info: No route to host” 需要在tracker上需要关闭防火墙

查看状态

/usr/bin/fdfs_monitor /etc/fdfs/storage.conf
[2017-09-11 16:00:18] DEBUG - base_path=/work/fastdfs/data/storage, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0

server_count=1, server_index=0

tracker server is 10.45.148.253:22122

group count: 1

Group 1:
group name = group1
disk total space = 47786 MB
disk free space = 40245 MB
trunk free space = 0 MB
storage server count = 2
active server count = 1
storage server port = 23000
storage HTTP port = 8888
store path count = 1
subdir count per path = 256
current write server index = 0
current trunk file id = 0

        Storage 1:
                id = 10.45.148.253
                ip_addr = 10.45.148.253 (localhost.localdomain)  ACTIVE
              
        Storage 2:
                id = 10.45.157.52
                ip_addr = 10.45.157.52  WAIT_SYNC

测试文件上传与下载

先创建一个client的目录/work/fastdfs/data/client,然后配置

# the base path to store log files
base_path=/work/fastdfs/data/client

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=10.45.148.253:22122

把刚才的配置文件上传

fdfs_test /etc/fdfs/client.conf upload /etc/fdfs/client.conf
This is FastDFS client test program v5.12

Copyright (C) 2008, Happy Fish / YuQing

FastDFS may be copied only under the terms of the GNU General
Public License V3, which may be found in the FastDFS source kit.
Please visit the FastDFS Home Page http://www.csource.org/
for more detail.

[2017-09-11 15:52:12] DEBUG - base_path=/work/fastdfs/data/client, connect_timeout=30, network_timeout=60, tracker_server_count=1, anti_steal_token=0, anti_steal_secret_key length=0, use_connection_pool=0, g_connection_pool_max_idle_time=3600s, use_storage_id=0, storage server id count: 0
tracker_query_storage_store_list_without_group:server 
1. group_name=, ip_addr=10.45.148.253, port=23000
group_name=group1, ip_addr=10.45.148.253, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/Ci2U_Vm2QKyAIkYBAAAFumsdOa450.conf
source ip address: 10.45.148.253
file timestamp=2017-09-11 15:52:12
file size=1466
file crc32=1797077422
example file url: http://10.45.148.253/group1/M00/00/00/Ci2U_Vm2QKyAIkYBAAAFumsdOa450.conf
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/Ci2U_Vm2QKyAIkYBAAAFumsdOa450_big.conf
source ip address: 10.45.148.253
file timestamp=2017-09-11 15:52:12
file size=1466
file crc32=1797077422
example file url: http://10.45.148.253/group1/M00/00/00/Ci2U_Vm2QKyAIkYBAAAFumsdOa450_big.conf

发现,10.45.148.253的storage的data/00/00 下有四个文件
Ci2U_Vm2QKyAIkYBAAAFumsdOa450_big.conf Ci2U_Vm2QKyAIkYBAAAFumsdOa450.conf
Ci2U_Vm2QKyAIkYBAAAFumsdOa450_big.conf-m Ci2U_Vm2QKyAIkYBAAAFumsdOa450.conf-m

但是10.45.157.52的storage没有文件,状态上也是(WAIT_SYNC等待同步)看了下10.45.148.253下的storage的日志:

file: storage_sync.c, line: 2745, connect to storage server 10.45.157.52:23000 fail, errno: 113, error info: No route to host

擦,又是防火墙问题。

这样文件就存储在了一个group下的两个storage下了,但是通过浏览器还是没有方法获取文件:http://10.45.148.253/group1/M00/00/00/Ci2U_Vm2QKyAIkYBAAAFumsdOa450.conf
因为这个fastdfs是个非常轻量级的工具,没有webServer的功能,需要通过ngnix或者其他web服务器才能够通过http访问。

这里还有一个问题,一个卷下(组)的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。如果卷中有两个ServerA和B,客户端写的时候写到了A,那么其他客户端可能从B中读取文件,这个时候由于有同步的延迟(fastdfs写成功一个就会返回,与ceph不同),可能是访问不到的。这个时候,正确的做法是找到已经写完成的ServerA,然后重定向过去。这个功能虽然可以在ngnix中利用负载均衡的功能实现,但是效率不高。如果卷中有两个Server还可以,但是有多个Server的时候ngnix是只能一个个去尝试的,命中完全靠猜。为了提高效率,有专门的fastdfs-nginx-module,这个Module可以快速定位到已经写成功的Server中,在出现上述问题的时候能够一次重定向成功。

部署中,ngnix有很多的插件,而且可以自己开发,所以,这个fastdfs-nginx-module需要单独的下载。
所以,需要在每个storage下都架设ngnix的web服务,然后再在其他的地方架设一个ngnix的负载均衡服务。
这里,虽然卷里面的Server没有master与slave的概念,没有了选举master的过程,看上去好像结构简单。但是互相同步的时候容易出错,需要更复杂的机制保证数据的一致性。

配置ngnix支持http下载

配置ngnix的web服务

首先在storage上配置nginx的webServer,需要增加fastdfs-nginx-module,先下载这个fastdfs-nginx-module,git clone https://github.com/happyfish100/fastdfs-nginx-module.git 下载下来后发现没有什么make文件,因为是需要和ngnix一起编译的。

下载ngnix
git clone https://github.com/nginx/nginx.git 或直接下载release版本wget https://github.com/nginx/nginx/archive/release-1.13.5.tar.gz

然后./configure 提示./configure: line 10: auto/options: No such file or directory 见了鬼了,明明有的,是相对路径的问题,需要在根目录下运行,注意最后一行需要添加插件的源码位置

./auto/configure \
--prefix=/usr/local/nginx \
--pid-path=/var/local/nginx/nginx.pid \
--lock-path=/var/lock/nginx/nginx.lock \
--error-log-path=/var/log/nginx/error.log \
--http-log-path=/var/log/nginx/access.log \
--with-http_gzip_static_module \
--http-client-body-temp-path=/var/temp/nginx/client \
--http-proxy-temp-path=/var/temp/nginx/proxy \
--http-fastcgi-temp-path=/var/temp/nginx/fastcgi \
--http-uwsgi-temp-path=/var/temp/nginx/uwsgi \
--http-scgi-temp-path=/var/temp/nginx/scgi \
--add-module=/work/fastdfs/fastdfs-nginx-module/src

然后 make && make install 修改配置文件/usr/local/nginx/conf下的nginx.conf文件

server {
	listen       8888;
	server_name  localhost;

	#charset koi8-r;

	#access_log  logs/host.access.log  main;

	location /group1/M00 {
		root  /work/fastdfs/data/storage/;
		ngx_fastdfs_module;
		index  index.html index.htm;
	}
	...
}

运行/usr/local/nginx/sbin/nginx,说有个目录没有,手动创建即可。查看

netstat -anp|grep 8888 

复制 fastdfs-nginx-module 源码中的配置文件到/etc/fdfs 目录, 并修改

tracker_server=10.45.148.253:22122
store_path0=/work/fastdfs/data/storage/
url_have_group_name = true

拷贝fastdfs/conf部分配置文件

cp http.conf mime.types /etc/fdfs

重启

nginx /usr/local/nginx/sbin/nginx -s reload

现在就可以访问

http://10.45.148.253:8888/group1/M00/00/00/Ci2U_Vm2QKyAIkYBAAAFumsdOa450.conf了。

同样配置10.45.157.52上的storage,通过http://10.45.157.52:8888/group1/M00/00/00/Ci2U_Vm2QKyAIkYBAAAFumsdOa450.conf也能访问。

到现在,可以通过http方式请求storage上的文件了,这两个storage上的文件是一样的,相互同步的。有负载均衡的作用,最后一步就是配置负载均衡了 负载均衡的配置,没有什么特别,七层的,一般的配置。这里需要说明下,如果只配置一个ngnix的负载均衡前端,那么会有单点故障的问题。一般是有多少个tracker就配置多少个nginx负载均衡端,那么这就又有另外一个问题,客户端需要知道所有的nginx的ip地址,当第一挂掉需要切换到另外的nginx上。

所以,最好还是用给的client来进行访问,client中配置了所有的tracker信息,自己就有了负载均衡的机制。

多个tracker

多个tracker低位是均等的,实现上看,tracker对于storage节点来说是被动的,storage是主动连接tracker的,而且tracker中没有需要持久化的数据,全部在内存。 所以,需要修改的只是在storage的节点中多增加一条tracker的记录

修改storage.conf配置文件 – 添加新的tracker

vim /etc/fdfs/storage.conf

添加以下内容

tracker_server=10.45.157.52:22122                    -- 再指定多一台tracker_server

重启storage节点

fdfs_storaged /etc/fdfs/storage.conf restart

修改storage节点的nginx-http-module模块配置文件,由于nginx-http-module需要和tracker进行通信,所以需要对mod_fastdfs.conf进行配置

vim /etc/fdfs/mod_fastdfs.conf

添加以下内容

tracker_server=10.45.157.52:22122                    -- 添加新增的tracker server

重启nginx

/usr/local/nginx/sbin/nginx -s reload

使用monitor命令查看storage情况 在任意一台storage上操作

fdfs_monitor /etc/fdfs/storage.conf
server_count=2, server_index=1                    
-- 表示tracker_server有2台 当前是第2台 
tracker server is 10.45.157.52:22122             
-- 当前的tracker server是10.45.157.52 刚好连到新的tracker server
-- 注意: 这里并没有同时列出2台tracker server  多敲几次fdfs_monitor命令 他每次都会随机选择一台tracker server

对于client端来说,同样增加下tracker即可。

总结

MYQA

Q: 测试的时候发现一个问题,按照上面的配置,虽然看起来像双击热备,但是当一个机器挂掉后,另外的机器的tracker写storage还是会返回挂掉的storage地址,这样会有一半的数据写失败。但是当只有一个storage挂掉后,tracker就能及时发现storage的掉线情况,不会写失败。
A: 一是可能是windows上c的客户端的bug,二是,可能这样部署有问题,只有两个tracker,当一个tracker挂掉后,另外一个tracker是不能准确判断storage的状态的(paxos算法这样么?待验证),所以维持不变。解决办法一是修改客户端逻辑,二是部署至少3个或以上的奇数个tracker提高系统稳定性。

参考

FastDFS【一】:FastDFS在Ubuntu的安装配置
FastDFS【二】:FastDFS配置Nginx
FastDFS多tracker配置(3)

Table of Contents