依赖环境版本说明:
操作系统CentOS6.5
- 目标
- 了解项目中使用FastDFS的原因和目的;
- 掌握FastDFS的架构组成部分,能说出tracker和storage的作用;
- 了解FastDFS+nginx上传和下载的执行流程;
- 掌握FastDFS+nginx在项目中作为图片服务器,上传和下载方法;
- 了解FastDFS+nginx集群的搭建。
- 应用场景
FastDFS是为互联网应用量身定做的一套分布式文件存储系统,非常适合用来存储用户图片、视频、文档等文件,但是FastDFS没有对文件做分块存储(图片、文档。压缩包等),因此不太适合分布式计算场景。
以下是使用FastDFS的部分用户列表:
大型网盘(有400个group,存储容量达到了6PB,文件数超过1亿)
UC (http://www.uc.cn/,存储容量超过10TB)
支付宝(http://www.alipay.com/)
京东商城(http://www.360buy.com/)
淘淘搜(http://www.taotaosou.com/)
赶集网(http://www.ganji.com/)
迅雷(http://www.xunlei.com/)
丫丫网(http://www.iyaya.com/)
58同城(http://www.58.com/)
搜房网(http://www.soufun.com/)
- FastDFS环境
FastDFS Server仅支持unix系统,在Linux和FreeBSD测试通过。在Solaris系统下网络通信方面有些问题。
编译需要的其他库文件有pthread(系统自带无需建立依赖),V5.0以前的版本依赖libevent;V5.0以后,不再依赖libevent。v5.04开始依赖libfastcommon,github下载地址:https://github.com/happyfish100/libfastcommon
v5版本从v5.05开始才是稳定版本,请使用v5版本的尽快升级到v5.05或更新的版本,建议升级到v5.08。
对libevent的版本要求为1.4.x,建议使用最新的stable版本,如1.4.14b。
注意,千万不要使用libevent 2.0非stable版本。测试了一下,libevent 2.0.10是可以正常工作的。
在64位系统下,可能需要自己在/usr/lib64下创建libevent.so的符号建立软链接。比如:
#ln -s /usr/lib/libevent.so /usr/lib64/libevent.so
在ubuntu 11及后续版本,可能会出现找不到动态库pthread库,解决方法参见:
http://bbs.chinaunix.net/thread-2324388-1-2.html
若出现libfastcommon版本不匹配问题,请执行如下命令:
#/bin/rm -rf /usr/local/lib/libfastcommon.so /usr/local/include/fastcommon
- FastDFS介绍
- 什么是FastDFS
(淘宝架构师_余庆)FastDFS是用c语言编写的一款开源的分布式文件系统,源码目前是开源在GitHub上面,由C语言开发FastDFS为互联网量身定制,充分考虑了冗余备份(双机热备)、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务,其中官方的建议是:(文件大小建议范围:4KB < file_size <500MB)。
- FastDFS架构
FastDFS架构如下图:看的出来Client就是我们使用的浏览器,或者APP对静态资源的引用等,从中也不难理解,其实Fastdfs集群是由Tracker 、Storage 组成。
Tracker: 是FastDFS的协调者,负责管理所有的storage server和group,每个storage在启动后会连接Tracker,告知自己所属的group、磁盘剩余空间、文件同步状况、文件上传下载次数等信息,并保持周期性的心跳,tracker根据storage的心跳信息,建立group==>[storage server list]的映射表;作用是负载均衡和调度,通过Tracker server在文件上传时可以根据一些策略找到Storage server提供文件上传服务,所以可以将tracker称为追踪服务器或调度服务器。
Storage: 以组(group或volume)为单位组织,一个group内包含多台storage机器,数据互为备份,存储空间以group内容量最小的storage为准,所以建议group内的多个storage尽量配置相同,以免造成存储空间的浪费;作用是文件存储,客户端上传的文件最终存储在Storage服务器上,Storage server没有实现自己的文件系统而是利用操作系统的文件系统来管理文件,所以可以将storage称为存储服务器。
如下图:
- Tracker 集群
FastDFS集群中的Tracker server可以有多台,Tracker server之间是相互平等关系同时提供服务,Tracker server不存在单点故障。客户端请求Tracker server采用轮询方式,如果请求的tracker无法提供服务则换另一个tracker。
- Storage集群
Storage集群采用了分组存储方式。storage集群由一个或多个组(group)构成,集群存储总容量为集群中所有组的存储容量之和。一个组由一台或多台存储服务器组成,组内的Storage server之间是平等关系,不同组的Storage server之间不会相互通信,同组内的Storage server之间会相互连接进行文件同步,从而保证同组内每个storage上的文件完全一致的。一个组的存储容量为该组内存储服务器容量最小的那个,由此可见组内存储服务器的软硬件配置最好是一致的。
采用分组存储方式的好处是灵活、可控性较强。比如上传文件时,可以由客户端直接指定上传到的组也可以由tracker进行调度选择。一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务能力(纵向扩容)。当系统容量不足时,可以增加组来扩充存储容量(横向扩容)。
- 文件上传流程
客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。
- 组名:文件上传后所在的storage组名称,在文件上传成功后有storage服务器返回,需要客户端自行保存。
- 虚拟磁盘路径:storage配置的虚拟路径,与磁盘选项store_path*对应。如果配置了store_path0则是M00,如果配置了store_path1则是M01,以此类推。
- 数据两级目录:storage服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件(256*256个文件)。
- 文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。
- 文件下载流程
tracker根据请求的文件路径即文件ID 来快速定义文件。比如请求下边的文件:
- 通过组名tracker能够很快的定位到客户端需要访问的存储服务器组是group1,并选择合适的存储服务器提供客户端访问。
- 存储服务器根据“文件存储虚拟磁盘路径”和“数据文件两级目录”可以很快定位到文件所在目录,并根据文件名找到客户端需要访问的文件。
- FastDFS+Nginx实现文件服务器
- 架构
- 架构图
- 架构描述
出于高可用的需求tracker和storage都使用两台服务器,storage使用两个组用以说明storage可以任意扩充组实现线性扩展。
- client
client请求tracker进行文件上传、下载、删除:
client可以通过java client API方式进行文件上传、下载、删除;
client可以通过http方式(浏览器端路径)进行文件下载。tracker通过nginx提供http下载接口;
不推荐(和其他文件服务器无区别):client也可以直接访问storage进行文件上传、下载、删除,但建议client通过tracker进行文件上传、下载、删除。
- Tracker Server
每个tracker server互相平等,tracker server上部署nginx是为了对外提供http文件下载接口,tracker上nginx只是起到代理、负载均衡的作用。tracker的nginx会代理转发至storage上的nginx。
tracker上的两个nginx可以采用主备方式实现高可用,nginx高可用参数nginx文档。
- Storage Server
每台storage上也部署nginx,storage上的nginx与tracker上的nginx有区别,storage上的nginx需要安装FastDSF-nginx-module模块,此模块的作用是使用FastDFS和nginx进行整合,nginx对外提供http文件下载接口,注意:nginx只提供文件下载接口不提供上传接口。文件上传仍然通过java client API进行。
- FastDFS集群的搭建
安装8台虚拟机(最小化安装,大家可以参考:这篇博客进行安装);
给8台虚拟机配置静态IP并且要能上网,大家可以参考:这篇博客进行配置,不过由于现在是最小化安装,是没有安装vim命令的,因此需要使用"vi"命令来修改文件。
配置好静态IP之后,我们使用XShell/CRT/Putty等工具来操作虚拟机(因为真实环境中我们是不大可能直接去操作服务器的,都是通过远程连接工具来进行操作的)。如下图所示,我使用的虚拟机分别是192.168.200.133、192.168.200.134、192.168.200.135、192.168.200.136、192.168.200.137、192.168.200.138、192.168.200.139、192.168.200.144。其中,192.168.200.133、192.168.200.134分别作为tracker1和tracker2。192.168.200.135、192.168.200.136作为group1,192.168.200.137、192.168.200.138作为group2,把192.168.200.139、192.168.200.144作为Nginx集群多层负载均衡。多层负载均衡会生成一个虚拟IP,我们最终会通过虚拟IP来访问我们的集群。
- FastDFS--Tracker安装
分别在192.168.200.133和192.168.200.134上安装tracker。
注:初次安装可只安装一台tracker方便调试。
- 下载
tracker和storage使用相同的安装包:
下载地址:http://sourceforge.net/projects/FastDFS/ 或 https://github.com/happyfish100/FastDFS (推荐)
本文档下载:FastDFS_v5.05.tar.gz,其他的版本也可以(向linux上传文件使用的FileZilla工具).
- FastDFS安装环境
FastDFS是C语言开发,建议在linux上运行,本文档使用CentOS6.5作为安装环境,因为此版本图形化界面和安装补丁都比较齐全。下载网址:https://www.centos.org/download/
安装FastDFS需要先将官网下载的源码进行编译,编译依赖gcc环境,如果没有gcc环境,需要安装gcc:
#yum install make cmake gcc gcc-c++
- 安装libevent库
FastDFS4.0版本依赖libevent库,此步骤可以忽略,因为fastDFS5.0版本以上已经依赖libfastcommon库,
如果需要,安装命令如下:
#yum -y install libevent
- 安装libfastcommon编译安装
libfastcommon是FastDFS官方提供的,libfastcommon包含了FastDFS运行所需要的一些基础库。
下载地址:https://sourceforge.net/projects/libfastcommon/
将libfastcommonV1.0.7.tar.gz拷贝至/usr/local/src下
#cp libfastcommonV1.0.7.tar.gz /usr/local/software
#cd /usr/local/software
#tar -zxvf libfastcommonV1.0.7.tar.gz
#cd libfastcommon-1.0.7
#./make.sh
#./make.sh install
注意:libfastcommon安装好后会自动将库文件安装至/usr/lib64下,由于FastDFS程序引用usr/local/lib或者是usr/lib目录,所以需要为/usr/lib64创建软连接(推荐)或者將文件拷贝到lib目录中(后面太多的文件复制容易乱):
libfastcommon默认安装到了/usr/lib64/libfastcommon.so;/usr/lib64/libfdfsclient.so
#ls |grep fast 查看
创建软连接命令:
#ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so
#ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so
#ln -s /usr/lib64/libfdfsclient.so /usr/local/lib/libfdfsclient.so
#ln -s /usr/lib64/libfdfsclient.so /usr/lib/libfdfsclient.so
- tracker编译安装
将FastDFS_v5.05.tar.gz拷贝至/usr/local/software下
#cp FastDFS_v5.05.tar.gz /usr/local/software
#cd /usr/local/software
#tar -zxvf FastDFS_v5.05.tar.gz
#cd FastDFS_v5.05
# ./make.sh
# ./make.sh install
安装过程中会发现它用了两个文件夹/usr/bin(命令工具包括上传、下载等)和/etc/fdfs(样例配置文件路徑),服务脚本:
/etc/init.d/fdfs_storaged
/etc/init.d/fdfs_trackerd
因为FastDFS服务脚本设置的bin目录是/usr/local/bin,但是实际命令安装在/usr/bin,可以进入/usr/bin中查看相应
的fads的相关命令:
# cd /usr/bin
# ls | grep fdfs
所以要修改两个服务脚本的命令路径(将/usr/local/bin替换为/usr/bin):
#cd /etc/init.d
#vi fdfs_trackerd
查找替换命令统一修改:Shift+:%s+/usr/local/bin+usr/bin
#cd /etc/init.d
#vi fdfs_storaged
查找替换命令统一修改:Shift+:%s+/usr/local/bin+usr/bin
- 配置fastdfs的tracker调度服务器的配置
安装成功后进入/etc/fdfs目录:
拷贝一份新的tracker配置文件:
#cd /etc/fdfs
#cp tracker.conf.sample tracker.conf
修改tracker.conf
#vi tracker.conf
修改内容如下:
disabled=false(可用)
base_path=/home/yuqing/FastDFS -->改为:base_path=/home/FastDFS/Tracker 注:默认的数据目录
port:22122 注:tracker端口
store_lookup=2-->改为0
注:该值默认是2(即负载均衡策略),现在把它修改为0(即轮询策略,修改成0方便测试,当然,最终还是要改回到2的。如果值为1的话表明要始终向某个group进行上传下载操作;
配置http端口:http.server_port=8000
由于我们指定的数据目录并不存在,所以创建tracker数据目录文件夹:
# mkdir -p /home/FastDFS/Tracker
此时启动tracker后目录文件夹中什么也没有;所以要配置防火墙,在防火墙中打开跟踪器端口(22122):
#vi /etc/sysconfig/iptables
添加如下端口行:
重启防火墙:
#service iptables restart
- 启动
# /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start或者
# /etc/init.d/fdfs_trackerd start(推荐,后台调的就是上面的命令)
成功启动后会在/home/FastDFS/Tracker中产生data、logs两个目录。
查看是否启动成功:
# ps -ef | grep fdfs
如果关闭Tracker命令:
# /etc/init.d/fdfs_trackerd stop
备注:可以不用配置
设置fastDFS跟踪器开启自动启动:
# vi /etc/rc.d/rc.local
添加如下信息:
## FastDFS Tracker
/etc/init.d/fdfs_trackerd start
- FastDFS--Storage安装
分别在192.168.200.135、192.168.200.136、192.168.200.137、192.168.200.138上安装storage。
注:初次安装可只安装一台storage方便调试。
- FastDFS安装环境
同tracker安装
- 安装libevent库
同tracker安装
- 安装libfastcommon
同tracker安装。
- storage编译安装
同tracker编译安装。
- 配置fastdfs的storage存储服务器
192.168.200.135、192.168.200.136、192.168.200.137、192.168.200.138这四台虚拟机为我们的存储节点,四个节点中同一组的配置应该是相同的,也就是192.168.200.135、192.168.200.136一组(组名为group1),192.168.200.137、192.168.200.138一组(组名为group2)。
安装成功后进入/etc/fdfs目录:
拷贝一份新的storage配置文件:
#cd /etc/fdfs
#cp storage.conf.sample storage.conf
修改storage.conf
#vi storage.conf
修改内容如下:
disabled=false
port=23000
group_name=group1
store_path_count=1
base_path=/home/yuqing/FastDFS-->改为:base_path=/home/FastDFS/Storage
store_path0=/home/yuqing/FastDFS-->改为:store_path0=/home/FastDFS/Storage--->M00
#如果有多个挂载磁盘则定义多个store_path,如下
#store_path1=.....------>M01
#store_path2=......------>M02
tracker_server=192.168.200.133:22122 #配置tracker服务器:IP
#如果有多个则配置多个tracker
tracker_server=192.168.200.134:22122
#配置http端口http.server_port=8888
其他参数保留默认,具体配置见文档(http://bbs.chinaunix.net/thread-1941456-1-1.html)
配置完了192.168.200.135,接下来我们把storage.conf文件复制到192.168.200.136、192.168.200.137、192.168.200.138这三台设备上。其中192.168.200.136这台设备与192.168.200.135同属于group1,因此把配置文件放到它的/etc/fdfs/目录后不用做任何修改。但是192.168.200.137和192.168.200.138这两台设备需要修改一下,修改也非常简单,只需要把group_name由group1改为group2就可以了.命令:
#scp -r /etc/fdfs/storage.conf root@192.168.200.134:/etc/fdfs/
创建storage数据存储目录文件夹:
#mkdir -p /home/FastDFS/Storage
- 配置防火墙自动重启(同上),启动
#vi /etc/sysconfig/iptables
防具墙中添加23000端口
重启防火墙:
#service iptables restart
启动storage:
# /etc/init.d/fdfs_storaged start
#tailf logs/storaged.log来查看启动信息
看到上面的信息,说明我们的tracker和storage集群搭建好了,下面我们测试一下tracker的高可用性,从上图可以看到目前使用的tracker leader,我们现在人为关掉这台tracker,可以看到自动切换成leader角色,说明配置成功。
当我们所有的tracker和storage节点都启动成功后,我们可以在任意的一个存储节点上查看存储集群的信息,命令:
#/usr/bin/fdfs_monitor /etc/fdfs/storage.conf 查看集群信息
可以看到tracker Server有两个,group的数量是2,第一组的IP有哪个,第二组的IP有哪个,与我们规划的集群完全一致。
相应的文件夹中产生data,logs两个文件夹查看:
# ps -ef |grep fdfs
备注:可以不用配置
设置FastDFS存储服务器为开机启动:
#vi /etc/rc.d/rc.local
添加:
##FastDFS Storage
#/etc/init.d/fdfs_storaged start
- tracker和storage集群上传图片测试
- 通过fdfs_test程序
由于目前还没有搭建完集群,因此我们暂且在tracker的一台设备上(我们就选择192.168.200.133这台设备)使用client来上传图片进行测试:
FastDFS安装成功可通过/usr/bin/fdfs_test测试上传操作。在tracker上上传:
拷贝文件/etc/fdfs/client.conf.sample并编辑/etc/fdfs/client.conf
修改内容如下:
base_path=/home/FastDFS/Tracker
tracker_server=192.168.200.133:22122
tracker_server=192.168.200.134:22122
使用格式:/usr/bin/fdfs_test 客户端配置文件地址 upload 上传文件
比如将/home下的图片上传到FastDFS中:
#/usr/bin/fdfs_test /etc/fdfs/client.conf upload /home/test.png或者
#/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /home/test.png (推荐)
打印如下日志或返回url:
This is FastDFS client test program v5.05
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.
[2015-05-18 02:07:10] DEBUG - base_path=/home/FastDFS, 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=192.168.101.5, port=23000
server 2. group_name=, ip_addr=192.168.101.6, port=23000
group_name=group1, ip_addr=192.168.101.5, port=23000
storage_upload_by_filename
group_name=group1, remote_filename=M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485.png
source ip address: 192.168.101.5
file timestamp=2015-05-18 02:07:11
file size=5103
file crc32=3979441827
example file url: http://192.168.101.5/group1/M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485.png
storage_upload_slave_by_filename
group_name=group1, remote_filename=M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png
source ip address: 192.168.101.5
file timestamp=2015-05-18 02:07:11
file size=5103
file crc32=3979441827
example file url: http://192.168.101.5/group1/M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png
注:使用的命令:/usr/bin/fdfs_upload_file /etc/fdfs/client.conf /usr/local/3.jpg,可以看到这条命令由3部分组成,第一部分是/usr/bin/fdfs_upload_file,意思是指定要进行上传文件操作,第二部分是/etc/fdfs/client.conf,意思是指定上传操作使用的配置文件,这个配置文件就是我们上面刚配置过的client.conf文件,第三部分是/usr/local/3.jpg,意思是指定要上传哪个目录下的哪个文件。按回车执行上传命令后,会返回一个串:group1/M00/00/00/wKicB1jjiFmAOUdkAAHk-VzqZ6w720.jpg,其中group1表示这张图片被保存在了哪个组当中,M00代表磁盘目录,如果电脑只有一个磁盘那就只有M00, 如果有多个磁盘,那就M01、M02...等等。00/00代表磁盘上的两级目录,每级目录下是从00到FF共256个文件夹,两级就是256*256个。wKicB1jjiFmAOUdkAAHk-VzqZ6w720.jpg表示被存储到storage上的3.jpg被重命名的名字,这样做的目的是为了防止图片名字重复。
http://192.168.101.5/group1/M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png就是文件的下载路径。
对应storage服务器上的/home/FastDFS/Storage/data/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png文件。
我们在搭建集群的时候,配置的策略是轮询策略,那么我们现在再上传一次该图片,看是否会存储到group2下面。如下图所示,发现这次返回的路径信息中显示存储到了group2下面。
由于现在还没有和nginx整合无法使用http下载。
- 通过java Client API
完整的测试方法参考测试源代码。
public class FastdfsClientTest {
//客户端配置文件
public String conf_filename = "F:\\workspace_indigo\\fastdfsClient\\src\\cn\\itcast\\fastdfs\\cliennt\\fdfs_client.conf";
//本地文件,要上传的文件
public String local_filename = "F:\\develop\\upload\\linshiyaopinxinxi_asd.xlsx";
//上传文件
@Test
public void testUpload() {
for(int i=0;i<10;i++){
try {
ClientGlobal.init(conf_filename);
TrackerClient tracker = new TrackerClient();
TrackerServer trackerServer = tracker.getConnection();
StorageServer storageServer = null;
StorageClient storageClient = new StorageClient(trackerServer,
storageServer);
NameValuePair nvp [] = new NameValuePair[]{
new NameValuePair("item_id", "100010"),
new NameValuePair("width", "80"),
new NameValuePair("height", "90")
};
String fileIds[] = storageClient.upload_file(local_filename, null,
nvp);
System.out.println(fileIds.length);
System.out.println("组名:" + fileIds[0]);
System.out.println("路径: " + fileIds[1]);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
- FastDFS 和nginx整合
- 在Storage上安装nginx
到目前为止,我们还是不能够使用http方式来上传或下载文件的,因此我们需要配置下nginx来达到这个目的。
- FastDFS-nginx-module(vi install可查看安装说明)
在4台storage上安装nginx,将FastDFS-nginx-module_v1.16.tar.gz传至/usr/local/software下
#cd /usr/local/software
#tar -zxvf FastDFS-nginx-module_v1.16.tar.gz -C /usr/local/software
#cd FastDFS-nginx-module/src
#cd fastdfs-nginx-module/src
修改FastDFS-nginx-module的config配置文件(将/usr/local/路径改为/usr/)
该配置文件的第四行我们需要做下修改,这是因为我们前面为了查看方便而把东西放到了/usr/local/include下,但是实际执行make install安装时却安装在了/usr/include下面,也就是我们多了一层local目录,因此我们需要把该行的两个local目录去掉。
#vi config
上传nginx:FileZilla
安装编译nginx所需的依赖包:
#yum install pcre
#yum install pcre-devel
#yum install zlib
#yum install zlib-devel
安装nginx(添加fastDFS-nginx-module模块)编译:
#cd /usr/local/software/
#tar -zxvf nginx-1.6.2.tar.gz
#cd nginx-1.6.2
#./configure --add-module=/usr/local/src/fastdfs-nginx-module/src
# make &&make install
将FastDFS-nginx-module/src下的mod_FastDFS.conf文件拷贝至/etc/fdfs/下
#cp mod_FastDFS.conf /etc/fdfs/
并修改mod_FastDFS.conf的内容:
#vi /etc/fdfs/mod_FastDFS.conf
修改:
connect_timeout=10 注:超时时间
base_path=/home/FastDFS(可使用默认)
tracker_server=192.168.200.133:22122
tracker_server=192.168.200.134:22122
url_have_group_name=true #url中包含group名称 注:是否允许从地址栏访问
store_path0=/home/FastDFS/Storage #指定数据文件存储路径
group_name=group1
group_count=2
添加:
[group1]
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/home/FastDFS/Storage
添加:
[group2]
group_name=group2
storage_server_port=23000
store_path_count=1
store_path0=/home/FastDFS/Storage
进行复制使用命令:
#scp mod_fastdfs.conf 192.168.200.136:/etc/fdfs/
#scp mod_fastdfs.conf 192.168.200.138:/etc/fdfs/
#scp mod_fastdfs.conf 192.168.200.137:/etc/fdfs/
复制完之后,我们到6、7、8这三台设备上看下配置文件是否就是我们刚才复制过去的文件。由于192.168.200.135这台设备与192.168.200.136这台设备同属group1,因此192.168.200.136这台设备不用做修改。我们只需把192.168.200.137和192.168.200.138这两台设备的这个配置文件的group名称改为group2即可。192.168.200.137的修改如下图所示,192.168.200.138与之一样。
复制FastDFS的部分(http.conf mime.types)配置文件到/etc/fdfs目录
#cd /usr/local/software/FastDFS/conf
# cp http.conf mime.types /etc/fdfs
在/fastDFS/Storage文件存储目录下创建软连接,将其连接到实际存放数据的目录
#ln -s /home/FastDFS/Storage/data/ /home/FastDFS/Storage/data/M00
配置nginx的配置文件
#cd /usr/local/nginx/conf
#vi nginx.conf
修改监听storage端口:
location ~/group([0-9])/M00 {
ngx_fastdfs_module;
}
防火墙中打开nginx的storage的端口
# vi /etc/sysconfig/iptables
添加:
#service iptables restart
#/usr/local/nginx/sbin/nginx
启动成功提示:pid号;
重启:#/usr/local/nginx/sbin/nginx -s reload
我们在地址栏输入:http://192.168.200.135:8888/group1/M00/00/00/wKicCFjj1xqAcN8EAAHk-VzqZ6w619.jpg.
- 在tracker上安装nginx反向代理
我们需要在两个跟踪器上安装nginx(也就是192.168.200.133和192.168.200.134)以提供反向代理服务,目的是使用统一的一个IP地址对外提供服务,一个tracker对应多个storage,通过nginx对storage负载均衡。
在每个tracker上安装nginx,两个 nginx为主备高可用。
解压ngx_cache_purge-2.3.tar.gz,如下
#cd /usr/local/software
#tar -zxvf ngx_cache_purge-2.3.tar.gz -C /usr/local/software
#cd ngx_cache_purge-2.3
下载需要的依赖库,在两台设备上依次执行下面四条命令。
#yum install pcre
#yum install pcre-devel
#yum install zlib
#yum install zlib-devel
安装nginx
#cd /usr/local/software
#tar -zxvf nginx-1.6.2.tar.gz
#cd / nginx-1.6.2
#./configure --add-module=/usr/local/software/ngx_cache_purge-2.3
#make && make install
下面我们需要修改下两台设备/usr/local/nginx/conf/目录下的nginx.conf文件,大家可以直接把下面代码替换这个目录下的该文件,也可以直接到:这个地址下载nginx.conf文件来替换。不过由于我们搭建环境的虚拟机IP可能不一样,因此,我们需要根据实际情况修改下IP等信息。(注意192.168.200.133和192.168.200.134这两台设备的/usr/local/nginx/conf/目录下的nginx.conf都要修改)
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
use 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;
#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_cache_path /fastdfs/cache/nginx/proxy_cache levels=1:2
keys_zone=http-cache:200m max_size=1g inactive=30d;
proxy_temp_path /fastdfs/cache/nginx/proxy_cache/tmp;
#group1的服务设置
upstream fdfs_group1 {
server 192.168.200.135:8888 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.200.1368888 weight=1 max_fails=2 fail_timeout=30s;
}
#group2的服务设置
upstream fdfs_group2 {
server 192.168.200.137:8888 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.200.138:8888 weight=1 max_fails=2 fail_timeout=30s;
}
server {
listen 8000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
#group1的负载均衡配置
location /group1/M00 {
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_cache http-cache;
proxy_cache_valid 200 304 12h;
proxy_cache_key $uri$is_args$args;
#对应group1的服务设置
proxy_pass http://fdfs_group1;
expires 30d;
}
location /group2/M00 {
proxy_next_upstream http_502 http_504 error timeout invalid_header;
proxy_cache http-cache;
proxy_cache_valid 200 304 12h;
proxy_cache_key $uri$is_args$args;
#对应group2的服务设置
proxy_pass http://fdfs_group2;
expires 30d;
}
location ~/purge(/.*) {
allow 127.0.0.1;
allow 192.168.156.0/24;
deny all;
proxy_cache_purge http-cache $1$is_args$args;
}
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;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
修改完nginx.conf文件之后,我们下面需要创建目录:
这是因为我们在nginx.conf文件中配置缓存路径时指定了该目录,但是这两个目录目前还不存在,因此我们需要在192.168.200.133和192.168.200.134这两台设备上都创建下这两个目录,由于涉及到多级,因此需要递归创建目录,使用命令:
#mkdir -p /fastdfs/cache/nginx/proxy_cache
#mkdir -p /fastdfs/cache/nginx/proxy_cache/tmp
#/usr/local/nginx/sbin/nginx
启动完之后,可以使用
#ps -ef | grep nginx
命令来查看nginx是否正常启动:
两台设备都启动完nginx之后,我们再在192.168.200.133上上传两次次图片,第一次返回的路径是在group1下,第二次返回的路径是在group2下。
由于我们在192.168.200.133和192.168.200.134上配置了代理,代理端口是8000,所以我们可以访问这两个IP的8000端口来访问我们刚才上传的图片:
http://192.168.200.133:8000/group1/M00/00/00/wKicCFjkOVGAMlQvAAHk-VzqZ6w757.jpg
http://192.168.200.134:8000/group1/M00/00/00/wKicCFjkOVGAMlQvAAHk-VzqZ6w757.jpg
这说明我们配置的代理完全没问题。
通过java客户端上传文件,使用浏览器访问,比如访问上传图片测试的文件:
访问storage:
http://192.168.200.135/group1/M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png
ip地址改为192.168.200.136也行,因为同一个分组的storage文件互相同步。
访问tracker:
http://192.168.200.133group1/M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png
ip地址改为192.168.200.134也行。
- Keepalived实现的nginx集群
nginx对外提供服务有可能碰到服务挂掉的时候,这时候高可用就显得异常重要了,因此现在我们搭建一个
nginx和keepalived结合实现的nginx集群高可用的环境,大家可以参考
首先介绍一下Keepalived,它是一个高性能的服务器高可用或热备解决方案,Keepalived主要来防止服务器单点故障的发生问题,可以通过其与Nginx的配合实现web服务端的高可用; Keepalived以VRRP协议为实现基础,用VRRP协议来实现高可用性(HA).VRRP (Virtual Router Redundancy Protocol)协议是用于实现路由器冗余的协议,VRRP协议将两台或多台路由器设备虚拟成一个设备,对外提供虚拟路由器IP(一个或多个)我们使用keepalived来管理两台设备的Nginx,并虚拟出一个IP,我们现在两台装有Nginx的设备分别是192.168.200.139和192.168.200.144,那么我们可以虚拟出一个192.168.200.xxx的IP,外界请求直接访问虚拟IP而不是真正的Nginx,让虚拟IP去访问提供服务的Nginx(注意:高可用是指同一时间提供服务的只有一台设备,提供服务的设备挂掉之后,备份服务器便开始提供服务)。
我们拿两台虚拟机来搭建nginx高可用环境,这两台设备分别是192.168.200.139(主机名是nginx1)和192.168.200.144(主机名是nginx2)
#vi /etc/hosts
添加:
192.168.200.139 nginx1
安装gcc,使用命令:
#yum install make cmake gcc gcc-c++
安装依赖:
#yum install pcre
#yum install pcre-devel
#yum install zlib
#yum install zlib-devel
安装nginx:
#cd /usr/local/software
#tar -zxvf nginx-1.6.2.tar.gz
#cd nginx-1.6.2 && ./configure --prefix=/usr/local/nginx
# make && make install
nginx默认的端口是80,我们需要在防火墙配置中添加80端口:"-A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT"从而可以让外界访问80端口,否则防火墙将禁止外界访问80端口。
#vi /etc/sysconfig/iptables
# service iptables restart
#/usr/local/nginx/sbin/nginx
#/usr/local/nginx/sbin/nginx -s stop
#/usr/local/nginx/sbin/nginx -s reload
通过浏览器访问nginx欢迎页,我们在地址栏输入:http://192.168.200.139/(80端口不用输也可以)或http://192.168.200.144:80/,如下图所示。
nginx的具体配置参考此地址;
配置Tracker服务器高可用、反向代理与负载均衡
其实上面可以通过30或31的8000端口进行文件访问了,下面统一端口,对33和34再进行一次负载均衡。
使用Keepalived + Nginx组成的高可用负载均衡集群,做两个Tracker节点中Nginx的负载均衡。
这里使用Nginx,将Keepalived 和 Nginx 安装到 133和134上,VIP为111。
#vi /usr/local/nginx/conf/nginx.conf
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
## FastDFS Tracker Proxy
upstream fastdfs_tracker {
server 192.168.200.133:8000 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.200.134:8000 weight=1 max_fails=2 fail_timeout=30s;
}
server {
listen 80;
server_name localhost;
location / {
root html;
index index.html index.htm;
}
error_page 500502503504/50x.html;
location = /50x.html {
root html;
}
## FastDFS Proxy
location /dfs {
root html;
index index.html index.htm;
proxy_pass http://fastdfs_tracker/;
proxy_set_header Host $http_host;
proxy_set_header Cookie $http_cookie;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
client_max_body_size 300m;
}
}
}
安装keepalived
下面我们在192.168.200.139和192.168.200.144两台设备上都安装下keepalived,
下载地址: keepalived-1.2.18.tar.gz。
#cd /usr/local/software
#tar -zxvf keepalived-1.2.18.tar.gz
安装一个软件包
#yum install -y openssl openssl-devel
#cd keepalived-1.2.18/ && ./configure --prefix=/usr/local/keepalived
#make && make install
安装完nginx之后,我们把keepalived做成一个服务,这样可以做到开机自动启动
1.创建/etc/keepalived目录,我们在下面的输入框中输入mkdir /etc/keepalived
2.复制几个文件到指定目录:先复制第一个文件,我们在下面的输入框中输入
#cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
下面复制第二个文件,我们在下面的输入框中输入
#cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
下面复制第三个文件,我们在输入框中输入
#cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
3.创建两个软链接:
首先创建第一个软链接,我们在下面的输入框中输入
#ln -s /usr/local/sbin/keepalived /usr/sbin/
下面我们创建第二个软链接,我们在下面的输入框中输入
#ln -s /usr/local/keepalived/sbin/keepalived /sbin/
4.设置成开机启动,我们在下面的输入框中输入
#chkconfig keepalived on
5.既然设置成了系统服务,启动该服务
#service keepalived start
# service keepalived restart
#ps -ef | grep keepalived
# service keepalived stop
下面我们使用keepalived来实现nginx的高可用
1、我们需要修改下/etc/keepalived/keepalived.conf文件,首先修改192.168.200.139上的这个文件,修改后的配置内容如下
! Configuration File for keepalived
global_defs {
router_id nginx1 #当前主机名
}
vrrp_script chk_nginx {
script "/etc/keepalived/nginx_check.sh"
interval 2 #时间间隔,每隔2s执行nginx_check.sh
weight -20 #192.168.200.139这个节点的优先级降低20
}
vrrp_instance VI_1 {
state MASTER #该节点角色
interface eth0 #虚拟机的网卡
virtual_router_id 111 #虚拟ip末端
mcast_src_ip 192.168.200.139
priority 100 #优先级
nopreempt #不抢占ip
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
track_script {
chk_nginx
}
virtual_ipaddress {
192.168.200.111
}
}
看完了配置文件,我们再来看下定时检查nginx的脚本文件nginx_check.sh(需要确保脚本格式是unix格式,方法是vi进入编辑模式,然后输入:set ff并按回车即可看到格式
#!/bin/sh
A=`ps -C nginx --no-header |wc -l`
if [ $A -eq 0 ];then
/usr/local/nginx/sbin/nginx
sleep 2
if [ `ps -C nginx --no-header |wc -l` -eq 0 ];then
killall keepalived
fi
fi
两个文件所在的目录是/etc/keepalived
# pwd
/etc/keepalived
# ll
总用量 8
-rw-r--r--. 1 root root 554 4月 9 01:51 keepalived.conf
-rw-r--r--. 1 root root 180 4月 9 03:30 nginx_check.sh
我们在192.168.200.139这个节点上也需要有这两个文件:注意virtual_router_id的值要与192.168.200.139这个节点配置的值要一致;由于目前nginx_check.sh脚本只有读权限,因此我们需要把两个节点上这个文件的权限放开:
#chmod 777 nginx_check.sh
上面做好了铺垫之后,我们现在启动nginx,不过在启动nginx之前要保持两个节点nginx.conf配置一致.
为了能够区分欢迎页是哪个节点的欢迎页,我们修改下欢迎页的信息
#cd /usr/local/nginx/
#cd html/
#vi index.html
# /usr/local/nginx/sbin/nginx -s reload
下面我们启动两个节点上的keepalived
#service keepalived start
启动keepalived之后,我们可以在两个节点上看到共同的虚拟IP192.168.200.111,如下图所示,我们发现在两个节点上都看到了虚拟IP192.168.200.111,这是不合理的,正确情况应该是只在Master角色的节点上有虚拟IP。
造成上图这种情况的原因是防火墙,为了避免因防火墙引起的各种问题,我们把两个节点的防火墙都关闭,而且可以设置开机也不启动防火墙,关闭防火墙的命令是:service iptables stop,设置不让防火墙开机重启的命令是chkconfig iptables off。关闭防火墙之后,我们再在两个节点查看IP信息,如下图所示,可以看到主节点192.168.200.139上有虚拟IP的信息,而备节点192.168.200.144上没有虚拟IP。这样才是正确的。
这时我们便可以通过使用虚拟IP:192.168.200.111来访问nginx了,如下图所示,可以看到我们这时访问到的是192.168.156.11这台设备上的nginx。之所以会看到这台设备上的nginx是因为我们给这台设备keepalived赋予的优先级是100,而另一台设备192.168.200.144上keepalived赋予的优先级是90,显然192.168.200.139的优先级要高于192.168.200.144,因此keepalived服务器会选择192.168.200.139这个节点上的nginx对外提供服务。
使用虚拟IP(推荐):
两个tracker的nginx为主备,对外由vip提供服务,使用域名访问如下:
比如vip对应的域名为img.test.com:
http://192.168.200.111/dfs/group1/M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png
http://img.test.com/group1/M00/00/00/wKhlBVVY2M-AM_9DAAAT7-0xdqM485_big.png
备注:启动集群步骤
1.启动6台设备(192.168.200.133、192.168.200.134、192.168.200.135、192.168.200.136、192.168.200.137、192.168.200.138)的nginx(其中192.168.200.139和192.168.200.144配置了keepalived开机自启动,顺带会启动nginx,因此这两台设备不用启动nginx)
2.启动tracker(192.168.200.133和192.168.200.134,启动命令:/etc/init.d/fdfs_trackerd start)
3.启动storage(192.168.200.135、192.168.200.136、192.168.200.137、192.168.200.138,启动命令:/etc/init.d/fdfs_storaged start)
这样FastDFS集群便都启动完了。
group1/M00/00/A3/wKjIh1rWrT6AfdCoAAEK9dxETzE871.jpg
- 性能测试
测试工具:
本次测试使用FastDFS安装包中自带的工具进行测试,该工具是开源代码工具,可以根据自身情况修改。
测试步骤:
- 进入测试脚本目录
#cd /usr/local/software/fastdfs-5.05/test
- 编译安装
#make &&make install
如果编译报错,要修改fastdfs的安装路径,需要更改编辑一下./Makefile 文件,当时系统环境是64位的,需要更改一下库的路径
INC_PATH = -I/usr/include -I/usr/include/fastdfs -I/usr/include/fastcommon
LIB_PATH = -L/usr/lib -lfdfsclient -lfastcommon
3修改tracker的配置文件(修改需要测试的tracker_server的ip和端口)
# vi /etc/fdfs/client.conf
4执行测试前要生成测试文件,执行
#./gen_files
会分别生成5k、50k、200k、1m、10m、100m的文件各一个,默认情况下测试upload会循环10次,那样客户端生成的tcp连接为10个,我们可以通过修改源文件修改这个值。修改test_upload.c
#vi test_upload.c
将常量PROCESS_COUNT 改为需要模拟的客户端tcp连接数,比如1000;
修改完后,需要重新编译一次修改完后,需要重新编译一次
#make && make install
5测试上传
修改测试上传的脚本,将默认的10修改为需要模拟的数,比如100,这个数不能超过之前配置的常量1000
#vi test_upload.sh 保存后
#sh ./test_upload.sh
#cd upload
#../combine_result 10
6测试下载
#sh ./test_download.sh
#cd download
#../combine_result 20
7测试删除
#sh ./test_delete.sh
#cd delete
#../combine_result 10
网络上测试说明:
测试环境: DFS单台虚拟服务器8核CPU,16G内存。 大图平均400K,小图平均14K。
利用合并存储,通过约40小时的持续上传1Byte文件,制造了1亿数据量。
测试结论:
1、DFS没有性能瓶颈的问题,上传和浏览时,不用传统的类似DB检索的过程,所以速度稳定可靠。
2、如果开启合并存储,上传和读取的速度,与普通存储差不多,可以放心使用。
- 附录
- 配置文件详解
- tracker.conf
# is this config file disabled
# false for enabled
# true for disabled
disabled=false
# 这个配置文件是否不生效,呵呵(改成是否生效是不是会让人感觉好点呢?) false 为生效(否则不生效) true反之
# bind an address of this host
# empty for bind all addresses of this host
bind_addr=
# 是否绑定IP,
# bind_addr= 后面为绑定的IP地址 (常用于服务器有多个IP但只希望一个IP提供服务)。如果不填则表示所有的(一般不填就OK),相信较熟练的SA都常用到类似功能,很多系统和应用都有
# the tracker server port
port=22122
# 提供服务的端口,不作过多解释了
# connect timeout in seconds
# default value is 30s
connect_timeout=30
#连接超时时间,针对socket套接字函数connect
# network timeout in seconds
network_timeout=60
# tracker server的网络超时,单位为秒。发送或接收数据时,如果在超时时间后还不能发送或接收数据,则本次网络通信失败。
# the base path to store data and log files
base_path=/home/yuqing/fastdfs
# base_path 目录地址(根目录必须存在,子目录会自动创建)
# 附目录说明:
tracker server目录及文件结构:
${base_path}
|__data
| |__storage_groups.dat:存储分组信息
| |__storage_servers.dat:存储服务器列表
|__logs
|__trackerd.log:tracker server日志文件
数据文件storage_groups.dat和storage_servers.dat中的记录之间以换行符(\n)分隔,字段之间以西文逗号(,)分隔。
storage_groups.dat中的字段依次为:
1. group_name:组名
2. storage_port:storage server端口号
storage_servers.dat中记录storage server相关信息,字段依次为:
1. group_name:所属组名
2. ip_addr:ip地址
3. status:状态
4. sync_src_ip_addr:向该storage server同步已有数据文件的源服务器
5. sync_until_timestamp:同步已有数据文件的截至时间(UNIX时间戳)
6. stat.total_upload_count:上传文件次数
7. stat.success_upload_count:成功上传文件次数
8. stat.total_set_meta_count:更改meta data次数
9. stat.success_set_meta_count:成功更改meta data次数
10. stat.total_delete_count:删除文件次数
11. stat.success_delete_count:成功删除文件次数
12. stat.total_download_count:下载文件次数
13. stat.success_download_count:成功下载文件次数
14. stat.total_get_meta_count:获取meta data次数
15. stat.success_get_meta_count:成功获取meta data次数
16. stat.last_source_update:最近一次源头更新时间(更新操作来自客户端)
17. stat.last_sync_update:最近一次同步更新时间(更新操作来自其他storage server的同步)
# max concurrent connections this server supported
# max_connections worker threads start when this service startup
max_connections=256
# 系统提供服务时的最大连接数。对于V1.x,因一个连接由一个线程服务,也就是工作线程数。
# 对于V2.x,最大连接数和工作线程数没有任何关系
# work thread count, should <= max_connections
# default value is 4
# since V2.00
# V2.0引入的这个参数,工作线程数,通常设置为CPU数
work_threads=4
# 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
# 上传组(卷) 的方式 0:轮询方式 1: 指定组 2: 平衡负载(选择最大剩余空间的组(卷)上传)
# 这里如果在应用层指定了上传到一个固定组,那么这个参数被绕过
# which group to upload file
# when store_lookup set to 1, must set store_group to the group name
store_group=group2
# 当上一个参数设定为1 时 (store_lookup=1,即指定组名时),必须设置本参数为系统中存在的一个组名。如果选择其他的上传方式,这个参数就没有效了。
# which storage server to upload file
# 0: round robin (default)
# 1: the first server order by ip address
# 2: the first server order by priority (the minimal)
store_server=0
# 选择哪个storage server 进行上传操作(一个文件被上传后,这个storage server就相当于这个文件的storage server源,会对同组的storage server推送这个文件达到同步效果)
# 0: 轮询方式
# 1: 根据ip 地址进行排序选择第一个服务器(IP地址最小者)
# 2: 根据优先级进行排序(上传优先级由storage server来设置,参数名为upload_priority)
# 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
# 选择storage server 中的哪个目录进行上传。storage server可以有多个存放文件的base path(可以理解为多个磁盘)。
# 0: 轮流方式,多个目录依次存放文件
# 2: 选择剩余空间最大的目录存放文件(注意:剩余磁盘空间是动态的,因此存储到的目录或磁盘可能也是变化的)
# 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 server 作为下载服务器
# 0: 轮询方式,可以下载当前文件的任一storage server
# 1: 哪个为源storage server 就用哪一个 (前面说过了这个storage server源 是怎样产生的) 就是之前上传到哪个storage server服务器就是哪个了
# reserved storage space for system or other applications.
# if the free(available) space of any stoarge server in
# a group <= reserved_storage_space,
# no file can be uploaded to this group.
# bytes unit can be one of follows:
### G or g for gigabyte(GB)
### M or m for megabyte(MB)
### K or k for kilobyte(KB)
### no unit for byte(B)
### XX.XX% as ratio such as reserved_storage_space = 10%
reserved_storage_space = 10%
# storage server 上保留的空间,保证系统或其他应用需求空间。可以用绝对值或者百分比(V4开始支持百分比方式)。
#(指出 如果同组的服务器的硬盘大小一样,以最小的为准,也就是只要同组中有一台服务器达到这个标准了,这个标准就生效,原因就是因为他们进行备份)
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info
# 选择日志级别(日志写在哪?看前面的说明了,有目录介绍哦 呵呵)
#unix group name to run this program,
#not set (empty) means run by the group of current user
run_by_group=
# 操作系统运行FastDFS的用户组 (不填 就是当前用户组,哪个启动进程就是哪个)
#unix username to run this program,
#not set (empty) means run by current user
run_by_user=
# 操作系统运行FastDFS的用户 (不填 就是当前用户,哪个启动进程就是哪个)
# allow_hosts can ocur more than once, host can be hostname or ip address,
# "*" means match all ip addresses, can use range like this: 10.0.1.[1-15,20] or
# host[01-08,20-25].domain.com, for example:
# allow_hosts=10.0.1.[1-15,20]
# allow_hosts=host[01-08,20-25].domain.com
allow_hosts=*
# 可以连接到此 tracker server 的ip范围(对所有类型的连接都有影响,包括客户端,storage server)
# sync log buff to disk every interval seconds
# default value is 10 seconds
sync_log_buff_interval = 10
# 同步或刷新日志信息到硬盘的时间间隔,单位为秒
# 注意:tracker server 的日志不是时时写硬盘的,而是先写内存。
# check storage server alive interval
check_active_interval = 120
# 检测 storage server 存活的时间隔,单位为秒。
# storage server定期向tracker server 发心跳,如果tracker server在一个check_active_interval内还没有收到storage server的一次心跳,那边将认为该storage server已经下线。所以本参数值必须大于storage server配置的心跳时间间隔。通常配置为storage server心跳时间间隔的2倍或3倍。
# thread stack size, should > 512KB
# default value is 1MB
thread_stack_size=1MB
# 线程栈的大小。FastDFS server端采用了线程方式。更正一下,tracker server线程栈不应小于64KB,不是512KB。
# 线程栈越大,一个线程占用的系统资源就越多。如果要启动更多的线程(V1.x对应的参数为max_connections,
V2.0为work_threads),可以适当降低本参数值。
# auto adjust when the ip address of the storage server changed
# default value is true
storage_ip_changed_auto_adjust=true
# 这个参数控制当storage server IP地址改变时,集群是否自动调整。注:只有在storage server进程重启时才完成自动调整。
# storage sync file max delay seconds
# default value is 86400 seconds (one day)
# since V2.00
storage_sync_file_max_delay = 86400
# V2.0引入的参数。存储服务器之间同步文件的最大延迟时间,缺省为1天。根据实际情况进行调整
# 注:本参数并不影响文件同步过程。本参数仅在下载文件时,判断文件是否已经被同步完成的一个阀值(经验值)
# the max time of storage sync a file
# default value is 300 seconds
# since V2.00
storage_sync_file_max_time = 300
# V2.0引入的参数。存储服务器同步一个文件需要消耗的最大时间,缺省为300s,即5分钟。
# 注:本参数并不影响文件同步过程。本参数仅在下载文件时,作为判断当前文件是否被同步完成的一个阀值(经验值)
# if use a trunk file to store several small files
# default value is false
# since V3.00
use_trunk_file = false
# V3.0引入的参数。是否使用小文件合并存储特性,缺省是关闭的。
# the min slot size, should <= 4KB
# default value is 256 bytes
# since V3.00
slot_min_size = 256
# V3.0引入的参数。
# trunk file分配的最小字节数。比如文件只有16个字节,系统也会分配slot_min_size个字节。
# the max slot size, should > slot_min_size
# store the upload file to trunk file when it's size <= this value
# default value is 16MB
# since V3.00
slot_max_size = 16MB
# V3.0引入的参数。
# 只有文件大小<=这个参数值的文件,才会合并存储。如果一个文件的大小大于这个参数值,将直接保存到一个文件中(即不采用合并存储方式)。
# the trunk file size, should >= 4MB
# default value is 64MB
# since V3.00
trunk_file_size = 64MB
# V3.0引入的参数。
# 合并存储的trunk file大小,至少4MB,缺省值是64MB。不建议设置得过大。
# if create trunk file advancely
# default value is false
trunk_create_file_advance = false
# 是否提前创建trunk file。只有当这个参数为true,下面3个以trunk_create_file_打头的参数才有效。
# the time base to create trunk file
# the time format: HH:MM
# default value is 02:00
trunk_create_file_time_base = 02:00
# 提前创建trunk file的起始时间点(基准时间),02:00表示第一次创建的时间点是凌晨2点。
# the interval of create trunk file, unit: second
# default value is 38400 (one day)
trunk_create_file_interval = 86400
# 创建trunk file的时间间隔,单位为秒。如果每天只提前创建一次,则设置为86400
# the threshold to create trunk file
# when the free trunk file size less than the threshold, will create
# the trunk files
# default value is 0
trunk_create_file_space_threshold = 20G
# 提前创建trunk file时,需要达到的空闲trunk大小
# 比如本参数为20G,而当前空闲trunk为4GB,那么只需要创建16GB的trunk file即可。
# if check trunk space occupying when loading trunk free spaces
# the occupied spaces will be ignored
# default value is false
# since V3.09
# NOTICE: set this parameter to true will slow the loading of trunk spaces
# when startup. you should set this parameter to true when neccessary.
trunk_init_check_occupying = false
#trunk初始化时,是否检查可用空间是否被占用
# if ignore storage_trunk.dat, reload from trunk binlog
# default value is false
# since V3.10
# set to true once for version upgrade when your version less than V3.10
trunk_init_reload_from_binlog = false
# 是否无条件从trunk binlog中加载trunk可用空间信息
# FastDFS缺省是从快照文件storage_trunk.dat中加载trunk可用空间,
# 该文件的第一行记录的是trunk binlog的offset,然后从binlog的offset开始加载
# if use storage ID instead of IP address
# default value is false
# since V4.00
use_storage_id = false
# 是否使用server ID作为storage server标识
# specify storage ids filename, can use relative or absolute path
# since V4.00
storage_ids_filename = storage_ids.conf
# use_storage_id 设置为true,才需要设置本参数
# 在文件中设置组名、server ID和对应的IP地址,参见源码目录下的配置示例:conf/storage_ids.conf
# if store slave file use symbol link
# default value is false
# since V4.01
store_slave_file_use_link = false
# 存储从文件是否采用symbol link(符号链接)方式
# 如果设置为true,一个从文件将占用两个文件:原始文件及指向它的符号链接。
# if rotate the error log every day
# default value is false
# since V4.02
rotate_error_log = false
# 是否定期轮转error log,目前仅支持一天轮转一次
# rotate error log time base, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
# default value is 00:00
# since V4.02
error_log_rotate_time=00:00
# error log定期轮转的时间点,只有当rotate_error_log设置为true时有效
# rotate error log when the log file exceeds this size
# 0 means never rotates log file by log file size
# default value is 0
# since V4.02
rotate_error_log_size = 0
# error log按大小轮转
# 设置为0表示不按文件大小轮转,否则当error log达到该大小,就会轮转到新文件中
# 以下是关于http的设置了 默认编译是不生效的 要求更改 #WITH_HTTPD=1 将 注释#去掉 再编译
# 关于http的应用 说实话 不是很了解 没有见到 相关说明 ,望 版主可以完善一下 以下是字面解释了
#HTTP settings
http.disabled=false # HTTP服务是否不生效
http.server_port=8080 # HTTP服务端口
#use "#include" directive to include http other settiongs
##include http.conf # 如果加载http.conf的配置文件 去掉第一个#
- Storage.conf
# is this config file disabled
# false for enabled
# true for disabled
disabled=false
#同上文了 就不多说了
# the name of the group this storage server belongs to
group_name=group1
# 指定 此 storage server 所在 组(卷)
# bind an address of this host
# empty for bind all addresses of this host
bind_addr=
# 同上文
# if bind an address of this host when connect to other servers
# (this storage server as a client)
# true for binding the address configed by above parameter: "bind_addr"
# false for binding any address of this host
client_bind=true
# bind_addr通常是针对server的。当指定bind_addr时,本参数才有效。
# 本storage server作为client连接其他服务器(如tracker server、其他storage server),是否绑定bind_addr。
# the storage server port
port=23000
# storage server服务端口
# connect timeout in seconds
# default value is 30s
connect_timeout=30
#连接超时时间,针对socket套接字函数connect
# network timeout in seconds
network_timeout=60
# storage server 网络超时时间,单位为秒。发送或接收数据时,如果在超时时间后还不能发送或接收数据,则本次网络通信失败。
# heart beat interval in seconds
heart_beat_interval=30
# 心跳间隔时间,单位为秒 (这里是指主动向tracker server 发送心跳)
# disk usage report interval in seconds
stat_report_interval=60
# storage server向tracker server报告磁盘剩余空间的时间间隔,单位为秒。
# the base path to store data and log files
base_path=/home/yuqing/fastdfs
# base_path 目录地址,根目录必须存在 子目录会自动生成 (注 :这里不是上传的文件存放的地址,之前是的,在某个版本后更改了)
# 目录结构 因为 版主没有更新到 论谈上 这里就不发了 大家可以看一下置顶贴:
# max concurrent connections server supported
# max_connections worker threads start when this service startup
max_connections=256
# 同上文
# work thread count, should <= max_connections
# default value is 4
# since V2.00
# V2.0引入的这个参数,工作线程数,通常设置为CPU数
work_threads=4
# the buff size to recv / send data
# default value is 64KB
# since V2.00
buff_size = 256KB
# V2.0引入本参数。设置队列结点的buffer大小。工作队列消耗的内存大小 = buff_size * max_connections
# 设置得大一些,系统整体性能会有所提升。
# 消耗的内存请不要超过系统物理内存大小。另外,对于32位系统,请注意使用到的内存不要超过3GB
# if read / write file directly
# if set to true, open file will add the O_DIRECT flag to avoid file caching
# by the file system. be careful to set this parameter.
# default value is false
disk_rw_direct = false
# V2.09引入本参数。设置为true,表示不使用操作系统的文件内容缓冲特性。
# 如果文件数量很多,且访问很分散,可以考虑将本参数设置为true
# if disk read / write separated
## false for mixed read and write
## true for separated read and write
# default value is true
# since V2.00
disk_rw_separated = true
# V2.0引入本参数。磁盘IO读写是否分离,缺省是分离的。
# disk reader thread count per store base path
# for mixed read / write, this parameter can be 0
# default value is 1
# since V2.00
disk_reader_threads = 1
# V2.0引入本参数。针对单个存储路径的读线程数,缺省值为1。
# 读写分离时,系统中的读线程数 = disk_reader_threads * store_path_count
# 读写混合时,系统中的读写线程数 = (disk_reader_threads + disk_writer_threads) * store_path_count
# disk writer thread count per store base path
# for mixed read / write, this parameter can be 0
# default value is 1
# since V2.00
disk_writer_threads = 1
# V2.0引入本参数。针对单个存储路径的写线程数,缺省值为1。
# 读写分离时,系统中的写线程数 = disk_writer_threads * store_path_count
# 读写混合时,系统中的读写线程数 = (disk_reader_threads + disk_writer_threads) * store_path_count
# when no entry to sync, try read binlog again after X milliseconds
# 0 for try again immediately (not need to wait)
sync_wait_msec=200
# 同步文件时,如果从binlog中没有读到要同步的文件,休眠N毫秒后重新读取。0表示不休眠,立即再次尝试读取。
# 出于CPU消耗考虑,不建议设置为0。如何希望同步尽可能快一些,可以将本参数设置得小一些,比如设置为10ms
# after sync a file, usleep milliseconds
# 0 for sync successively (never call usleep)
sync_interval=0
# 同步上一个文件后,再同步下一个文件的时间间隔,单位为毫秒,0表示不休眠,直接同步下一个文件。
# sync start time of a day, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
sync_start_time=00:00
# sync end time of a day, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
sync_end_time=23:59
# 上面二个一起解释。允许系统同步的时间段 (默认是全天) 。一般用于避免高峰同步产生一些问题而设定,相信sa都会明白
# write to the mark file after sync N files
# default value is 500
write_mark_file_freq=500
# 同步完N个文件后,把storage的mark文件同步到磁盘
# 注:如果mark文件内容没有变化,则不会同步
# path(disk or mount point) count, default value is 1
store_path_count=1
# 存放文件时storage server支持多个路径(例如磁盘)。这里配置存放文件的基路径数目,通常只配一个目录。
# store_path#, based 0, if store_path0 not exists, it's value is base_path
# the paths must be exist
store_path0=/home/yuqing/fastdfs
#store_path1=/home/yuqing/fastdfs2
# 逐一配置store_path个路径,索引号基于0。注意配置方法后面有0,1,2 ......,需要配置0到store_path - 1。
# 如果不配置base_path0,那边它就和base_path对应的路径一样。
# subdir_count * subdir_count directories will be auto created under each
# store_path (disk), value can be 1 to 256, default value is 256
subdir_count_per_path=256
# FastDFS存储文件时,采用了两级目录。这里配置存放文件的目录个数 (系统的存储机制,大家看看文件存储的目录就知道了)
# 如果本参数只为N(如:256),那么storage server在初次运行时,会自动创建 N * N 个存放文件的子目录。
# tracker_server can ocur more than once, and tracker_server format is
# "host:port", host can be hostname or ip address
tracker_server=10.62.164.84:22122
tracker_server=10.62.245.170:22122
# tracker_server 的列表 要写端口的哦 (再次提醒是主动连接tracker_server )
# 有多个tracker server时,每个tracker server写一行
#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info
# 日志级别不多说
#unix group name to run this program,
#not set (empty) means run by the group of current user
run_by_group=
# 同上文了
#unix username to run this program,
#not set (empty) means run by current user
run_by_user=
# 同上文了 (提醒注意权限 如果和 webserver不搭 可以会产生错误 哦)
# allow_hosts can ocur more than once, host can be hostname or ip address,
# "*" means match all ip addresses, can use range like this: 10.0.1.[1-15,20] or
# host[01-08,20-25].domain.com, for example:
# allow_hosts=10.0.1.[1-15,20]
# allow_hosts=host[01-08,20-25].domain.com
allow_hosts=*
# 允许连接本storage server的IP地址列表 (不包括自带HTTP服务的所有连接)
# 可以配置多行,每行都会起作用
# the mode of the files distributed to the data path
# 0: round robin(default)
# 1: random, distributted by hash code
file_distribute_path_mode=0
# 文件在data目录下分散存储策略。
# 0: 轮流存放,在一个目录下存储设置的文件数后(参数file_distribute_rotate_count中设置文件数),使用下一个目录进行存储。
# 1: 随机存储,根据文件名对应的hash code来分散存储。
# valid when file_distribute_to_path is set to 0 (round robin),
# when the written file count reaches this number, then rotate to next path
# default value is 100
file_distribute_rotate_count=100
# 当上面的参数file_distribute_path_mode配置为0(轮流存放方式)时,本参数有效。
# 当一个目录下的文件存放的文件数达到本参数值时,后续上传的文件存储到下一个目录中。
# call fsync to disk when write big file
# 0: never call fsync
# other: call fsync when written bytes >= this bytes
# default value is 0 (never call fsync)
fsync_after_written_bytes=0
# 当写入大文件时,每写入N个字节,调用一次系统函数fsync将内容强行同步到硬盘。0表示从不调用fsync
# sync log buff to disk every interval seconds
# default value is 10 seconds
sync_log_buff_interval=10
# 同步或刷新日志信息到硬盘的时间间隔,单位为秒
# 注意:storage server 的日志信息不是时时写硬盘的,而是先写内存。
# sync binlog buff / cache to disk every interval seconds
# this parameter is valid when write_to_binlog set to 1
# default value is 60 seconds
sync_binlog_buff_interval=60
# 同步binglog(更新操作日志)到硬盘的时间间隔,单位为秒
# 本参数会影响新上传文件同步延迟时间
# sync storage stat info to disk every interval seconds
# default value is 300 seconds
sync_stat_file_interval=300
# 把storage的stat文件同步到磁盘的时间间隔,单位为秒。
# 注:如果stat文件内容没有变化,不会进行同步
# thread stack size, should >= 512KB
# default value is 512KB
thread_stack_size=512KB
# 线程栈的大小。FastDFS server端采用了线程方式。
# 对于V1.x,storage server线程栈不应小于512KB;对于V2.0,线程栈大于等于128KB即可。
# 线程栈越大,一个线程占用的系统资源就越多。
# 对于V1.x,如果要启动更多的线程(max_connections),可以适当降低本参数值。
# the priority as a source server for uploading file.
# the lower this value, the higher its uploading priority.
# default value is 10
upload_priority=10
# 本storage server作为源服务器,上传文件的优先级,可以为负数。值越小,优先级越高。这里就和 tracker.conf 中store_server= 2时的配置相对应了
# if check file duplicate, when set to true, use FastDHT to store file indexes
# 1 or yes: need check
# 0 or no: do not check
# default value is 0
check_file_duplicate=0
# 是否检测上传文件已经存在。如果已经存在,则不存在文件内容,建立一个符号链接以节省磁盘空间。
# 这个应用要配合FastDHT 使用,所以打开前要先安装FastDHT
# 1或yes 是检测,0或no 是不检测
# file signature method for check file duplicate
## hash: four 32 bits hash code
## md5: MD5 signature
# default value is hash
# since V4.01
file_signature_method=hash
# 文件去重时,文件内容的签名方式:
## hash: 4个hash code
## md5:MD5
# namespace for storing file indexes (key-value pairs)
# this item must be set when check_file_duplicate is true / on
key_namespace=FastDFS
# 当上个参数设定为1 或 yes时 (true/on也是可以的) , 在FastDHT中的命名空间。
# set keep_alive to 1 to enable persistent connection with FastDHT servers
# default value is 0 (short connection)
keep_alive=0
# 与FastDHT servers 的连接方式 (是否为持久连接) ,默认是0(短连接方式)。可以考虑使用长连接,这要看FastDHT server的连接数是否够用。
# 下面是关于FastDHT servers 的设定 需要对FastDHT servers 有所了解,这里只说字面意思了
# you can use "#include filename" (not include double quotes) directive to
# load FastDHT server list, when the filename is a relative path such as
# pure filename, the base path is the base path of current/this config file.
# must set FastDHT server list when check_file_duplicate is true / on
# please see INSTALL of FastDHT for detail
##include /home/yuqing/fastdht/conf/fdht_servers.conf
# 可以通过 #include filename 方式来加载 FastDHT servers 的配置,装上FastDHT就知道该如何配置啦。
# 同样要求 check_file_duplicate=1 时才有用,不然系统会忽略
# fdht_servers.conf 记载的是 FastDHT servers 列表
# if log to access log
# default value is false
# since V4.00
use_access_log = false
# 是否将文件操作记录到access log
# if rotate the access log every day
# default value is false
# since V4.00
rotate_access_log = false
# 是否定期轮转access log,目前仅支持一天轮转一次
# rotate access log time base, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
# default value is 00:00
# since V4.00
access_log_rotate_time=00:00
# access log定期轮转的时间点,只有当rotate_access_log设置为true时有效
# if rotate the error log every day
# default value is false
# since V4.02
rotate_error_log = false
# 是否定期轮转error log,目前仅支持一天轮转一次
# rotate error log time base, time format: Hour:Minute
# Hour from 0 to 23, Minute from 0 to 59
# default value is 00:00
# since V4.02
error_log_rotate_time=00:00
# error log定期轮转的时间点,只有当rotate_error_log设置为true时有效
# rotate access log when the log file exceeds this size
# 0 means never rotates log file by log file size
# default value is 0
# since V4.02
rotate_access_log_size = 0
# access log按文件大小轮转
# 设置为0表示不按文件大小轮转,否则当access log达到该大小,就会轮转到新文件中
# rotate error log when the log file exceeds this size
# 0 means never rotates log file by log file size
# default value is 0
# since V4.02
rotate_error_log_size = 0
# error log按文件大小轮转
# 设置为0表示不按文件大小轮转,否则当error log达到该大小,就会轮转到新文件中
# if skip the invalid record when sync file
# default value is false
# since V4.02
file_sync_skip_invalid_record=false
# 文件同步的时候,是否忽略无效的binlog记录
下面是http的配置了。如果系统较大,这个服务有可能支持不了,可以自行换一个webserver,我喜欢lighttpd,当然ng也很好了。具体不说明了。相应这一块的说明大家都懂,不明白见上文。
#HTTP settings
http.disabled=false
# the port of the web server on this storage server
http.server_port=8888
http.trunk_size=256KB
# http.trunk_size表示读取文件内容的buffer大小(一次读取的文件内容大小),也就是回复给HTTP client的块大小。
# use the ip address of this storage server if domain_name is empty,
# else this domain name will ocur in the url redirected by the tracker server
http.domain_name=
# storage server上web server域名,通常仅针对单独部署的web server。这样URL中就可以通过域名方式来访问storage server上的文件了,
# 这个参数为空就是IP地址的方式。
#use "#include" directive to include HTTP other settiongs
##include http.conf