FastDFS高性能分布式文件系统
Posted 追风逐影行者无疆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了FastDFS高性能分布式文件系统相关的知识,希望对你有一定的参考价值。
FastDFS高性能分布式文件系统
1.FastDFS文件系统现状
1.
2.
2.1. FastDFS文件系统简介
FastDFS是一个开源的轻量级分布式文件系统。它解决了大数据量存储和负载均衡等问题。特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务,如文件站点、图片站点、视频站点等。在UC基于FastDFS开发向用户提供了:网盘,社区,广告和应用下载等业务的存储服务。
FastDFS是一款开源的轻量级分布式文件系统纯C实现,支持Linux、FreeBSD等UNIX系统类Google FS,不是通用的文件系统,只能通过专有API访问,目前提供了C、Java和php API为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性FastDFS可以看做是基于文件的key value pair存储系统,称作分布式文件存储服务更为合适。
2.2. FastDFS文件系统架构介绍
FastDFS由跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端(Client)构成。
Ø 跟踪服务器Tracker Server
主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。tracker根据storage的心跳信息,建立group==>[storageserverlist]的映射表。
Tracker需要管理的元信息很少,会全部存储在内存中;另外tracker上的元信息都是由storage汇报的信息生成的,本身不需要持久化任何数据,这样使得tracker非常容易扩展,直接增加tracker机器即可扩展为tracker cluster来服务,cluster里每个tracker之间是完全对等的,所有的tracker都接受stroage的心跳信息,生成元数据信息来提供读写服务。
Ø 存储服务器Storage Server
主要提供容量和备份服务;以group 为单位,每个 group 内可以有多台storage server,数据互为备份。以group为单位组织存储能方便的进行应用隔离、负载均衡、副本数定制(group内storage server数量即为该group的副本数),比如将不同应用数据存到不同的group就能隔离应用数据,同时还可根据应用的访问特性来将应用分配到不同的group来做负载均衡;缺点是group的容量受单机存储容量的限制,同时当group内有机器坏掉时,数据恢复只能依赖group内地其他机器,使得恢复时间会很长。
group内每个storage的存储依赖于本地文件系统,storage可配置多个数据存储目录,比如有10块磁盘,分别挂载在/data/disk1-/data/disk10,则可将这10个目录都配置为storage的数据存储目录。storage接受到写文件请求时,会根据配置好的规则选择其中一个存储目录来存储文件。为了避免单个目录下的文件数太多,在storage第一次启动时,会在每个数据存储目录里创建2级子目录,每级256个,总共65536个文件,新写的文件会以hash的方式被路由到其中某个子目录下,然后将文件数据作为本地文件存储到该目录中。
Ø 客户端Client
主要是上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。每个客户端服务器都需要安装nginx
基本架构如下图所示:
Ø FastDFS的存储策略
为了支持大容量,存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份和负载均衡的作用。
在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。当存储空间不足或即将耗尽时,可以动态添加卷。只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。
Ø FastDFS的上传过程
FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。
我们知道StorageServer会定期的向Tracker Server发送自己的存储信息。当Tracker Server Cluster中的Tracker Server不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。
当Tracker收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storage server。当分配好storage server后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个fileid,最后根据以上的信息生成文件名存储文件。文件名的格式如下:
Ø FastDFS的文件同步
写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。
每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。
storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。
Ø FastDFS的文件下载
客户端uploadfile成功后,会拿到一个storage生成的文件名,接下来客户端根据这个文件名即可访问到该文件。
跟upload file一样,在downloadfile时客户端可以选择任意tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。
2.FastDFS文件系统部署
3.
3.1. FastDFS文件系统安装
1.
2.
3.
3.1.
1.
2.
3.
3.1.
3.1.1. 安装组件
Nginx + FastDFS + fastdfs-nginx-module
部署结构:
tracker:storage0:192.168.80.32 storage1:192.168.80.30 storage2:192.168.80.31 nginx:192.168.80.32 |
下载下列最新的安装包:
fastdfs-master.zip
libfastcommon-master.zip
fastdfs-nginx-module-master.zip
nginx.tar.gz
Ø 防火墙设置
防火墙中打开tracker服务器端口( 默认为 22122)
shell> vi /etc/sysconfig/iptables
添加如下端口行:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 22122 -j ACCEPT |
storage服务器需要添加端口:
-A INPUT -m state --state NEW -m tcp -p tcp --dport 23000 -j ACCEPT |
重启防火墙:
shell> service iptables restart
Ø 所有服务器先安装libevent工具包
yum -y install libevent |
Ø 所有服务器安装libfastcommon工具包
1. 先将fastdfs-master.zip和libfastcommon-master.zip 上传至所有服务器的/opt文件夹下
2. 解压缩 unzip libfastcommon-master.zip
3. 编译安装
cd libfastcommon-master ./make.sh ./make.sh install |
4. 把/usr/lib64/libfastcommon.so文件向/usr/lib/下复制一份 (32位才需要)
3.1.2. 安装Tracker服务
Ø 编译安装
解压缩unzip fastdfs-master.zip
cd fastdfs-master ./make.sh ./make.sh install |
安装后在/usr/bin/目录下有以fdfs开头的文件都是编译出来的,配置文件都放到/etc/fdfs文件夹。
把/opt/fastdfs-master/conf目录下的所有的配置文件都复制到/etc/fdfs下。
cp -r /opt/fastdfs-master/conf/* /etc/fdfs |
Ø 创建文件存放路径
mkdir -p /data/fastdfs/tracker #创建tracker文件存放路径(tracker服务器才需要) mkdir -p /data/fastdfs/storage #创建storage 文件存放路径 mkdir -p /data/fastdfs/client #创建client 文件存放路径 |
Ø 配置tracker服务
修改/etc/fdfs/conf/tracker.conf文件
port=22122 #tracker服务端口 |
注:其它内容默认,有关配置说明参考以下补充内容。
tracker配置文件说明:
disabled=false#配置是否生效 bind_addr=192.168.6.102#绑定IP port=22122#服务端口 connect_timeout=30#连接超时时间 network_timeout=60# tracker server的网络超时,单位为秒。 base_path=/home/yangzi#目录地址,里面会创建data(存放存储服务器信息)、logs,日志文件 max_connections=256#系统提供服务最大连接数 work_threads=4#线程数,通常设置CPU数 store_lookup=2 上传组(卷) 的方式 0:轮询方式 1: 指定组 2: 平衡负载(选择最大剩余空间的组(卷)上传) 这里如果在应用层指定了上传到一个固定组,那么这个参数被绕过 store_group=group1 当上一个参数设定为1 时 (store_lookup=1,即指定组名时),必须设置本参数为系统中存在的一个组名。如果选择其他的上传方式,这个参数就没有效了 store_server=0 选择哪个storage server 进行上传操作(一个文件被上传后,这个storage server就相当于这个文件的storage server源,会对同组的storage server推送这个文件达到同步效果) # 0: 轮询方式 # 1: 根据ip 地址进行排序选择第一个服务器(IP地址最小者) # 2: 根据优先级进行排序(上传优先级由storage server来设置,参数名为upload_priority) store_path=0 选择storage server 中的哪个目录进行上传。storage server可以有多个存放文件的base path(可以理解为多个磁盘)。 # 0: 轮流方式,多个目录依次存放文件 # 2: 选择剩余空间最大的目录存放文件(注意:剩余磁盘空间是动态的,因此存储到的目录或磁盘可能也是变化的) download_server=0 选择哪个 storage server 作为下载服务器 # 0: 轮询方式,可以下载当前文件的任一storage server # 1: 哪个为源storage server 就用哪一个 (前面说过了这个storage server源 是怎样产生的) 就是之前上传到哪个storage server服务器就是哪个了 reserved_storage_space = 4GB storage server 上保留的空间,保证系统或其他应用需求空间(指出 如果同组的服务器的硬盘大小一样,以最小的为准,也就是只要同组中有一台服务器达到这个标准了,这个标准就生效,原因就是因为他们进行备份) log_level=info#选择日志级别 run_by_group=#操作系统运行FastDFS的用户组 run_by_user=#操作系统运行FastDFS的用户 allow_hosts=*#可以连接到此 tracker server 的ip范围(对所有类型的连接都有影响,包括客户端,storage server) sync_log_buff_interval = 10# 同步或刷新日志信息到硬盘的时间间隔,单位为秒 # 注意:tracker server 的日志不是时时写硬盘的,而是先写内存。 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 = 64KB# 线程栈的大小。FastDFS server端采用了线程方式。更正一下,tracker server线程栈不应小于64KB,不是512KB。 # 线程栈越大,一个线程占用的系统资源就越多。如果要启动更多的线程(V1.x对应的参数为max_connections, V2.0为work_threads),可以适当降低本参数值。 storage_ip_changed_auto_adjust = true# 这个参数控制当storage server IP地址改变时,集群是否自动调整。注:只有在storage server进程重启时才完成自动调整。 storage_sync_file_max_delay = 86400# V2.0引入的参数。存储服务器之间同步文件的最大延迟时间,缺省为1天。根据实际情况进行调整 storage_sync_file_max_time = 300# V2.0引入的参数。存储服务器同步一个文件需要消耗的最大时间,缺省为300s,即5分钟。 http.disabled=true# HTTP服务是否不生效 当然编译的时候我已经把 with_httpd宏去掉了, http.server_port=80# HTTP服务端口 # 下列参数只有 开启http服务才有用 http.check_alive_interval=30 http.check_alive_type=tcp http.check_alive_uri=/status.html http.need_find_content_type=true |
3.1.3. 配置storage服务
在2台storage服务器上配置storage服务,前题也是安装libfastcommon和fastdfs。
修改/etc/fdfs/conf/storage.conf文件。
group_name=group1 #存储组名 port=23000 #storage端口 23000 base_path=/data/fastdfs/storage #基础存储数据和日志文件 store_path0=/data/fastdfs/storage #group 所占用的目录或硬盘,有几个写几个 tracker_server=192.168.80.32:22122 #指定tracker1服务器 |
注:其它内容默认,有关配置说明参考本节后面补充内容。
只编辑tracker服务器上的client.conf
vim /etc/fdfs/client.conf base_path=/data/fastdfs/client #基础数据和日志文件 tracker_server=192.168.80.32:22122 #tracker1服务器 |
以上就是fastdfs的所有配置,下面分别启动32服务上的tracker、storage和30和31上的storage。
storage.conf配置说明:
disabled=false#配置是否生效 group_name=group1#storage所在组(卷) bind_addr=192.168.6.100# 绑定IP,另一太 storage IP为 192.168.6.101 client_bind=true#bind_addr通常是针对server的。当指定bind_addr时,本参数才有效。 port=23000# 是storage 服务端口 connect_timeout=30# 连接超时时间,针对socket套接字函数connect network_timeout=60# storage server 网络超时时间,单位为秒。 heart_beat_interval=30# 心跳间隔时间,单位为秒 stat_report_interval=60# storage server向tracker server报告磁盘剩余空间的时间间隔,单位为秒。 base_path=/home/eric# base_path 目录地址,根目录必须存在 子目录会自动生成 # 会产生data(数据存储地方)、 logs日志文件 max_connections=256# 最大连接数 buff_size = 256KB# 设置队列结点的buffer大小。 work_threads=4# 工作线程数 disk_rw_separated = true# 磁盘IO读写是否分离,缺省是分离的。 disk_reader_threads = 1# 针对单个存储路径的读线程数,缺省值为1 disk_writer_threads = 1# 针对单个存储路径的写线程数,缺省值为1 sync_wait_msec=200# 同步文件时,如果从binlog中没有读到要同步的文件,休眠N毫秒后重新读取,0表示不休眠,立即再次尝试读取。 sync_interval=0# 同步上一个文件后,再同步下一个文件的时间间隔,单位为毫秒,0表示不休眠,直接同步下一个文件。 sync_start_time=00:00 sync_end_time=23:59# 允许系统同步的时间段 (默认是全天) 。一般用于避免高峰同步产生一些问题而设定,相信sa都会明白。 write_mark_file_freq=500# 把storage的mark文件定期同步到磁盘的时间间隔,单位为秒 store_path_count=1# 存放文件时storage server支持多个路径(例如磁盘)。这里配置存放文件的基路径数目,通常只配一个目录。 store_path0=/home/eric# 逐一配置store_path个路径,索引号基于0。注意配置方法后面有0,1,2 ......,需要配置0到store_path - 1。 # 如果不配置base_path0,那边它就和base_path对应的路径一样。 subdir_count_per_path=32# FastDFS存储文件时,采用了两级目录。这里配置存放文件的目录个数 tracker_server=192.168.6.188:22122# tracker_server 的列表 要写端口的哦 log_level=info# 日志级别 run_by_group=# 运行storage 用户组 run_by_user=# 运行storage 用户 allow_hosts=*# 允许连接IP列表 file_distribute_path_mode=0 # 文件在data目录下分散存储策略。 # 0: 轮流存放 # 1: 随机存储 file_distribute_rotate_count=100# 当上面的参数file_distribute_path_mode配置为0(轮流存放方式)时,本参数有效。 #当一个目录下的文件存放的文件数达到本参数值时,后续上传的文件存储到下一个目录中 fsync_after_written_bytes=0# 当写入大文件时,每写入N个字节,调用一次系统函数fsync将内容强行同步到硬盘。0表示从不调用fsync sync_log_buff_interval=10# 同步或刷新日志信息到硬盘的时间间隔,单位为秒 sync_binlog_buff_interval=60# 同步binglog(更新操作日志)到硬盘的时间间隔,单位为秒 sync_stat_file_interval=300# 把storage的stat文件同步到磁盘的时间间隔,单位为秒。 thread_stack_size=512KB# 线程栈的大小。FastDFS server端采用了线程方式。 # 线程栈越大,一个线程占用的系统资源就越多。 upload_priority=10 本storage server作为源服务器,上传文件的优先级,可以为负数。值越小,优先级越高。这里就和 tracker.conf 中store_server= 2时的配置相对应了 if_alias_prefix= check_file_duplicate=0 # 是否检测上传文件已经存在。如果已经存在,则不存在文件内容,建立一个符号链接以节省磁盘空间。 结合 fastdfh使用的。 1是检测,0是不检测,我们不使用fastdfh 当然 0 key_namespace=FastDFS# 当上个参数设定为1 或 yes时 (true/on也是可以的) , 在FastDHT中的命名空间 keep_alive=0# 与FastDHT servers 的连接方式 (是否为持久连接) # 下面是http的配置 http.disabled=true http.domain_name= http.server_port=80 http.trunk_size=256KB http.need_find_content_type=true |
3.1.4. 启动tracker
启动命令:
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf |
重启命令:
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart |
检查FastDFS Tracker Server是否启动成功:
ps -ef | grep fdfs_trackerd |
停止服务:
/etc/init.d/fdfs_trackerd stop |
设置tracker服务开机启动:
chkconfig fdfs_trakcerd on |
3.1.5. 启动storage服务
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart #停止storage服务器: /etc/init.d/fdfs_storaged stop #设置storage服务开机启动: chkconfig fdfs_storaged on |
3.1.6. 测试服务
/usr/bin/fdfs_test /etc/fdfs/client.conf upload /etc/fdfs/anti-steal.jpg |
有以上返回内容说明已经上传成功,但我们将url 在浏览器上访问时会返回404 是不允许直接访问的,因此我们需要用到下面的nginx代理来作web服务访问。
3.2. 搭建nginx提供http服务
fastdfs-nginx-module作用说明
FastDFS 通过Tracker 服务器,将文件放在 Storage 服务器存储,但是同组存储服务器之间需要进入文件复制,有同步延迟的问题。
如果Tracker 服务器将文件上传到了 192.168.80.30,上传成功后文件ID已经返回给客户端。此时 FastDFS 存储集群机制会将这个文件同步到同组存储192.168.80.31,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 192.168.80.31 上取文件,就会出现文件无法访问的错误。
而fastdfs-nginx-module 可以重定向文件连接到源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。
可以使用官方提供的nginx插件。要使用nginx插件需要重新编译。
1.
2.
3.
3.1.
3.2.
3.2.1. 更改fastdfs-nginx-module配置
上传fastdfs-nginx-module.tar.gz
1. 解压插件压缩包
2. 修改/opt/fastdfs-nginx-module/src/config文件,把其中的local去掉。(最新的没有local)
将mod_fastdfs.conf 拷贝到fdfs下进行配置
cd fastdfs-nginx-module/src cp mod_fastdfs.conf /etc/fdfs/ #将mod_fastdfs.conf 拷贝到fdfs下进行配置 vim /etc/fdfs/mod_fastdfs.conf base_path=/tmp #日志存放路径 tracker_server=192.168.80.32:22122 #配置成tracker server 地址和端口 storage_server_port=23000 url_have_group_name = true#url 中是否包组名 store_path0=/data/fastdfs/storage #文件存放路径,与storage 一致 group_name=group1 |
3.2.2. 编译安装Nginx
Ø 安装依赖包
yum -y install zlib zlib-devel openssl openssl--devel pcre pcre-devel |
Ø 安装nginx
上传解压nginx
cd nginx
对nginx重新config
./configure \ --prefix=/opt/nginx \ --pid-path=/opt/nginx/nginx.pid \ --lock-path=/opt/nginx.lock \ --error-log-path=/opt/nginx/log/error.log \ --http-log-path=/opt/nginx/log/access.log \ --with-http_gzip_static_module \ --http-client-body-temp-path=/opt/nginx/client \ --http-proxy-temp-path=/opt/nginx/proxy \ --http-fastcgi-temp-path=/opt/nginx/fastcgi \ --http-uwsgi-temp-path=/opt/nginx/uwsgi \ --http-scgi-temp-path=/opt/nginx/scgi \ --add-module=/opt/fastdfs-nginx-module/src |
再进行编译安装
./make.sh && ./make.sh install |
配置nginx,在nginx的配置文件中添加一个Server:
vim /opt/nginx/conf/nginx.conf
server { listen 8888; server_name 192.168.80.32; location /group1/M00/{ #root /home/FastDFS/fdfs_storage/data; ngx_fastdfs_module; } } |
上面的内容已经固定成了group1的M00,Storage 对应有多个group 的情况下,访问路径带 group 名,如/group1/M00/00/00/xxx,在这里改用:
location ~/group([0-9])/M00 {
ngx_fastdfs_module;
}
Ø 注意:
8888 端口值是要与/etc/fdfs/storage.conf 中的http.server_port=8888相对应,因为 http.server_port 默认为8888,如果想改成 80,则要对应修改过来。
如查下载时如发现老报 404, 将 nginx.conf 第一行 user nobody 修改为 user root 后重新启动。
防火墙中打开 Nginx 的8888 端口
vi /etc/sysconfig/iptables
添加:
-A INPUT -m state --state NEW -m tcp -p tcp--dport 8888 -j ACCEPT
重新启动防火墙:
shell> service iptables restart
3.2.3. 开机自启动设置
即在rc.local增加启动代码就可以了。
vi /etc/rc.local
增加一行 /opt/nginx/sbin/nginx
设置执行权限:
chmod 755 rc.local
3.2.4. 启动Nginx
shell> /opt/nginx/sbin/nginx
ngx_http_fastdfs_set pid=xxx
nginx重启命令为:
/opt/nginx/sbin/nginx -s reload
3.2.5. 访问测试
注意: 千万不要使用 kill -9 命令强杀FastDFS 进程,否则可能会导致 binlog 数据丢失。
以上一个简单的集群模式,其中上面的配置需要根据实际情况进行调整。
3.2.6. 注意事项
编译安装nginx需要pcre包,未安装会有如下提示:
./configure: error: the HTTP rewrite module requires the PCRE library.
You can either disable the modulebyusing--without-http_rewrite_module
option,or install the PCRE library into the system,or build the PCRE library
statically from the source with nginx byusing--with-pcre=<path> option.
需要安装pcre的devel包,pcre-devel。使用yum安装即可:(以下命令还带有ssl、zlib等依赖的安装)
yum -y install zlib zlib-devel openssl openssl--devel pcre pcre-devel |
以上是关于FastDFS高性能分布式文件系统的主要内容,如果未能解决你的问题,请参考以下文章