FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并看重高可用、高性能等指标,利用FastDFS很随意马虎搭建一套高性能的文件做事器集群供应文件上传、下载等做事。
从0,自己的一些疑问:FastDFS过期了吗?
相信这也是很多同学想要问的一些问题,我还没有理解这个技能的时候,也同样有这样的疑问。

首先,现在有很多文件存储都会选择像七牛云、阿里云OSS等云做事,为什么要自己搭一套文件做事器增加掩护本钱呢?
其次,这并不是口试的热点,乃至在入职之前自己都没有打仗过,乃至乃至,没有听说过,反倒是那些热门的技能,就算自己不主动去理解,当碰着的时候,大致也能知道是用来干嘛的。
那么我来说说我的理解,首先这个技能一定是还没有过期的,由于有些分外的文件,由于信息安全顾虑等缘故原由,不会选择公有云做事器,还有基于本钱考虑,还有很多的中型互联网公司仍旧是基于FastDFS来做自己的文件做事器的。其余,FastDFS作为一个分布式做事器,对轻量级、横向扩展、容灾备份、高可用、高性能、负载均衡都有着充分的考虑,依旧是一个文件做事器的不二之选。
那么为什么这样一项技能在如今却很少有人理解呢?
第一,我认为是需求所致,与其它业务比较,须要存储大量文件的业务相对之下还是比较少。如果文件存储量不大,按照传统的文件存储办法也不会有什么大的问题。
第二,现在有七牛云、阿里云OSS等公司供应工具存储,加之海内对付”上云“的追捧,就很少有人乐意自己搭做事器来做文件存储做事了。
当然对付一个技能人来说,各种各样的技能都得去学习,去适应,以是这篇文章希望可以帮助到感兴趣的同学,或是在事情中碰着高量级文件存储的同学,FastDFS是不错的选择。
传统文件存储办法这是传统文件存储的办法,做事器上乃至不须要装任何的运用,只须要有SFTP做事,我们就可以写对应的代码,完成文件的CRUD。
这样的好处便是很方便,只须要一台机器,几行代码就能搞定文件的存储,但是这种办法的瓶颈和毛病是很明显的。
首先,对付单体做事器来说,不考虑宕机的情形,单体文件做事器的带宽、磁盘容量是有上限的,那么当文件的体积占满了全体磁盘,我们只能选择扩展,但是这种单体做事器的办法,对付扩容就不太友好了,我们可以想想,难道我们要将原有的硬盘数据拷到一个更大的硬盘里,然后改换硬盘吗?
除了扩展以外,我们还须要面临一个问题,便是文件的查找,如果我们将所有文件都存放到一起,文件的数量如果到了一定的数量,就会面临磁盘IO速率瓶颈,不知道大家有没有碰着过下图中这种场景:
磁盘查询慢
如果我们须要在一个磁盘中找到某个文件,如果没有一个路径,或者路径下有很多文件,那么系统就会扫描磁盘,我们都知道,打算机体系构造中,关于速率,CPU>内存>硬盘,如果在生产环境下,真的须要存储大量的文件,假设存储的是用户的头像,那么用户每次打开APP,就须要等待个十几秒,自己的头像才会显示,那这个app估计没有人会利用吧。
有同学可能会说,那我们可以利用缓存啊,Redis的String类型是可以存储二进制数据的,而且Redis的String类型是一个Key对应一个值,查询效率会很高。的确这样在查询效率上可以达到,但是我们按照一张图片1M来打算,缓存又能存多少张图片呢?很显然这是一个十分昂贵的办法。
刚才我们考虑的都是做事器不宕机的状态,那么假设做事器宕机,那么我们就无法再供应数据存储做事;如果硬盘破坏,那么所有的数据都将丢失。
分布式文件系统上文中说了传统文件存储办法的一些毛病和弊端,这实在也是所有“单点“的弊端,无论是单点数据库、或者单点缓存、又或者是单点网关、单点注册中央,都在往分布式集群的方向发展。
总结一下,单点文件系统大致有这些弱点:
1. 磁盘容量存在瓶颈
2. IO速率存在瓶颈
3. 宕机、硬盘破坏数据丢失的风险
那么对付文件系统,我们如何利用分布式的办法来办理上述的毛病呢?
办理磁盘容量瓶颈上文中提到,当做事器文件系统存在磁盘容量瓶颈的缘故原由是磁盘无法很方便的进行扩容,我们常日须要从硬件的层面来考虑扩容硬盘,如:改换大容量硬盘。
这种办法显然是不现实的,由于改换硬盘意味着我们须要关做事器,生产环境做事器关停三十秒都是很严重的生产事件,以是我们只能利用做事器横向扩展的办法,如果不能改换硬盘,那么我们就加做事器。
多做事器
这样我们就可以利用多台做事器共同来构成我们的文件系统了,每个文件做事器都是一个独立的节点,来存储不同的文件,根据特定的逻辑(这里须要自己写),来决定文件须要存储到哪个文件做事器中。这样纵然做事器容量满了,我们也还可以连续横向扩展,理论上这样我们的文件系统是没有容量上限的。
办理IO速率瓶颈刚才我们办理了单点文件做事器容量瓶颈,但是如果某台或者某几台做事器上的文件数量过多(查询效率降落),或者有大量的用户访问某一台做事器,还是会造成IO速率瓶颈。那么要如何办理这个问题。
我们可以想一想类似的案例——MySQL数据库。
众所周知,MySQL的数据也是存在硬盘中的,而我们在写SQL语句的时候,为了担保查询效率,常日会避免全表扫描,而是通过索引让其找到我们对应的那条数据。
以是我们也可以通过这种办法,避免通盘扫描或者大范围扫描,而我们都知道,操作系统对付文件是有一个天然的索引的,便是我们的多级目录。FastDFS也正是利用了这个来增加我们文件IO的效率的,这个暂且不提,下文中会展示。
办理宕机、硬盘破坏数据丢失的风险能否办理这个问题才是分布式文件系统和单机文件系统最根本的差异,由于无论是单机磁盘容量瓶颈还是IO速率瓶颈,我们都可以通过增加硬件配置来办理,只不过不太方便且本钱太高罢了。而单机模式是绝对无法办理宕机造成的文件做事失落效,或者硬盘破坏造成的数据丢失的,由于数据只存在一份。
那么我们思考一下分布式文件系统是如何来办理这些问题的。
首先我们须要办理宕机的问题,如上图,我们有多个文件做事器节点,但是如果我们自己写逻辑来决定某个文件该当存哪个做事器上,假设那个做事器此时宕机了,文件依旧是无法存入的,当然我们可以连续写逻辑来决定如果宕机了之后该当怎么办,但是FastDFS中已经替我们实现了,Tracker节点可以帮助我们选择文件该当上传到哪个做事器上,并且还可以在某个节点宕机的时候选择其从节点(备份节点)进行文件上传,防止由于宕机造成的无法操作文件。
那么根据上面这幅图,第二个问题也就很好理解了,假设某台做事器硬盘破坏了,那么数据依旧会存在备份,纵然备份做事器也破坏了,数据也只会丢失一部分,而不会全部丢失。
FastDFS上面说了这么多的关于分布式文件系统可以办理的一些实际问题,那么就直接切入本日的主题——FastDFS。
整体架构FastDFS文件系统由两大部分组成,客户端和做事端。
客户端常日指我们写的程序(当然FastDFS也供应了客户端测试程序),例如我们利用Java去连接FastDFS、操作文件,那么我们的Java程序便是一个客户端,FastDFS供应专有API访问,目前供应了C、Java和PHP等编程措辞的API,用来访问FastDFS文件系统。
做事端由两个部分组成,分别是跟踪器(Tracker)和存储节点(Storage)。
跟踪器(Tracker):紧张做调度事情,类似微做事注册中央,在内存中记录集群存储节点的storage的状态信息,是客户端和做事端存储节点storage的枢纽,由于干系信息全部在内存中,每个Storage在启动后会连接Tracker,奉告自己所属的group等信息,并周期性发送心跳,TrackerServer的性能非常高,假设我们有上百个Storage节点,我们只须要3台旁边的Tracker就足够了。
存储节点(Storage)用于存储文件,包括文件和文件属性(metaData)都保存到做事器磁盘上,完成文件管理的所有功能:文件存储、文件同步和文件访问等。Storage以group为组织单位,一个group内可以包含多台Storage机器,数据互为备份,总存储空间以group内容量最小的storage为准(木桶),以是建议一个group内的机器存储空间大小该当只管即便相同,以免造成空间的摧残浪费蹂躏。Storage在第一次启动时,会在每一个存储目录里创建二级目录,共计256 256个目录,我们上传的文件会以Hash的办法被路由到个中某个子目录下。
FastDFS整体架构
事情流程上传FastDFSUpload
下载FastDFSDownload
客户端发送下载要求,Tracker根据文件信息,返回Storage地址和端口(客户端也可以通过自己存储的文件位置直接访问Storage)。
客户端访问Storage,Storage根据file_id(组名、虚拟磁盘、二级目录、文件名)查找到文件,返回文件数据。
当客户端发起上传要求时,会先访问Tracker,由于Storage定期向Tracker发送状态信息,以是Tracker中存有所有Storage Group的信息。
Tracker根据本地的Storage Group信息,为客户端上传的文件分配Storage Group,并返回给客户端。
客户端拿到Storage Group地址和端口后,上传文件到指定的Storage Group中。
Storage返回文件的路径信息和文件名。
Client将文件信息存储到本地。
单机安装安装前准备
安装
安装FastDFS须要两个源码包,分别是libfastcommon-1.0.43.tar.gz和fastdfs-6.06.tar.gz。
这里附上作者的github地址:fastdfs,libfastcommon,大家可以到这里下载对应的包。
下载完成后,将其上传到我们的linux做事器中
分别运行tar -zxvf fastdfs-6.06.tar.gz和tar -zxvf libfastcommon-1.0.43.tar.gz对其进行解压,解压后进入libfastcommon-1.0.43目录中运行sh make.sh,运行完毕后运行sh make.sh install,然后进入fastdfs-6.06目录中实行相同的操作,即可完成安装。
安装成功后进入/usr/bin目录下,如果存在很多fdfs开头的命令,则证明安装成功。
而/etfc/fdfs目录中存放了所有的FastDFS的配置文件:
然后进入/etc/fdfs,这里存放了所有fastDFS的配置文件
末了一步,我们须要进入FastDFS安装包解压后的conf目录下,找到http.conf和mime.types将其复制到/etc/fdfs目录下。
这样我们就完成了FastDFS的安装。
配置文件详解安装完成后须要先把配置文件配置好才能够正常启动,这里会贴上tracker.conf、storage.conf、client.conf的所有配置项,就当作一个配置模板吧,配置的时候可以直接copy。
首先是tracker.conf:
storage.conf:
须要配置tracker.conf和storage.conf
启动
我们须要进行一些最小配置,来支持FastDFS的启动。
首先是tracker.conf
然后是storage.conf
配置好并且检讨配置文件中的目录都存在之后,将配置文件拷贝到/etc/fdfs目录下,然后启动tracker和storage即可。
FastDFS的文件存储办法
启动FastDFS后,可以去到我们刚才在storage.conf中配置的storage_path目录下,可以看到FastDFS在这个目录下创建了一个data目录,在data目录中创建了256256个文件夹,用于分散存储数据,这样可以提高查找文件的效率。这个便是上文中所说的,FastDFS办理IO效率的一种手段,将文件分布到每个目录下,类似于Java中的HashMap,通过文件的HashCode,迅速判断文件的位置从而找到文件。
至此我们的FastDFS已经成功启动。
检讨Linux上是否安装了GCC、libevent、libevent-devel
如果没有安装,则需进行安装
yuminstallgcclibeventlibevent-devel-y
功能测试
上文中我们已经将FastDFS成功启动,并且可以看到启动后数据目录的变革。现在我们就可以利用客户端来测试一下FastDFS的功能了。
首先我们须要配置一下客户端,在/etc/fdfs目录下找到client.conf配置文件,进行如下的最小配置:
配置完毕后,须要在任意目录下,创建一个用于测试的文件。
创建好文件并写入内容后,就可以对已支配的fdfs进行各种办法的测试了。
首先是文件上传,FastDFS自带的客户端通过fdfs_test 配置文件 upload 须要上传的文件路径进行文件的上传,示例如下:
当实行完这条命令之后,我们可以看到文件上传到的storage server的一些信息,例如group_name,ip,端口等,还可以看到我们的文件上传到那个group,存在这个group的哪个路径下。
本次我们上传的文件通过返复书息,可以看到上传到group1下(由于我们只有一个storage并且只设置了一个group),上传到的路径为M00/ED/49/wKiJA19kwRqAI_g6AAAAEbcXlKw7921454,那么就可以到这个目录下查看一下这个文件是否已经上传成功了。
文件上传成功,但是这个目录下面不止存在我们刚才上传的文件,还存在其它的一些文件,这里做一下解释:
filename:为文件本体。
filename-m:为文件元数据,例如文件的类型、大小、如果是图片还有长度宽度等。
filename_big:为备份文件,如果存在主备做事器,那么该文件会存放到备份做事器上。
filename_big-m:文件元数据的备份,如果存在主备做事器,那么该文件会存放到备份做事器上。
文件下载,利用自带的FastDFS测试客户端,文件下载的办法与上传类似,利用fdfs_test 配置文件路径 download 组名 远程文件名称,即可下载该文件。
示例如下:
文件下载成功。
文件删除测试,利用fdfs_test 配置文件路径 delete 组名 远程文件名称示例如下:
创造仅存在文件备份,而文件本体已删除成功。
FastDFS的HTTP访问我们只利用了FastDFS自带的客户端测试工具来测试文件的上传、下载和删除,但是在实际状况下我们并不是这么操作文件的,而是通过程序发送要求来操作文件,那么就涉及到要通过HTTP访问文件,这里纯挚依赖FastDFS就无法做到了,我们须要Nginx的合营。
Nginx的安装这里就不再赘述了,这里就默认大家都安装好了Nginx。这里直接进行nginx的配置。
配置之前我们首先须要一个nginx的扩展模块包——fastdfs-nginx-module,这里同样供应一个下载地址:fastdfs-nginx-module。
下载完成之后,将其上传到做事器并解压:
然后将mod_fastdfs.conf文件复制到/etc/fdfs目录下,并且修正它,修正项如下:
配置完成后我们须要将这个扩展模块新增到原来的nginx中:
修正nginx.conf文件,新增一个server:
然后重启nginx:
如果你的nginx和fastdfs都是启动状态,那么此时已经可以访问成功了。
访问成功
fastdfs-nginx-module的实行事理完成了文件访问之后,我们复盘一下刚才我们做了什么,首先我们安装了nginx,然后将nginx的fastdfs扩展模块添加到nginx中,之后进行了一下扩展模块和nginx的配置,但在配置nginx的代理的时候,我们并没有像以前一样直接将代理地址写入配置中,而是将原来写代理地址的位置直接写了fastdfs扩展模块,那么这个模块究竟是如何运行起来的呢?
按照传统的nginx反向代理的配置办法,我们该当在拦截到要求之后,直接通过配置地址的办法,代理到目标做事器上,但是这里直接指向fastdfs模块,很显然,这个模块帮我们干了这件事。
还记得我们在扩展模块的配置文件中,配置了Tracker Server的地址吗?
当我们要求任意一个Group时,都会被nginx拦截下来然后发送给扩展模块,然后扩展模块通过我们配置的这个Tracker Server的地址,将要求转发给Tracker,Tracker会根据自己本地的group映射表,返回一个ip:port,例如我们刚才访问的是group1,那么扩展模块会将group1发送给Tracker, Tracker返回192.168.137.3:23000给nginx,然后扩展模块再通过这个地址,去访问storage,获取文件流,返回给浏览器。
扩展模块实行流程
FastDFS分布式集群搭建单点FastDFS跑通之后,有同学可能就会有迷惑,那这和我们之前的文件系统也没有很大差别啊,前面说的横向扩展、容灾备份我们也完备都没有看到啊。
不急不急,这就来了。
刚才我们在一台机器上支配了FastDFS,并且测试了上传下载删除等功能,末了整合nginx完成了利用浏览器对文件的访问,并且理解了一下扩展模块的运行事理。这些是为了让大家更好的理解FastDFS,但是本篇文章紧张先容分布式文件系统,分布式文件系统最大的特点也就在于容灾备份、可扩展、高可用。那么接下来便是重头戏,来讲讲FastDFS分布式集群的搭建。
架构图我们须要准备7台Linux虚拟机,来完本钱次集群的搭建,包括1台Nginx,2台Tracker Server,4台Storage分为2个group,每个group中一主一备。
我这里准备的linux做事器信息如下:
个中Group1中的两台Storage相互备份,Group2中的两台Storage相互备份。
搭建
对这六台做事器,按照上文中的安装过程,依次安装Nginx和FastDFS。(步骤如上)
建议在安装之前实行yum命令先一次性将依赖包安装完成:
yum -y install gcc perl openssl openssl-devel pcre pcre-devel zlib zlib-devel libevent libevent-devel wget net-tools
配置集群
集群的配置和上面单体的配置有些许不同,由于我们是将Tracker和Storage拆开,以是在装Tracker的做事器上并不须要进行Storage的配置,同理在装Storage的机器上也不须要进行Tracker的配置。
Tracker(101和102做事器)须要配置的点:
Storage(103 104 105 106做事器)须要配置的点:
storage配置
集群启动
利用fdfs_trackered 配置文件路径来启动trakcer:
Tracker启动
利用fdfs_stroaged 配置文件路径来启动storage:
我们可以在任意一台storage做事器中,利用fdfs_monitor /etc/fdfs/storage.conf命令来查看全体集群的状态:
可以看到集群已经搭建成功了,并且我们可以看到每个storage的状态信息,例如每个节点的所属组、IP、存储空间大小、HTTP端口、是否启动、连接的tracker server等等。
集群测试在六台机器中随意找一台配置client.conf文件,配置项如下:
然后创建一个用于测试上传功能的文件,创建完毕后,利用fdfs_upload_file进行上传,由于我们设置的上传模式是轮询,以是记住要多上传几遍,才能看出效果。
集群上传文件
上传效果,可以看到group1的两台机器互为备份,而group2的两台机器互为备份。
负载均衡策略
刚才我们设置的上传策略是轮询,以是我们可以看到,每次在上传的时候,都会切换到与上一次不同的group中。FastDFS可以设置三种不同的负载均衡策略,分别是:轮询、指定一个group上传、选择一个剩余空间最多的group进行上传。
由于篇幅有限,这里就不一一测试了,感兴趣的同学可以在线下进行测试。
访问集群中的文件做一个大略的回顾,上文中在配置单体的FastDFS时,我们是如何通过HTTP访问文件的?
我们利用了nginx,安装了fastdfs的扩展模块,然后在nginx中做了一个反向代理指向扩展模块,扩展模块去要求我们的tracker server获取到group对应的storage做事器的ip端口号等信息,然后扩展模块拿到这个信息之后,就去storage server中获取文件流,返回给浏览器。
以是FastDFS集群也一样,我们也须要通过nginx来访问文件,但是这里的配置略微有些不同。
我们得分这么几种情形来配置nginx:Tracker、Storage、入口做事器。
Tracker Server的nginx配置:
启动nginx,如果nginx的work process没有正常启动,须要将mod_fastdfs.conf、fastdfs解压包目录中的mime.types和http.conf复制到/etc/fdfs目录下。
Storage Server的nginx配置:
首先须要配置mod_fastdfs.conf
nginx配置:
然后启动Storage的nginx。
测试一下访问:
测试访问
集群访问流程实际我们刚才不论是访问哪台做事器,都是可以正常访问到这个文件的。
我们可以来推一下刚才的访问流程,我们刚才在tracker中配置了stroage的负载均衡,而在stroage的反向代理中配置了fastdfs的扩展模块。
假设我们访问的是tracker,那么tracker做事器我们配置了负载均衡,负载均衡会自动路由到任意一台storage上,storage上配置了扩展模块,会带上我们访问的group去要求tracker,tracker返回这个group的storage的ip和端口号。
那么假设我们访问的是storage,那么storage里的扩展模块就直接携带我们的url中的group去访问tracker,一样也能找到storage的ip和端口。
以是只要group是精确的,无论访问哪台机器,都可以访问到文件。
配置统一入口还记得我们搭集群之前说过,我们须要7台机器吗,但是现在我们只用了6台,第7台机器便是用在这里。
由于刚才我们只是把集群搭起来了,但是这样我们须要记住6个ip地址,再来回顾一下最初的架构图:
我们须要供应一个nginx,负载均衡到两个tracker中,然后我们之后的程序就只须要访问这个入口,就可以正常利用全体集群的做事了。
nginx配置如下:
测试:
通过入口访问成功
集群搭建完毕。
结语分布式文件系统对付传统文件系统的一些上风,详细在于容灾备份、横向扩展,和解决传统文件系统文中先容的详细的技能——FastDFS整合nginx,作为分布式文件系统的办理方案之一,可以很好的办理一些生产环境下的巨量文件存储问题。
其余FastDFS也可以很方便的通过Java程序来对文件进行诸如上传下载之类的操作,但由于篇幅缘故原由,本文中没有先容到,当然如果大家感兴趣的话我会不才一篇博客中来详细说说在真实项目是如何利用FastDFS的。