美文网首页极乐科技Java项目SSM+shiro等
【Java实战项目】Migo商城2.0 图片服务器的搭建与使用

【Java实战项目】Migo商城2.0 图片服务器的搭建与使用

作者: 极乐君 | 来源:发表于2017-03-09 15:30 被阅读925次

    来源:一叶知秋
    作者:知秋

    这里简单说下fastdfs的说明搭建使用,回头专门出附章来讲这块的api和各种配置,这里就来过简易版的,能进行开发就可。

    什么是FastDFS

    FastDFS是一个开源的轻量级分布式文件系统。它解决了大数据量存储和负载均衡等问题。特别适合以中小文件(建议范围:4KB< file_size <500MB)为载体的在线服务,如相册网站、视频网站等等。

    FastDFS是用c语言编写的一款开源的分布式文件系统。FastDFS为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,使用FastDFS很容易搭建一套高性能的文件服务器集群提供文件上传、下载等服务。

    FastDFS的设计理念

    和现有的类Google FS分布式文件系统相比,FastDFS的架构和设计理念有其独到之处,主要体现在轻量级分组方式对等结构三个方面。

    轻量级

    FastDFS只有两个角色:Tracker serverStorage serverTracker server作为中心结点,其主要作用是负载均衡和调度。

    Tracker server在内存中记录分组Storage server的状态等信息,不记录文件索引信息,占用的内存量很少。另外,客户端(应用)和Storage server访问Tracker server时,Tracker server扫描内存中的分组和Storage server信息,然后给出应答。由此可以看出Tracker server非常轻量化,不会成为系统瓶颈。

    FastDFS中的Storage server在其他文件系统中通常称作Trunk serverDataserverStorage server直接利用OS的文件系统存储文件。FastDFS不会对文件进行分块存储,客户端上传的文件和Storage server上的文件一一对应。

    众所周知,大多数网站都需要存储用户上传的文件,如图片、视频、电子文档等。出于降低带宽和存储成本的考虑,网站通常都会限制用户上传的文件大小,例如图片文件不能超过5MB、视频文件不能超过100MB等。我认为,对于互联网应用,文件分块存储没有多大的必要。它既没有带来多大的好处,又增加了系统的复杂性。FastDFS不对文件进行分块存储,与支持文件分块存储的DFS相比,更加简洁高效,并且完全能满足绝大多数互联网应用的实际需要。

    FastDFS中,客户端上传文件时,文件ID不是由客户端指定,而是由Storage server生成后返回给客户端的。文件ID中包含了组名文件相对路径文件名Storage server可以根据文件ID直接定位到文件。因此FastDFS集群中根本不需要存储文件索引信息,这是FastDFS比较轻量级的一个例证。而其他文件系统则需要存储文件索引信息,这样的角色通常称作NameServer。其中mogileFS采用MySQL数据库来存储文件索引以及系统相关的信息,其局限性显而易见,MySQL将成为整个系统的瓶颈。

    FastDFS轻量级的另外一个体现是代码量较小。最新的V2.0包括了C客户端APIFastDHT客户端APIPHP extension等,代码行数不到5.2万行。

    分组方式

    Google FS都支持文件冗余备份,例如Google FSTFS的备份数是3。一个文件存储到哪几个存储结点,通常采用动态分配的方式。采用这种方式,一个文件存储到的结点是不确定的。举例说明,文件备份数是3,集群中有A、B、C、D四个存储结点。文件1可能存储在A、B、C三个结点,文件2可能存储在B、C、D三个结点,文件3可能存储在A、B、D三个结点。

    FastDFS采用了分组存储方式。集群由一个或多个组构成,集群存储总容量为集群中所有组的存储容量之和。一个组由一台或多台存储服务器组成,同组内的多台Storage server之间是互备关系,同组存储服务器上的文件是完全一致的。文件上传、下载、删除等操作可以在组内任意一台Storage server上进行。类似木桶短板效应,一个组的存储容量为该组内存储服务器容量最小的那个,由此可见组内存储服务器的软硬件配置最好是一致的。采用分组存储方式的好处是灵活、可控性较强。比如上传文件时,可以由客户端直接指定上传到的组。一个分组的存储服务器访问压力较大时,可以在该组增加存储服务器来扩充服务能力(纵向扩容)。当系统容量不足时,可以增加组来扩充存储容量(横向扩容)。采用这样的分组存储方式,可以使用FastDFS对文件进行管理,使用主流的Web serverApache、nginx等进行文件下载。

    对等结构

    FastDFS集群中的Tracker server也可以有多台,Tracker serverStorage server均不存在单点问题。Tracker server之间是对等关系,组内的Storage server之间也是对等关系。传统的Master-Slave结构中的Master是单点,写操作仅针对Master。如果Master失效,需要将Slave提升为Master,实现逻辑会比较复杂。和Master-Slave结构相比,对等结构中所有结点的地位是相同的,每个结点都是Master,不存在单点问题

    FastDFS的架构

    FastDFS的系统架构 如图:

    从图中可以看出,Tracker server之间相互独立,不存在直接联系。

    客户端和Storage server主动连接Tracker serverStorage server主动向Tracker server报告其状态信息,包括磁盘剩余空间、文件同步状况、文件上传下载次数等统计信息。Storage server会连接集群中所有的Tracker server,向他们报告自己的状态。Storage server启动一个单独的线程来完成对一台Tracker server的连接和定时报告。需要说明的是,一个组包含的Storage server不是通过配置文件设定的,而是通过Tracker server获取到的。

    不同组的Storage server之间不会相互通信,同组内的Storage server之间会相互连接进行文件同步。Storage server采用binlog文件记录文件上传、删除等更新操作。binlog中只记录文件名,不记录文件内容。
    ​ 文件同步只在同组内的Storage server之间进行,采用push方式,即源头服务器同步给目标服务器。只有源头数据才需要同步,备份数据并不需要再次同步,否则就构成环路了。有个例外,就是新增加一台Storage server时,由已有的一台Storage server将已有的所有数据(包括源头数据和备份数据)同步给该新增服务器。

    Storage server中由专门的线程根据binlog进行文件同步。为了最大程度地避免相互影响以及出于系统简洁性考
    虑,Storage server对组内除自己以外的每台服务器都会启动一个线程来进行文件同步。

    文件同步采用增量同步方式,系统记录已同步的位置(binlog文件偏移量)到标识文件中。标识文件名格式:
    {dest storage IP}_{port}.mark,例如:192.168.1.14_23000.mark。

    文件上传和下载的交互过程
    文件上传流程

    接下来我们一起看一下文件上传和下载的交互过程。文件上传流程的步骤如下

    1. Client询问Tracker server上传到的Storage server
    2. Tracker server返回一台可用的Storage server,返回的数据为该Storage server的IP地址和端口;
    3. Client直接和该Storage server建立连接,进行文件上传,Storage server返回新生成的文件ID,文件上传结束。

    再啰嗦点细节:

    选择tracker server

    当集群中不止一个tracker server时,由于tracker之间是完全对等的关系,客户端在upload文件时可以任意选择一个trakcer。
    

    选择存储的group

    当tracker接收到upload file的请求时,会为该文件分配一个可以存储该文件的group,支持如下选择group的规则: 1. Round robin,所有的group间轮询 2. Specified group,指定某一个确定的group 3. Load balance,剩余存储空间多多group优先
    

    选择storage server

    当选定group后,tracker会在group内选择一个storage server给客户端,支持如下选择storage的规则: 1. Round robin,在group内的所有storage间轮询 2. First server ordered by ip,按ip排序 3. First server ordered by priority,按优先级排序(优先级在storage上配置)
    

    选择storage path

    当分配好storage server后,客户端将向storage发送写文件请求,storage将会为文件分配一个数据存储目录,支持如下规则: 1. Round robin,多个存储目录间轮询 2. 剩余存储空间最多的优先
    

    生成Fileid

    选定存储目录之后,storage会为文件生一个Fileid,由storage server ip、文件创建时间、文件大小、文件crc32和一个随机数拼接而成,然后将这个二进制串进行base64编码,转换为可打印的字符串。
    

    选择两级目录

    当选定存储目录之后,storage会为文件分配一个fileid,每个存储目录下有两级256*256的子目录,storage会按文件fileid进行两次hash(猜测),路由到其中一个子目录,然后将文件以fileid为文件名存储到该子目录下。
    

    生成文件名

    当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名,文件名由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成。
    

    客户端上传文件后存储服务器将文件ID返回给客户端,此文件ID用于以后访问该文件的索引信息。文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

    文件同步

    写文件时,客户端将文件写至group内一个storage server即认为写文件成功,storage server写完文件后,会由后台线程将文件同步至同group内其他的storage server

    每个storage写文件后,同时会写一份binlogbinlog里不包含文件数据,只包含文件名等元信息,这份binlog用于后台同步,storage会记录向group内其他storage同步的进度,以便重启后能接上次的进度继续同步;进度以时间戳的方式进行记录,所以最好能保证集群内所有server的时钟保持同步。

    storage的同步进度会作为元数据的一部分汇报到tracker上,tracker在选择读storage的时候会以同步进度作为参考。

    比如一个group内有A、B、C三个storage server,A向C同步到进度为T1 (T1以前写的文件都已经同步到B上了),B向C同步到时间戳为T2(T2 > T1),tracker接收到这些同步进度信息时,就会进行整理,将最小的那个做为C的同步时间戳,本例中T1即为C的同步时间戳为T1(即所有T1以前写的数据都已经同步到C上了);同理,根据上述规则,tracker会为A、B生成一个同步时间戳。

    文件下载流程
    1. Client询问Tracker server可以下载指定文件的Storage server,参数为文件ID(包含组名和文件名);
    2. Tracker server返回一台可用的Storage server;
    3. Client直接和该Storage server建立连接,完成文件下载
    文件同步延迟问题的提出

    客户端将一个文件上传到一台Storage server后,文件上传工作就结束了。由该Storage server根据binlog中的上传记录将这个文件同步到同组的其他Storage server。这样的文件同步方式是异步方式,异步方式带来了文件同步延迟的问题。新上传文件后,在尚未被同步过去的Storage server上访问该文件,会出现找不到文件的现象。

    FastDFS是如何解决文件同步延迟这个问题的呢?

    文件的访问分为两种情况:文件更新和文件下载。文件更新包括设置文件附加属性和删除文件。文件的附加属性包括文件大小、图片宽度、图片高度等。FastDFS中,文件更新操作都会优先选择源Storage server,也就是该文件被上传到的那台Storage server。这样的做法不仅避免了文件同步延迟的问题,而且有效地避免了在多台Storage server上更新同一文件可能引起的时序错乱的问题。

    那么文件下载是如何解决文件同步延迟这个问题的呢?

    要回答这个问题,需要先了解文件名中包含了什么样的信息。Storage server生成的文件名中,包含了源Storage server的IP地址和文件创建时间等字段。文件创建时间为UNIX时间戳,后面称为文件时间戳。从文件名或文件ID中,可以反解出这两个字段。然后我们再来看一下,Tracker server是如何准确地知道一个文件已被同步到一台Storage server上的。前面已经讲过,文件同步采用主动推送的方式。另外,每台storage server都会定时向tracker server报告它向同组的其他storage server同步到的文件时间戳。当tracker server收到一台storage server的文件同步报告后,它会依次找出该组内各个storage server(后称作为S)被同步到的文件时间戳最小值,作为S的一个属性记录到内存中。

    FastDFS对文件同步延迟问题的解决方案

    下面我们来看一下FastDFS采取的解决方法。

    一个最简单的解决办法,和文件更新一样,优先选择源Storage server下载文件即可。这可以在Tracker server的配置文件中设置,对应的参数名为download_server。

    另外一种选择Storage server的方法是轮流选择(round-robin)。当Client询问Tracker server有哪些Storage server可以下载指定文件时,Tracker server返回满足如下四个条件之一的Storage server:

    1. 该文件上传到的源Storage server,文件直接上传到该服务器上的;

    2. 文件创建时间戳 < Storage server被同步到的文件时间戳,这意味着当前文件已经被同步过来了;

    3. 文件创建时间戳=Storage server被同步到的文件时间戳,且(当前时间—文件创建时间戳) > 一个文件同步完成需要的最大时间(如5分钟);

      (当前时间—文件创建时间戳) > 文件同步延迟阈值,比如我们把阈值设置为1天,表示文件同步在一天内肯定可以完成。

    图片服务器的搭建

    因为开发所用,这里就搭建个单机版

    安装环境 CentOS6.8 64位

    需要gcc的编译环境

    需要libevent的包。

    yum install -y zlib zlib-devel pcre pcre-devel gcc gcc-c++ openssl openssl-devel libevent libevent-devel perl unzip

    安装步骤

    Tracker的安装

    第一步:把源码包上传到linux系统。

    第二步:解压缩libfastcommonV1.0.7.tar.gz包。

    第三步:进入/root/libfastcommon-1.0.7文件夹执行./make.sh、./make.sh install

    安装libfastcommon
    
    下载最新版本: libfastcommon
    wget https://github.com/happyfish100/libfastcommon/archive/master.zip
    unzip master.zip
    cd libfastcommon-master/
    ./make.sh
    ./make.sh install
    
    

    第四步:把/usr/lib64/libfastcommon.so文件向/usr/lib文件夹下复制一份。(32位系统可这么做,64位不需要)

    第五步:把FastDFS_v5.05.tar.gz解压缩。

    第六步:进入/root/FastDFS目录执行:./make.sh、./make.sh install

    
    wget http://sourceforge.net/projects/fastdfs/files/FastDFS%20Server%20Source%20Code/FastDFS%20Server%20with%20PHP%20Extension%20Source%20Code%20V5.05/FastDFS_v5.05.tar.gz
    tar zxf FastDFS_v5.05.tar.gz && cd FastDFS
    ./make.sh
    ./make.sh install
    \cp -pa conf/*.conf /etc/fdfs/
    cd /etc/fdfs/
    rm -rf *.sample
    

    第七步:配置trackerServer。

    1、 把/root/FastDFS/conf目录下的所以的文件复制到/etc/fdfs目录下。

    2、 编辑/etc/fdfs/tracker.conf

    第八步:启动tracker服务

    /usr/bin/fdfs_trackerd/etc/fdfs/tracker.conf restart

    Storage服务的安装

    如果storage和tracker不在同一台服务上需要重复执行Tracker的安装的第一步到第六步

    配置Storage服务:

    需要修改/etc/fdfs/storage.conf文件

    启动服务:

    [root@localhost fdfs]#/usr/bin/fdfs_storaged /etc/fdfs/storage.conf

    测试上传服务

    修改客户端的配置文件/etc/fdfs/client.conf

    上传文件:

    /usr/bin/fdfs_testclient.conf upload xxx.jpg

    访问图片

    使用FastDFS的Nginx插件和Nginx配合,实现图片的访问。Nginx需要安装到storage服务所在的服务器

    安装步骤:

    第一步:把插件包解压缩。fastdfs-nginx-module_v1.16.tar.gz

    第二步:编辑/root/fastdfs-nginx-module/src/config文件。删除其中的local字样

    wget http://nginx.org/download/nginx-1.8.0.tar.gz
    http://sourceforge.net/projects/fastdfs/files/FastDFS%20Nginx%20Module%20Source%20Code/fastdfs-nginx-module_v1.16.tar.gz/download
    
    tar zxf fastdfs-nginx-module_v1.16.tar.gz && tar zxf nginx-1.8.0.tar.gz 
    
    #修改模块中对应的路径,要不然模块不能正确安装加载
    cd fastdfs-nginx-module/src
    vi conf   #更改如下, 去掉local,并指定lib64(64系统)
    CORE_INCS="$CORE_INCS /usr/include/fastdfs /usr/include/fastcommon/"
    CORE_LIBS="$CORE_LIBS -L/usr/lib64 -lfastcommon -lfdfsclient"
    

    第三步:把/root/fastdfs-nginx-module/src/mod_fastdfs.conf文件复制到/etc/fdfs目录下。

    第四步:把/usr/lib64/libfdfsclient.so文件复制到/usr/lib目录下(32位系统,64位系统不需要)

    第五步:编译Nginx

    对Nginx进行config

    ./configure \
    --prefix=/usr/local/nginx \
    --pid-path=/var/run/nginx/nginx.pid \
    --lock-path=/var/lock/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=/root/fastdfs-nginx-module/src
    
    

    第六步:配置Nginx

    第七步:编辑Nginx插件的配置文件:

    修改/etc/fdfs/mod_fastdfs.conf文件

    第八步:启动Nginx

    最後,再多说一点 这是之前自己 笔记的一点心得,贴出来

    nginx通过插件fastdfs-nginx-module_v1.16.tar管理访问/group1/M00/过来的路径
    这是插件的日志路径
    # the base path to store log files
    base_path=/tmp
    这里接收管理storage存放路径
    # store_path#, based 0, if store_path0 not exists, it's value is base_path
    # the paths must be exist
    # must same as storage.conf 注意看这些注释,然后就知道怎么配了
    store_path0=/home/fastdfs/storage
    通过下面来和索引器联系起来
    # valid only when load_fdfs_parameters_from_tracker is true
    tracker_server=192.168.42.129:22122
    
    

    忘说了:
    启动测试前,开放端口号端口给浏览器访问

    /sbin/iptables -I INPUT -p tcp --dport 80 -j ACCEPT
    /sbin/iptables -I INPUT -p tcp --dport 22 -j ACCEPT
    /sbin/iptables -I INPUT -p tcp --dport 22122 -j ACCEPT
    #然后保存:
    /etc/rc.d/init.d/iptables save
    #重启防火墙以便改动生效:(或者直接重启系统)
    /etc/init.d/iptables restart
    

    往期回顾:


    更多内容请关注:极乐科技

    相关文章

      网友评论

        本文标题:【Java实战项目】Migo商城2.0 图片服务器的搭建与使用

        本文链接:https://www.haomeiwen.com/subject/olwbgttx.html