一、什么是fastDFS 1.介绍 FastDFS是一个开源的高性能分布式文件系统。它的主要功能包括:文件存储,文件同步和文件访问(文件上传和文件下载),它可以解决高容量和负载平衡问题。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。 FastDFS应该满足基于服务的网站的要求在照片共享网站和视频共享网站等文件上。 FastDFS具有两个角色:跟踪器和存储。跟踪器负责计划和负载平衡以访问文件。存储器存储文件及其功能是文件管理,包括:文件存储,文件同步,提供文件访问界面。跟踪器还管理元数据,这些元数据是表示为文件的键值对的属性。例如:width = 1024,键是“ width”,值是“ 1024”。 跟踪器和存储包含一台或多台服务器。跟踪器或存储群集中的服务器可以随时添加到群集中或从群集中删除,而不会影响联机服务。跟踪器群集中的服务器是对等的。 存储服务器按文件卷/组进行组织以获得高容量。该存储系统包含一个或多个卷,这些卷的文件相互独立。整个存储系统的容量等于所有卷容量的总和。文件卷包含一个或多个存储服务器,这些服务器之间的文件相同。文件卷中的服务器相互备份,并且所有这些服务器都在负载平衡中。将存储服务器添加到卷中时,该卷中已经存在的文件会自动复制到该新服务器,复制完成后,系统会将该服务器联机切换为提供存储服务。 当整个存储容量不足时,您可以添加一个或多个卷以扩展存储容量。为此,您需要添加一个或多个存储服务器。 2.技术应用场景 文件为载体的在线服务,如相册网站、视频网站等等。
二、fastDFS工作原理 1.fastDFS架构
FastDFS系统有三个角色:Tracker 服务器、Storage 服务器、Client客户端。 Tracker服务器(跟踪器):主要做调度工作,在访问上起负载均衡的作用。负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。注意:Tracker只负责调度,维护各个Storage分组和分组中服务器信息,不存储Storage中的文件路径。 Storage服务器(存储器):主要提供容量和备份服务。以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。存储空间大小为各group容量累加之和。 Client(客户端cu):上传下载数据的服务器(第三方服务器,javaAPI运用程序),需要存储每一个上传文件的存储路径和文件名。
2.Tracker集群 Tracker可以有一台或多台,Tracker 集群中每一台服务器是相互平等关系,每一台Tracker服务器都负责管理Storage服务器,故不存在单点故障,客户端访问tracker服务器时可以采用轮询方式。
3.Storage集群 storage集群由一个或多个组构成,集群存储总容量为集群中所有组的存储容量之和。一个组由一台或多台存储服务器组成,组内的Storage server之间是平等关系,不同组的Storage server之间不会相互通信,同组内的Storage server之间会相互连接进行文件同步,从而保证同组内每个storage上的文件完全一致的。一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务能力(纵向扩容)。当系统容量不足时,可以增加组来扩充存储容量(横向扩容)。Storage集群的服务器会定向向Tracker服务器报告自己的状态,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。 4.FastDFS的文件同步 写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server。每个storage写文件后,同时会写一份binlog,binlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读storage的时候会以同步进度作为参考。 5.文件上传流程
FastDFS向使用者提供基本文件访问接口,包括(upload上传、download下载、delete删除),以客户端(api)方式给用户使用。集群中各Tracker是对等的,客户端上传时可以选择任意一个Tracker,当Tracker收到客户端上传文件的请求时,会为该文件分配一个可以存储文件的group,当选定了group后就要决定给客户端分配group中的哪一个storage server。当分配好storage server后,客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录。然后为文件分配一个fileid,最后根据以上的信息生成文件名存储文件。
6.文件下载流程 跟upload file一样,在downloadfile时客户端可以选择任意tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。 三、服务器搭建 1.安装包准备 Libfastcommon:是FastDFS 和 FastDHT 中提取出来的公共 C 函数库,基础环境,版本libfastcommonV1.0.7.tar.gz FastDFS-FastDFS:tracker和starage安装包,版本FastDFS_v5.05.tar.gz fastdfs-nginx-module:nginx插件,安装在Storage可以重定向连接到源服务器取文件,避免客户端由于复制延迟的问题,出现错误,版本fastdfs-nginx-module_v1.16.tar.gz Nginx:反向代理服务器,版本nginx-1.8.1.tar.gz
2.安装环境介绍 Tracker服务器:192.168.158.11-12;Storage服务器:192.168.158.13-16.其中13与14为group1,15与16为group2. 3.安装libfastcommon类库(全部服务器) 上传libfastcommonV1.0.7.tar.gz到/usr/local
cd /usr/local tar -zxvf libfastcommonV1.0.7.tar.gz cd libfastcommon-1.0.7 ./make.sh ./make.sh install安装完的路径在/usr/lib64,但是fastDFS访问的lib路径在 /usr/local/lib 中 所以此时需要建立软连接
ln -s /usr/lib64/libfastcommon.so /usr/local/lib/libfastcommon.so ln -s /usr/lib64/libfastcommon.so /usr/lib/libfastcommon.so4.安装FastDFS(全部) 上传FastDFS_v5.05.tar.gz到/usr/local
cd /usr/local tar -zxvf FastDFS_v5.05.tar.gz cd FastDFS ./make.sh ./make.sh install安装好后,程序是在/usr/bin目录下: 配置文件在/etc/fdfs目录下 5.配置tracker(11.12) 5.1创建存储数据和日志根目录,并复制tracker.conf文件f
mkdir /home/fastdfs cd /etc/fdfs cp tracker.conf.sample tracker.conf5.1修改tracker.conf文件(tracker.conf各项配置见tracker.conf详解)
vi tracker.conf base_path=/home/fastdfs5.3启动
/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart5.4设置开机启动
echo '/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart' >> /etc/rc.d/rc.local5.5确认是否启动
ps -ef|grep fdfs6.配置Storage(13-16) 将存储节点分为两个组,其中group1 (13、14)、group2 (15、16) 6.1创建存储数据和日志根目录,并复制tracker.conf文件f
mkdir /home/fastdfs cd /etc/fdfs cp storage.conf.sample storage.conf6.storage.conf文件(storage.conf各项配置见storage.conf详解)
vi storage.conf group_name=group1 #组名(第一组13、14为group1,第二组15、16为group2) base_path=/home/fastdfs store_path0=/home/fastdfs #第一个存储目录,第二个存储目录起名为:store_path1=xxx,依次类推... store_path_count=1 # 存储路径个数,需要和store_path个数匹配 tracker_server=192.168.158.11:22122# tracker服务器IP和端口 tracker_server=192.168.158.12:22122 # tracker服务器IP和端口6.3启动
/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart6.4设置开机启动
echo '/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart' >> /etc/rc.d/rc.local6.5确认是否启动
netstat -tupln | grep storaged7.Storage上安装nginx 7.1安装fastdfs-nginx-module,主要这个模块只需要在Storage上安装 上传fastdfs-nginx-module_v1.16.tar.gz到/usr/local 解压
cd /usr/local tar -zxvf fastdfs-nginx-module_v1.16.tar.gz7.2编辑fastdfs-nginx-module文件(修改CORE_INCS和CORE_LIBS路径)
cd fastdfs-nginx-module/src/ vi config CORE_INCS="$CORE_INCS /usr/local/include/fastdfs /usr/local/include/fastcommon/" CORE_LIBS="$CORE_LIBS -L/usr/local/lib -lfastcommon -lfdfsclient"把local都去掉 然后安装nginx
yum install -y pcre* zlib zlib-devel openssl openssl-devel ./configure --with-http_ssl_module --add-module=/usr/local/fastdfs-nginx-module/src make && make install7.3配置fastdfs-nginx-module 进入fastdfs-nginx-module的src目录,将md_fastdfs.conf配置文件拷贝到/etc/fdfs/目录中
cd /usr/local/fastdfs-nginx-module/src cp mod_fastdfs.conf /etc/fdfs/ vi /etc/fdfs/mod_fastdfs.conf一般只需改动以下几个参数即可:
base_path=/home/fastdfs #保存日志目录 tracker_server=192.168.158.11:22122 tracker_server=192.168.158.11:22122 storage_server_port=23000 #storage服务器的端口号 group_name=group1 #当前服务器的group名 url_have_group_name = true #文件url中是否有group名 store_path_count=1 #存储路径个数,需要和store_path个数匹配 store_path0=/home/fastdfs #存储路径 group_count = 2 #设置组的个数 [group1] #设置了group_count = 2,接下来就需要在文件尾部追加这2个group setting group_name=group1 storage_server_port=23000 store_path_count=1 store_path0=/home/fastdfs [group2] group_name=group2 storage_server_port=23000 store_path_count=1 store_path0=/home/fastdfs7.4复制文件
cp /usr/local/nginx/conf/http.conf /etc/fdfs cp /usr/local/nginx/conf/mime.types /etc/fdfs7.5建立M00至存储目录的符号连接
ln -s /home/fastdfs/data /home/fastdfs/data/M00 ll /home/fastdfs/data/M007.6配置nginx Vi /usr/local/nginx/conf/nginx.conf 将listen端口改为8888,启动用户使用root user root listen 8888; 在server段中添加:
location ~/group[1-2]/M00 { root /home/fastdfs/data; ngx_fastdfs_module; }7.7将nginx设置为开机启动:
echo '/usr/local/nginx/sbin/nginx' >> /etc/rc.d/rc.local8.Tracker上安装nginx 8.1安装nginx
yum install -y pcre* zlib zlib-devel openssl openssl-devel ./configure --with-http_ssl_module make && make install8.2配置nginx
vi /usr/local/nginx/conf/nginx.conf worker_processes 4; #根据CPU核心数而定 events { worker_connections 65535; #最大链接数 use epoll; #新版本的Linux可使用epoll加快处理性能 } http { #设置group1的服务器 upstream fdfs_group1 { server 192.168.158.13:8888 weight=1 max_fails=2 fail_timeout=30s; server 192.168.158.14:8888 weight=1 max_fails=2 fail_timeout=30s; } #设置group2的服务器 upstream fdfs_group2 { server 192.168.158.15:8888 weight=1 max_fails=2 fail_timeout=30s; server 192.168.158.16:8888 weight=1 max_fails=2 fail_timeout=30s; } server { #设置服务器端口 listen 8080; #设置group1的负载均衡参数 location /group1/M00 { proxy_pass http://fdfs_group1; } #设置group2的负载均衡参数 location /group2/M00 { proxy_pass http://fdfs_group2; } } } }8.3将nginx设置为开机启动:
echo '/usr/local/nginx/sbin/nginx' >> /etc/rc.d/rc.local四、配置文件详解 1.tracker.conf文件详解 disabled:配置文件是否生效 bind_addr:绑定固定IP地址,服务器多个IP时希望指定IP提供服务时指定,不指定为服务器所有IP port:tracker服务端口 connect_timeout:套接字连接超时秒数,默认30秒 network_timeout:网络连接超时秒数,发送或接收数据时,超时后还不能发送或接收数据,则本次网络通信失败 base_path:存储数据和日志文件的基础目录地址(根目录必须存在,子目录会自动创建),tracker server目录及文件结构: ${base_path} |__data | |__storage_groups.dat:存储分组信息 | |__storage_servers.dat:存储服务器列表 | |__storage_sync_timestamp.dat:storage同步时间 | |__storage_changelog.dat:storage变更日志 | |__fdfs_trackerd.pid:tracker服务ID |__logs |__trackerd.log:tracker server日志文件 max_connections:系统提供服务时的最大连接数 accept_threads:线程总数 work_threads:工作线程数,通常为CPU数,应该不大于max_connections store_lookup:选择哪个group存储上传的文件,0:轮询,1:指定组,2:负载均衡(最大剩余空间的group) store_group:存储上传文件的group名称,store_lookup为1时,必须指定一个group名称 store_server:选择哪个storage进行上传操作,0:轮询(默认),1:根据IP地址选择一个最小的,2:storage服务设置的upload_priority优先级来选择 store_path:选择storage中的哪个目录进行上传,0:轮询,2:剩余空间最大的目录 download_server:选择哪个storage作为下载文件服务,0:轮询,1:与上传文件服务一致 reserved_storage_space:storage服务器为系统和其他应用保留的存储空间,支持百分比设置 log_level:日志级别 run_by_group:服务器运行FastDFS的用户组,不填为当前用户组 run_by_user:服务器运行FastDFS的用户,不填为当前用户 allow_hosts:可以连接此tracker服务的IP范围 sync_log_buff_interval:同步或刷新日志信息导磁盘的时间间隔单位为秒 check_active_interval:检测storage服务存活的时间间隔单位为秒,此参数应该大于storage服务配置的心跳时间 隔。 thread_stack_size:线程栈的大小 storage_ip_changed_auto_adjust:当storage服务的IP地址变更时是否自动调整 storage_sync_file_max_delay:storage服务之间同步文件的最大延迟秒数,本参数不影响文件同步过程,仅在下 文件时,判断文件是否已经被同步完成的一个阀值 storage_sync_file_max_time:存储服务器同步一个文件的最大秒数,本参数不影响文件同步过程,仅在下载文件 ,判断文件是否已经被同步完成的一个阀值 use_trunk_file:是否使用小文件合并存储特性 slot_min_size:trunk文件分配的最小字节数 slot_max_size:trunk文件分配的最大字节数,只有文件大小不大于这个参数值,才会合并存储。如果大于,将不 用合并存储方式 trunk_file_size:合并存储的trunk文件的大小 trunk_create_file_advance:是否提前创建trunk文件。此值为真,trunk_create_file_XXX的参数才有效 trunk_create_file_time_base:提前创建trunck文件的起始时间点 trunk_create_file_interval:创建trunck文件的时间间隔,单位为秒 trunk_create_file_space_threshold:提前创建trunk文件需要达到的空闲trunk大小 trunk_init_check_occupying:trunk初始化时,是否检查可用空间是否被占用 trunk_init_reload_from_binlog:是否从trunk二进制日志中国年加载trunk可用空间信息 trunk_compress_binlog_min_interval:trunk二进制日志压缩的最小时间间隔 use_storage_id:是否使用storage ID作为storage服务标识 storage_ids_filename:storage ID文件地址,use_storage_id为真,才需设置次参数。 id_type_in_filename:storage ID文件中服务ID类型,支持IP和storage服务ID store_slave_file_use_link:存储从文件是否采用符号链接方式 rotate_error_log:是否定期轮转错误日志 error_log_rotate_time:错误日志轮转时间点 rotate_error_log_size:错误日志按大小轮转 log_file_keep_days:日志文件保留天数。0:不删除老日志文件 use_connection_pool:使用连接池 connection_pool_max_idle_time:连接池连接最大时长 http.server_port:tracker服务的HTTP端口 http.check_alive_interval:检查storage HTTP服务存活时间间隔,单位为秒 http.check_alive_type:检查storage HTTP服务存活的服务协议类型 http.check_alive_uri:检查storage HTTP服务存活地址URI/URL
2.storage.conf文件详解 disabled:配置文件是否生效 group_name:storage服务所属group名称 bind_addr:绑定指定IP地址提供服务 client_bind:storage作为客户端连接其他服务时,是否绑定地址 port:storage服务端口 connect_timeout:套接字连接超时秒数,默认30秒 network_timeout:网络连接超时秒数,发送或接收数据时,超时后还不能发送或接收数据,则本次网络通信失败 heart_beat_interval:主动向tracker发送心跳间隔时间,单位为秒 stat_report_interval:向tracker服务报告磁盘剩余空间时间间隔,单位为秒 base_path:存储数据和日志文件的基础目录地址(根目录必须存在,子目录会自动创 max_connections:系统提供服务时的最大连接数 buff_size:接收或发送数据的队列结点缓存大小,工作队列消耗内存大小=send * max_connections accept_threads:线程总数 work_threads:工作线程数,通常为CPU数,应该不大于max_connections disk_rw_separated:磁盘读写是否分离 disk_reader_threads:读写分离时,系统中的写线程数=disk_reader_threads * store_path_count,读写混合时线程数=(disk_reader_threads + disk_writer_threads) * store_path_count disk_writer_threads:读写分离时,系统中的写线程数=disk_writer_threads * store_path_count sync_wait_msec:同步文件时,尝试从二进制日志文件中不断读取的休眠毫秒数 sync_interval:同步完一个文件后继续同步的时间间隔,单位毫秒 sync_start_time:同步开始时间点 sync_end_time:同步结束时间点 write_mark_file_freq:同步完N个文件后,同步storage的mark文件到磁盘 store_path_count:storage服务存放文件的基路径数 store_path#:逐一配置store_path路径,索引号从0开始,store_path0不配置的话,与base_path路径保持一致 subdir_count_per_path:FastDFS存储文件的目录个数,会自动创建N * N个子目录 tracker_server:tracker服务列表,每个一行。格式为主机和端口号,主机可以是主机名称或IP地址 log_level:日志级别 run_by_group:服务器运行FastDFS的用户组,不填为当前用户组 run_by_user:服务器运行FastDFS的用户,不填为当前用户 allow_hosts:允许连接storage服务的IP地址列表 file_distribute_path_mode:文件在data目录下分布存储策略,0:轮询,1:随机根据文件名对应的hashcode存储 file_distribute_rotate_count:file_distribute_path_mode为0时有效,当一个目录下的文件存放的文件数达到 参数值时,后续上传的文件存储到下一个目录 fsync_after_written_bytes:写入大文件时,每N字节强行将内容同步到硬盘 sync_log_buff_interval:同步或刷新日志信息导磁盘的时间间隔单位为秒 sync_binlog_buff_interval:同步二进制日志到硬盘的时间间隔单位为秒 sync_stat_file_interval:storage的stat信息同步到硬盘的时间间隔单位为秒 thread_stack_size:线程栈的大小 upload_priority:上传文件的优先级,值越小,优先级越高。tracker配置文件中的store_server值为2时生效 if_alias_prefix:网络适配器的别名前缀,不填写会自动设置系统类型 check_file_duplicate:是否上传的文件已经存在,配合FastDHT使用 file_signature_method:重复文件内容的签名方式,支持hash和md5 key_namespace:在FastDHT中保存文件索引的命名空间 keep_alive:与FastDHT连接的方式。长连接和断连接 use_access_log:是否将文件操作记录到操作日志 rotate_access_log:是否定期轮询操作日志 access_log_rotate_time:操作日志定期轮询时间点 rotate_error_log:是否定期轮询错误日志 error_log_rotate_time:错误日志定期轮询时间点 rotate_access_log_size:按文件大小轮询操作日志 rotate_error_log_size:按文件大小轮询错误日志 log_file_keep_days:日志文件保存天数 file_sync_skip_invalid_record:文件同步时,是否忽略无效的记录 use_connection_pool:是否使用连接池 connection_pool_max_idle_time:连接池连接最大时长 http.domain_name:storage服务web服务域名,可以通过tracker服务重定向URL来访问,如果域名为空使用IP地址 http.server_port:storage提供web服务的端口号 3.
五、测试与监控
1.运行测试: FastDFS安装成功可通过/usr/bin/fdfs_test测试上传、下载等操作。 cp client.conf.sample client.conf 修改/etc/fdfs/client.conf base_path=/home/fastdfs tracker_server=192.168.158.11:22122
使用格式: /usr/bin/fdfs_test 客户端配置文件地址 upload 上传文件 比如将/home下的文件上传到FastDFS中: /usr/bin/fdfs_test /etc/fdfs/client.conf upload /home/aaa.html 上传后将返回文件路径 2.运行监控 /usr/bin/fdfs_monitor <client_conf_filename> 3.fastdfs七种状态 FDFS_STORAGE_STATUS:INIT :初始化,尚未得到同步已有数据的源服务器 FDFS_STORAGE_STATUS:WAIT_SYNC :等待同步,已得到同步已有数据的源服务器 FDFS_STORAGE_STATUS:SYNCING :同步中 FDFS_STORAGE_STATUS:DELETED :已删除,该服务器从本组中摘除 FDFS_STORAGE_STATUS:OFFLINE :离线 FDFS_STORAGE_STATUS:ONLINE :在线,尚不能提供服务 FDFS_STORAGE_STATUS:ACTIVE :在线,可以提供服务 六、下载文件重命名 FastDFS上传的文件是重命名的,如果重命名需要配置Storage服务器nginx.conf ,并且访问时带上文件名 http://192.168.158.11:888/group1/M00/00/00/0g6GT1H40kkAZJeWAACCCJr7psA954_big.txt?filename=测试文件.txt
修改后的nginx.conf
location ~/group[1-2]/M00 { root /home/fastdfs/data; if ($arg_attname ~ "^(.+)") { add_header Content-Disposition "attachment;filename=$arg_attname"; } ngx_fastdfs_module; }文件过长保存问题 修改fastdfs_nginx模块. src下 common.c 第615行到622行
if (uri_len + 1 >= (int)sizeof(uri)) { logError("file: "__FILE__", line: %d, " \ "uri length: %d is too long, >= %d", __LINE__, \ uri_len, (int)sizeof(uri)); OUTPUT_HEADERS(pContext, (&response), HTTP_BADREQUEST) return HTTP_BADREQUEST; }注释后,重新安装nginx