[TOC]

0x00 基础介绍

0.前言

Q: 传统的文件系统面临的问题与挑战?
描述: 在传统WEB应用中,前端、后端、以及其它API服务部署在同一台服务器,所有文件都作为静态资源访问,随着业务量的不断增长,久而久之,图片和文件等资源占用的空间变得越来越大。

随之带来了各种性能、管理与安全风险等问题,如下所示:

  • 若文件直接置于应用服务器中,难以管理;
  • 昂贵的磁盘空间、高性能服务器大大增加了运维成本;
  • 易发生单点故障;
  • 传统FTP上传文件,存在诸多安全隐患(用户名和口令的明文传输等);
  • 无法保证文件的机密性,某些敏感文件如身份证照片等以明文存储,文件的授权访问不易控制;
  • 安全没有保障,文件上传、下载、删除、查看依赖于各个业务系统的实现,一个上传功能可能出现“修不完的漏洞”;


Q: 什么是分布式文件系统?
描述: 分布式文件系统(Distributed File System, DFS)是一种允许文件通过网络在多台主机上分享的文件系统,可让多机器上的多用户分享文件和存储空间。客户端并非直接访问底层的数据存储区块,而是通过网络以特定的通信协议与服务器通信,借通信协议来限制客户端对于文件系统的访问。分布式文件存储利用多台存储服务器分担存储压力,利用跟踪服务器定位存储信息,不但提高了系统可靠性、可用性以及读写效率,而且方便水平扩展。分布式文件存储可采用多副本备份机制,分布式存储对数据进行了分片,分片后的数据按照一定规则保存在集群节点上。即使单个集群节点机器发生故障也能保证数据不会丢失,最小化对业务的影响。

Tips: 既然传统的文件存储方式存在这么多弊端,那么新的分布式文件系统需要满足哪些需求呢?

WeiyiGeek.应用功能需求与技术需求

WeiyiGeek.应用功能需求与技术需求


1.简介

描述: FastDFS 是阿里的余庆大佬用 C 语言编写的一款开源的分布式文件系统(个人项目),它对文件进行管理。功能包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,适合中小文件(4KB < file_size <500MB)存储,解决了大容量文件存储负载均衡的问题。充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标

应用场景:

  • 1.特别适合以文件为载体的在线服务,如相册网站、视频网站等等。
  • 2.​适合用来存储用户图片、视频、文档等文件(小文件 建议范围:4KB < file_size < 500MB)。

Tips: 支持Linux、FreeBSD等UNIX系统类 google FS,但不是通用的文件系统;
Tips: FastDFS不适用于分布式计算存储的场景、以及数据库文件、VM虚拟机文件的存储;


2.特性

FastDFS是一种基于文件的key/value pair存储系统,作为一个轻量级分布式文件存储,FastDFS具有以下特性:

  • (1) 支持主从集群配置
  • (2) 支持在线扩容
  • (3) 支持备份容错
  • (4) 支持相同内容文件合并,节约磁盘空间
  • (5) 支持海量文件的存储和读写分离
  • (6) 文件不分块存储,上传的文件和 OS 文件系统中的文件一一对应
  • (7) 下载文件支持 HTTP 协议,可以使用内置 Web Server,也可以和其他 Web Server 配合使用
  • (8) 支持断点续传,对大文件简直是福音。


FastDFS 优点:

  • (1) 结构简单,元数据节点压力低
  • (2) 扩容简单,扩容后文件自动同步,无需重新平衡,增强了系统的可扩展性
  • (3) 高性能,文件处理速度快,适合海量小文件存储
  • (4) 主从架构,增强系统的可用性
  • (5) 实现软RAID,增强了系统的并发处理能力和数据容错恢复能力


FastDFS 缺点:

  • (1) 不能自定义文件key,自己定义会降低灵活性
  • (2) 大文件冲击问题:大文件没有分片,导致大文件的读写都由单块硬盘承担,对磁盘的冲击很大,由于我们主要以小文件为主,所以影响较小
  • (3) 缺乏自动化故障恢复机制、运维机制和在线配置能力
  • (4) 数据恢复效率低:磁盘镜像分布,修复速度取决于磁盘写入速度
  • (5) 源storage写一份即返回成功,源storage出现故障,就可能导致数据丢失,建立监控告警机制,对storage进行检测,实现出现故障时及时通知处理
  • (6) 缺乏必要的安全访问控制机制以及文件数据保护措施,通过文件服务网关可以自己实现访问控制与数据保护。
  • (7) 同步机制不支持文件正确性校验,降低了系统的可用性
  • (8) 对跨公网的文件同步,存在着比较大的延迟,需要应用做相应的容错策略()。

Tips : ​出于简洁考虑 FastDFS 没有对文件做分块存储,因此不太适合分布式计算场景。


3.架构

描述: FastDFS 文件系统主要由 Tracker serverStorage server 组成。其中 Storage 负责存储文件,Tracker 负责存储文件所在地址,主要作用是负载均衡和资源调度。


原理流程: 客户端请求 Tracker server 进行文件上传、下载、删除文件, Tracker server 将客户端的请求调度到 Storage server 完成文件的上传和下载。

从框架图中我们可以看到FastDFS服务端有三个角色, 跟踪服务器(tracker server)存储服务器(storage server)客户端(client)。Tracker、Storage 都可以实现集群部署,Tracker的每个节点地位平等,而Storage可以分为多个组,每个组之间保存的文件是不同的,组内部分为多个成员且地位一致,每个成员保存的内容是一样,没有主从概念。

WeiyiGeek.FastDFS架构

WeiyiGeek.FastDFS架构

Tips : 使用FastDFS存储文件优点,可以应对互联网的海量文件存储,一旦文件较多,可以随时横向扩展,且集群的实现也使系统不存在单点故障问题,用户不会因为服务器宕机而无法访问文件资源。


Tracker Server

描述: 跟踪服务器作为集群的中心节点,负责对客户端的请求进行负载均衡和调度工作,以及负责管理所有的 storage server 和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。tracker 根据 storage 的心跳信息,建立 group==>[storage serverlist] 的映射表。

重点: Tracker 管理的元数据信息较少并且会全部存储在内存中,另外 tracker 上的元信息都是由 storage 汇报的信息生成的,本身不需要持久化任何数据,使得 tracker 非常容易扩展,直接增加 tracker 机器即可扩展为 tracker cluster 来服务,cluster 里每个 tracker 之间是完全对等的,所有的 tracker 都接受 stroage 的心跳信息,生成元数据信息来提供读写服务。


Storage Server

描述: 存储服务器(又称:存储节点或数据服务器)主要提供容量和备份服务。

它以 group 为单位每个 group 内可以有多台 storage server 数据互为备份;

它有如下优缺点:

  • 优点: 是将不同应用数据存到不同的Group就能隔离应用数据,同时还可根据应用的访问特性来将应用分配到不同的Group来做负载均衡。
  • 缺点: 是Group的容量受单机存储容量的限制,同时当Group内有机器坏掉时,数据恢复只能依赖group内的其他机器,使得恢复时间会很长。

以 group 为单位每个 group 内可以有多台 storage server 数据互为备份; 以 group 为单位组织存储能方便的进行应用隔离、负载均衡、副本数定制(group内storage server数量即为该group的副本数);

Tips : group 组也可称为卷。同组内服务器上的文件是完全相同的,同一组内的storage server之间是对等的, 文件上传、 删除等操作可以在任意一台storage server上进行 。

重点: group内每个storage的存储依赖于本地文件系统,storage可配置多个数据存储目录,比如有10块磁盘分别挂载在/data/disk1-/data/disk10,则可将这10个目录都配置为storage的数据存储目录。storage接受到写文件请求时,会根据配置好的规则选择其中一个存储目录来存储文件。为了避免单个目录下的文件数太多,在storage第一次启动时,会在每个数据存储目录里创建2级子目录,每级256个,总共256^2=65536个文件,新写的文件会以hash的方式被路由到其中某个子目录下,然后将文件数据(文件和文件属性(meta data)键值对(Key Value Pair)方式,如:width=1024,heigth=768)作为本地文件存储到该目录中, 即Storage server直接利用OS的文件系统调用管理文件。


Client

描述: client(客户端) 作为业务请求的发起方,通过专有接口,使用TCP/IP协议与跟踪器服务器或存储节点进行数据交互。FastDFS向使用者提供基本文件访问接口,比如upload、download、append、delete等,以客户端库的方式提供给用户使用。


4.存储策略

描述: 为了支持大容量存储节点(服务器)采用了分卷(或分组)的组织方式。存储系统由一个或多个卷组成,卷与卷之间的文件是相互独立的,所有卷的文件容量累加就是整个存储系统中的文件容量。一个卷可以由一台或多台存储服务器组成,一个卷下的存储服务器中的文件都是相同的,卷中的多台存储服务器起到了冗余备份负载均衡的作用。

WeiyiGeek.存储策略方式

WeiyiGeek.存储策略方式

Tips : 在卷中增加服务器时,同步已有的文件由系统自动完成,同步完成后,系统自动将新增服务器切换到线上提供服务。

Tips : 当存储空间不足或即将耗尽时,可以动态添加卷, 只需要增加一台或多台服务器,并将它们配置为一个新的卷,这样就扩大了存储系统的容量。


5.过程剖析

文件上传 - Upload

描述: 通过前面架构介绍我们知道向使用者提供基本文件访问接口,比如 upload、download、append、delete 等,以客户端库的方式提供给用户使用。

简单流程:
描述: Storage Server 会定期的向 Tracker Server 发送自己的存储信息。当 Tracker Server Cluster 中的 Tracker Server 不止一个时,各个Tracker之间的关系是对等的,所以客户端上传时可以选择任意一个Tracker。 当Tracker收到客户端上传文件的请求时,会为该文件分配一个可用的 group (Storage Server其中的组)来进行存储文件的,当选定了group后就要决定给客户端分配group中的哪一个storage server。当分配好storage server后客户端向storage发送写文件请求,storage将会为文件分配一个数据存储目录,然后为文件分配一个fileid(路径信息和文件名),最后根据以上的信息生成文件名并存储文件。

WeiyiGeek.fdfs文件上传

WeiyiGeek.fdfs文件上传


内部机制

  • 1) 选择 tracker server
    描述: 当集群中不止一个tracker server时,由于tracker之间是完全对等的关系,客户端在upload文件时可以任意选择一个trakcer。 选择存储 Storage 的 group 当 tracker 接收到upload file的请求时,会为该文件分配一个可以存储该文件的group,支持如下选择group的规则:

    • 1、Round robin, 以轮询的方式依次的向各个group存储文件,对应配置值0
    • 2、Specified group,指定某一个确定的group,对应配置值1,此时需要配合配置store_group=group_name来指定
    • 3、Load balance,剩余存储空间多多group优先
  • 2) 选择 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上配置)
  • 3) 选择 storage path
    描述: 当分配好storage server后,客户端将向storage发送写文件请求,storage将会为文件分配一个数据存储目录,支持如下规则:

    • 1、Round robin,多个存储目录间轮询
    • 2、剩余存储空间最多的优先
  • 4) 生成 fileid
    描述: 选定存储目录之后storage会为文件生一个Fileid,由storage server ip、文件创建时间、文件大小、文件crc32和一个随机数拼接而成,然后将这个二进制串进行base64编码,转换为可打印的字符串。选择两级目录当选定存储目录之后,storage会为文件分配一个fileid,每个存储目录下有两级256*256的子目录,storage会按文件fileid进行两次hash(猜测),路由到其中一个子目录,然后将文件以fileid为文件名存储到该子目录下。

  • 5) 生成文件名
    描述: 当文件存储到某个子目录后,即认为该文件存储成功,接下来会为该文件生成一个文件名(精巧的文件ID-FID),文件名由group、存储目录、两级子目录、fileid、文件后缀名(由客户端指定,主要用于区分文件类型)拼接而成,是客户端上传文件后存储服务器返回给客户端,用于以后访问该文件的索引信息。

    1
    2
    3
    # fdfs_upload_file /etc/fdfs/storage.conf logo.jpg
    组名/磁盘/一级目录(2*Hex)/二级目录(2*Hex)/文件名称
    group1/M00/00/00/wKgMMmB2bmyAP9SWAAA_wvXjApM631.jpg
    WeiyiGeek.fdfs文件名称说明

    WeiyiGeek.fdfs文件名称说明

Tips : 文件索引信息包括:组名,虚拟磁盘路径,数据两级目录,文件名。

  • 组名:文件上传后所在的存储组名称,在文件上传成功后有存储服务器返回,需要客户端自行保存。
  • 文件存储虚拟磁盘路径:存储服务器配置的虚拟路径,与磁盘选项store_path*对应(默认常规为M00)。
  • 数据文件两级目录:存储服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件。
  • 文件名:与文件上传时不同。是由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址、文件创建时间戳、文件大小、随机数和文件拓展名等信息。


文件下载 - Download

描述: 跟upload file一样在download file时客户端可以选择任意 tracker server。tracker发送download请求给某个tracker,必须带上文件名信息,tracke从文件名中解析出文件的group、大小、创建时间等信息,然后为该请求选择一个storage用来服务读请求。由于group内的文件同步时在后台异步进行的,所以有可能出现在读到时候,文件还没有同步到某些 storage server上,为了尽量避免访问到这样的storage,tracker 按照如下规则选择 group 内可读的 storage:

  • 1.该文件上传到的源头 storage, 只要源头 storage存活着就肯定包含这个文件,源头的地址被编码在文件名中。
  • 2.文件创建时间戳 == storage 被同步到的时间戳且(当前时间-文件创建时间戳) > 文件同步最大时间(如5分钟) - 文件创建后认为经过最大同步时间后,肯定已经同步到其他storage了。
  • 3.文件创建时间戳 < storage被同步到的时间戳。 - 同步时间戳之前的文件确定已经同步了
  • 4.(当前时间-文件创建时间戳) > 同步延迟阀值(如一天)。 - 经过同步延迟阈值时间,认为文件肯定已经同步了。
WeiyiGeek.fdfs文件下载

WeiyiGeek.fdfs文件下载


文件访问 - HTTP

描述: FastDFS的tracker和storage都内置了http协议的支持,客户端可以通过http协议来下载文件,tracker在接收到请求时,通过http的redirect机制将请求重定向至文件所在的storage上;我们这里对nginx改造后生成hsiar,通过hsiar可以实现视频http请求后可以边下载边播的功能,从而减低对网络带宽的压力。

WeiyiGeek.图片来自chinaUnix

WeiyiGeek.图片来自chinaUnix

Tips: 采用Nginx作为网关处理请求转发和校验,Nginx的多路复用机制和非阻塞IO非常适合业务简单、耗时短的校验操作。


文件同步 - Sync

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

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

storage的同步进度会作为元数据的一部分汇报到tracker上,tracke在选择读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生成一个同步时间戳。


6.功能比对

单机文件系统的对比

文件系统 高可用 扩展 部署复杂程度 性能
单机文件系统 低,依赖于单机服务器,只要服务器崩溃,完全不可用。 低,要扩容只能停机增加硬盘。 当文件数量多到一定的程度,磁盘IO寻址操作将会成为瓶颈
分布式文件系统 高,一个group内的服务器崩溃后,group内的其他storage将接管服务。 高,可以不停机增加group机器。 高,部署较复杂 高,通过集群或者分布式的方式分担服务器的压力。


其他文件系统的对比

指标 适合类型 文件分布 系统性能 复杂度 FUSE POSIX 备份机制 通讯协议接口 社区支持 开发语言
FastDFS 4KB~500MB 小文件合并存储不分片处理 很高 简单 不支持 不支持 组内冗余备份 Api HTTP 国内用户群 C语言
TFS 所有文件 小文件合并,以block组织分片 复杂 不支持 Block存储多份,主辅灾备 API http C++
MFS 大于64K 分片存储 Master占内存多 支持 支持 多点备份动态冗余 使用fuse挂在 较多 Perl
HDFS 大文件 大文件分片分块存储 简单 支持 支持 多副本 原生api 较多 Java
Ceph 对象文件块 OSD一主多从 复杂 支持 支持 多副本 原生api 较少 C++
MogileFS 海量小图片 复杂 可以支持 不支持 动态冗余 原生api 文档少 Perl
ClusterFS 大文件 简单 支持 支持 C


7.参考来源

官方网站:https://github.com/happyfish100/
配置文档:https://github.com/happyfish100/fastdfs/wiki/
参考资料:https://www.oschina.net/question/tag/fastdfs
Java客户端:https://github.com/happyfish100/fastdfs-client-java


0x01 FastDFS 安装使用

描述: FastDFS 是一个开源的高性能分布式文件系统 (DFS), 下面我们进行简单的安装配置使用。

1.Linux 安装

描述: 在Linux我们常用CentOS或者Ubuntu作为服务器进行安装和使用,下面我将分别在CentOS以及Ubuntu中进行安装FastDFS。

1.1) CentOS 单机部署 FastDFS

环境描述:

  • (1) 软件版本
软件包 版本
CentOS 7.6 (1810)
FastDFS v5.11 master
libfastcommon v1.0.39 master
fastdfs-nginx-module v1.20 master
nginx v1.15.4 stable
  • (2) 磁盘目录准备: 创建数据和日志存储位置mkdir /home/fdfs以及所有安装包下载解压目录/usr/local/src

    1
    mkdir -vp /home/fdfs/{tracker,storage}
  • (3) 服务器地址及其端口: 10.10.107.232 (22122 、8080 / 23000 / 8888)


安装步骤:

  • Step 1.编译安装libfatscommon、FastDFS、fastdfs-nginx-module三大件
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    # 安装 libfatscommon
    git clone https://github.com/happyfish100/libfastcommon.git --depth 1
    cd libfastcommon/ && ./make.sh && ./make.sh install

    # 安装 FastDFS
    git clone https://github.com/happyfish100/fastdfs.git --depth 1
    cd fastdfs/ && ./make.sh && ./make.sh install
    # FastDFS 配置文件准备
    cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf # fastdfs tracker 服务配置文件
    cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf # fastdfs storage 服务配置文件
    cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf #客户端文件,测试用
    cp /usr/local/src/fastdfs/conf/http.conf /etc/fdfs/ #供nginx访问使用
    cp /usr/local/src/fastdfs/conf/mime.types /etc/fdfs/ #供nginx访问使用

    # 安装下载 fastdfs-nginx-module 并将配置文件复制到 /etc/fdfs/etc/fdfs
    git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1
    cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs

Tips : Fastdfs-nginx-module 模块是自定义的nginx模块,FastDFS 通过 Tracker 服务器,将文件放在 Storage 服务器存储,但是同组存储服务器之间需要进行文件复制,有同步延迟的问题。假设 Tracker 服务器将文件上传到了 10.10.107.234,上传成功后文件 ID已经返回给客户端。时 FastDFS 存储集群机制会将这个文件同步到同组存储 10.10.107.235,在文件还没有复制完成的情况下,客户端如果用这个文件 ID 在 10.10.107.234 上取文件,就会出现文件无法访问的错误。而该模块可以重定向文件链接到源服务器取文件,避免客户端由于复制延迟导致的文件无法访问错误。


  • Step 2.编译安装 nginx (原来测试时此处非最新版本1.15.4)
1
2
3
4
5
6
wget http://nginx.org/download/nginx-1.15.4.tar.gz && tar -zxvf nginx-1.15.4.tar.gz
cd nginx-1.15.4/
#添加fastdfs-nginx-module模块
./configure --prefix=/usr/local/nginx --add-module=/usr/local/src/fastdfs-nginx-module/src
#编译安装
make && make install
  • Step 3.FastDFS单机部署流程,对于我的使用场景只是做一个文件服务器,所以无需部署分布式集群,我们将 tracker 服务、storage 服务、 nginx 服务 部署在一台机器上就能完全满足系统的需求。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# 1.tracker配置
$vim /etc/fdfs/tracker.conf
#启用配置文件
disabled=false
#设置tracker的端口号
port=22122
#设置tracker的数据文件和日志目录(需预先创建)
base_path=/home/fdfs/tracker
#设置http端口号
http.server_port=8080


# 2.storage配置
$vim /etc/fdfs/storage.conf
# storage服务端口
port=23000
# 数据和日志文件存储根目录
base_path=/home/dfs/storage
# 第一个存储目录
store_path0=/home/dfs/storage
# tracker服务器IP和端口
tracker_server=10.10.107.232:22122
# http访问文件的端口,和nginx中保持一致
http.server_port=8888


# 3.client 配置
$vim /etc/fdfs/client.conf
# 路径要和 storage 服务器相同
base_path=/home/dfs
# tracker 服务器 IP 和端口
tracker_server=10.10.107.232:22122

# 4.ngx_fastdfs_module模块与Nginx配置
$vim /etc/fdfs/mod_fastdfs.conf
# tracker服务器IP和端口
tracker_server=10.10.107.232:22122
# URL是否带有group_name组名称
url_have_group_name=true
# storage 数据目录
store_path0=/home/fdfs/storage

$ # - 配置nginx.config - #
# 添加如下配置
server {
listen 8888; # 该端口为storage.conf中的http.server_port相同
server_name localhost;

# 方式1.ngx_fastdfs_module模块加载使用
location ~/group[0-9]/ {
ngx_fastdfs_module;
}

# 方式2.添加如下行,将 /group1/M00 指定要或者映射到 /home/dfs/storage/data
# location ~/group([0-9])/M00 {
# root /home/dfs/storage/data;
# # alias /home/dfs/storage/data;
# }

error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
  • Step 4.防火墙规则设置
    1
    2
    3
    4
    5
    6
    # Tracker
    iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 22122 -j ACCEP
    # Storage
    iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 23000 -j ACCEP
    # Nginx
    iptables -I INPUT -p tcp -m state --state NEW -m tcp --dport 8888 -j ACCEP
  • Step 5.tracker、storage、nginx 服务启动 (注意启动顺序)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # tracker 服务启动
    /etc/init.d/fdfs_trackerd [start|restart|stop] # 启动/重启动/停止tracker服务
    chkconfig fdfs_trackerd on # 自启动tracker服务
    service fdfs_trackerd start

    # storage 服务启动
    /etc/init.d/fdfs_storaged start|restart|stop # 启动/重启动/停止storage服务
    chkconfig fdfs_storaged on #自启动storage服务
    service fdfs_storaged start

    # nginx 服务启动
    /usr/local/nginx/sbin/nginx # 启动nginx
    /usr/local/nginx/sbin/nginx -s reload # 重启nginx
    /usr/local/nginx/sbin/nginx -s stop # 停止nginx
  • Step 6.启动完上面的服务之后,我们可以进行上传测试。
    1
    2
    3
    4
    5
    6
    # 保存后测试,返回ID表示成功 如:group1/M00/00/00/xx.tar.gz
    fdfs_upload_file /etc/fdfs/client.conf /usr/local/src/nginx-1.15.4.tar.gz
    group1/M00/00/00/wKgAQ1pysxmAaqhAAA76tz-dVgg.tar.gz

    # 测试下载,用外部浏览器访问刚才已传过的nginx安装包,引用返回的ID
    http://10.10.107.232:8888/group1/M00/00/00/wKgAQ1pysxmAaqhAAA76tz-dVgg.tar.gz


附录编译安装Shell脚本: (有fastdfs项目的改变自己需要进行修改)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#!/bin/bash
# data: 2019-07-23
# for: install FastDFS on CentOS7
# 安装编译依赖
yum install git gcc gcc-c++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget -y

cd /usr/local/src
git clone https://github.com/happyfish100/libfastcommon.git --depth 1
cd libfastcommon/
./make.sh && ./make.sh install

cd ../
git clone https://github.com/happyfish100/fastdfs.git --depth 1
cd fastdfs/
./make.sh && ./make.sh install

# 配置文件准备
cp /etc/fdfs/tracker.conf.sample /etc/fdfs/tracker.conf
cp /etc/fdfs/storage.conf.sample /etc/fdfs/storage.conf
cp /etc/fdfs/client.conf.sample /etc/fdfs/client.conf
cp /usr/local/src/fastdfs/conf/http.conf /etc/fdfs/
cp /usr/local/src/fastdfs/conf/mime.types /etc/fdfs/

cd ../
git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1
cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs

# 编译安装 nginx
cd../
wget http://nginx.org/download/nginx-1.15.4.tar.gz
tar -zxvf nginx-1.15.4.tar.gz
cd nginx-1.15.4/
./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/
make && make install
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx

至此使用Ubuntu安装FastDFS完毕!


1.2) Ubuntu 主从部署 FastDFS

描述: 在CentOS我们是进行的单机部署,此处我们采用两台机器进行FastDFS集群的配置部署,

storage 集群配置两种方式:

  • (1) Multiple volume : 如果为单个group配置多个storage的话,指定相同的group_name即可,此时拥有相同的组名的机器将会有一台被选为主,于此同时有几个节点将会有几个副本。

  • (2) Multiple group : 如果group_name配置不同即为创建不同的组,此处每个group下的storage都是单独的个体,个个都是主。

环境说明:

  • 操作系统以及网络地址
ROLE IP 地址 CPU、内存 发行版以及内核 备注
master 10.10.107.225 4C/8G Ubuntu 20.04.2 LTS (5.4.0-88-generic) Tracker/Storage/Nginx
slave 10.10.107.225 4C/2G Ubuntu 20.04.2 LTS (5.4.0-88-generic) Tracker/Storage
  • 软件版本一览
    • Fastdfs : 6.07
    • Nginx : 1.21.1


安装部署:

  • Step 1.基础环境准备Fastdfs数据目录以及执行用户创建、和机器别名(两台都要执行)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 1.软件仓库更新以及依赖下载
sudo apt-get update
sudo apt-get install git wget gcc make automake autoconf libtool libpcre3 libpcre3-dev zlib1g-dev build-essential

# 2.fastdfs 运行用户创建以及家目录创建。
# 此处巍峨采用普通用户运行fasfdfs以及nginx,为了安全考虑非常建议。
groupadd fdfs && useradd -m -d /home/fdfs -g fdfs fdfs

# 3.分别创建服务和数据存储目录
mkdir -vp /home/fdfs/{storage,tracker,client}

# 4.机器别名
tee -a /etc/hosts <<'EOF'
10.10.107.225 file1.weiyigeek.top
10.10.107.226 file2.weiyigeek.top
EOF


  • Step 2.从Github上拉取Fastdfs相关项目和依赖到本地、进行编译安装。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # 1.拉取Github代码仓库中Fastdfs ( --depth 1 用于指定克隆深度,为1即表示只克隆最近一次commit的代码,减少下载时间和存储空间)
    git clone https://github.com/happyfish100/libfastcommon.git --depth 1 \
    && git clone https://github.com/happyfish100/fastdfs.git --depth 1 \
    && git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1

    # 2.编译安装
    cd libfastcommon && ./make.sh && ./make.sh install
    cd ../fastdfs && ./make.sh && ./make.sh install

    # 3.配置文件复制
    cp /usr/local/src/fastdfs/conf/http.conf /etc/fdfs/ # fastdfs-nginx-module模块自配置文件供nginx访问使用
    cp /usr/local/src/fastdfs/conf/mime.types /etc/fdfs/ # fastdfs-nginx-module模块自配置文件供nginx访问使用
    cp /usr/local/src/fastdfs-nginx-module/src/mod_fastdfs.conf /etc/fdfs/ # mod_fastdfs.conf 模块自配置文件

    # 4.备份配置文件
    cp /etc/fdfs/storage.conf /etc/fdfs/storage.conf-bak
    cp /etc/fdfs/tracker.conf /etc/fdfs/tracker.conf-bak
    cp /etc/fdfs/client.conf /etc/fdfs/client.conf-bak
    cp /etc/fdfs/mod_fastdfs.conf /etc/fdfs/mod_fastdfs.conf-bak


  • Step 3.Nginx 负载均衡服务器编译安装
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    # nginx 源码下载
    wget http://nginx.org/download/nginx-1.20.1.tar.gz -O /usr/local/src
    cd /usr/local/src && tar -zxvf nginx-1.20.1.tar.gz -C .

    # 查看 fastdfs-nginx-module 中的文件
    $ ls /usr/local/src/fastdfs-nginx-module/src
    common.c common.h config mod_fastdfs.conf ngx_http_fastdfs_module.c

    # 编译安装 Nginx (此处我们指定了执行用户为fdfs是为了安全采用最小权限执行) , 此处未添加SSL支持如需要请百度,在编译时加入openssl功能。
    cd ../nginx-1.20.1/
    ./configure --prefix=/usr/local/nginx \
    --user=fdfs \
    --group=fdfs \
    --pid-path=/usr/local/nginx/logs/nginx.pid \
    --add-module=/usr/local/src/fastdfs-nginx-module/src
    make && make install


  • Step 4.为Tracker 、Storage 、Nginx 配置systemd管理的服务(6.07 默认生成的services服务文件启动时会卡在systemctl界面,我们需要进行更改其systemd服务文件)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
# 1.命令行替方式 (注意以下配置的路径是与后续在配置中配置路径强关联)
# sed -i 's/Type=forking/&\nUser=fdfs\nGroup=fdfs/' /lib/systemd/system/fdfs_storaged.service
# sed -i 's#/opt/fastcfs/data#/home/fdfs/storage/data#g' /lib/systemd/system/fdfs_storaged.service
# sed -i '/PIDFile/i WorkingDirectory=/home/fdfs/storage' /lib/systemd/system/fdfs_storaged.service
# sed -i '/ExecStop/a ExecReload=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart' /lib/systemd/system/fdfs_storaged.service


# 2.service 替换方式
# /lib/systemd/system/fdfs_trackerd.service
cat > /lib/systemd/system/fdfs_trackerd.service <<'EOF'
[Unit]
Description=FastDFS trackerd service
After=network-online.target

[Service]
Type=forking
# User=fdfs
# Group=fdfs
WorkingDirectory=/home/fdfs/tracker
PIDFile=/home/fdfs/tracker/data/fdfs_trackerd.pid
ExecStart=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
ExecStop=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf stop
ExecReload=/usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf restart

# No artificial start/stop timeout
TimeoutSec=3

# Disable OOM kill by Linux kernel
OOMScoreAdjust=-1000

[Install]
WantedBy=multi-user.target
EOF


# /lib/systemd/system/fdfs_storaged.service
cat > /lib/systemd/system/fdfs_storaged.service <<'EOF'
[Unit]
Description=FastDFS storaged service
After=network-online.target

[Service]
Type=forking
# User=fdfs
# Group=fdfs
WorkingDirectory=/home/fdfs/storage
PIDFile=/home/fdfs/storage/data/fdfs_storaged.pid
ExecStart=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
ExecStop=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf stop
ExecReload=/usr/bin/fdfs_storaged /etc/fdfs/storage.conf restart

# No artificial start/stop timeout
TimeoutSec=3

# Disable OOM kill by Linux kernel
OOMScoreAdjust=-1000

[Install]
WantedBy=multi-user.target
EOF

# /usr/lib/systemd/system/nginx.service
tee /usr/lib/systemd/system/nginx.service<<'EOF'
[Unit]
Description=Nginx - high performance web server service
Documentation=http://nginx.org/en/docs/
After=network-online.target remote-fs.target nss-lookup.target
Wants=network-online.target

[Service]
Type=forking
PIDFile=/usr/local/nginx/logs/nginx.pid
ExecStart=/usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/bin/kill -s TERM $MAINPID

[Install]
WantedBy=multi-user.target
EOF

# 3.老规矩重载systemd使编辑的service生效
systemctl daemon-reload

# 4.此处我们暂时不启用服务,我们还需进行后续的配置
systemctl stop fdfs_storaged.service fdfs_trackerd.service nginx.service
systemctl status fdfs_storaged.service fdfs_trackerd.service nginx.service

Tips : 非常注意 Tracker 、Storage 生成的pid的路径分别为/home/fdfs/tracker/data/fdfs_trackerd.pid/home/fdfs/storage/data/fdfs_storaged.pid


  • Step 5.两台机器的Tracker服务主要配置。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    $vim /etc/fdfs/tracker.conf


    # - Master 端- #
    # 是否禁用配置文件 (当然False了)
    disabled = false
    # 绑定指定监听的网卡地址否则留空则为全部网卡。
    bind_addr = 10.10.107.225
    # tracker 服务端口
    port = 22122
    # tracker 服务data和logs存储目录 (可以分开也可以全部设置storage中)
    # sed -i "s#/home/yuqing/fastdfs#/home/fdfs/tracker#g" /etc/fdfs/tracker.conf
    base_path = /home/fdfs/tracker
    # 为系统或其他应用程序保留的存储空间。
    reserved_storage_space = 10%
    # 指定用户运行 tracker 服务
    run_by_user = fdfs
    run_by_group = fdfs
    # 指定访问白名单默认所有都可访问 (正式环境一定要设置)
    allow_hosts = *


    # - Slave 端- #
    disabled = false
    bind_addr = 10.10.107.226 # 不同点
    port = 22122
    base_path = /home/fdfs/tracker
    reserved_storage_space = 10%
    run_by_user = fdfs
    run_by_group = fdfs
    allow_hosts = *


  • Step 6.两台机器的Storage服务主要配置。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    $ vim /etc/fdfs/storage.conf

    # - Master 端- #
    # 是否禁用配置文件 (当然False了)
    disabled = false
    # 此存储服务器所属的组的名称 (多个组可以将此组名进行更改) ,
    group_name = group1
    # 绑定指定监听的网卡地址否则留空则为全部网卡。
    bind_addr = 10.10.107.225
    # storage 服务端口
    port = 23000
    # storage 服务 data和logs 存储目录
    # sed -i "s#/home/yuqing/fastdfs#/home/fdfs/storage#g" /etc/fdfs/storage.conf
    base_path = /home/fdfs/storage
    # storage 服务数据存储目录 (the base_path should be independent (different) of the store paths)
    store_path0 = /home/fdfs/storage
    # 指定tracker_server地址和服务端口,如有多台则填多个。如果有外网地址可以在,
    tracker_server = 10.10.107.225:22122
    tracker_server = 10.10.107.226:22122
    # 指定用户和用户组运行storage服务
    run_by_group = fdfs
    run_by_user = fdfs
    # 指定可以访问 storage 的主机 (白名单机制)
    allow_hosts = *
    # 作为上载文件的源服务器的优先级,此值越低,其上载优先级越高。默认值为10
    upload_priority = 10
    # 如果域名为空,请使用此存储服务器的ip地址,否则该域名将出现在跟踪服务器重定向的url中
    http.domain_name = file1.weiyigeek.top
    # 此存储服务器上web服务器的端口 与 Nginx 监听端口是对应的。
    http.server_port = 8888

    # - Slave 端- #
    disabled = false
    # 此处由于master、slave要进行组同步所以此处必须是一致的。
    group_name = group1
    bind_addr = 10.10.107.226 # 不同点
    port = 23000
    base_path = /home/fdfs/storage
    store_path0 = /home/fdfs/storage
    tracker_server = 10.10.107.225:22122
    tracker_server = 10.10.107.226:22122
    run_by_group = fdfs
    run_by_user = fdfs
    allow_hosts = *
    upload_priority = 10
    http.domain_name = file2.weiyigeek.top # 不同点
    http.server_port = 8888

Tips : 根据需求进行设置A机房的所有storage配置中的priority为1,设置B机房的所有storage配置中的priority为10进行数据上传;


  • Step 7.两台机器的client.conf主要配置, 可选配置如果Master与Slave的机器只是作为存储而非fastdfs时此处可以省略,此处假设使用Master 端作为fastdfs客户端进行上传文件进行测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
vim /etc/fdfs/client.conf

# - Master 端- #
# clinet 存储日志文件的基本路径
# sed -i "s#/home/yuqing/fastdfs#/home/fdfs/client#g" /etc/fdfs/client.conf
base_path = /home/fdfs/client

# tracker server 地址以及端口(如果有多个则填写多个tracker_server)
tracker_server = 10.10.107.225:22122
tracker_server = 10.10.107.226:22122

# tracker HTTP 端口
http.tracker_server_port = 8080

Tips : 如果storage使用ids来标识,而不是用ip则storage_ids.conf配置文件需要配置。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# (1) storage_ids.conf
# <id> <group_name> <ip_or_hostname>
100001 group1 192.168.0.196
100002 group1 192.168.0.116

# (2) tracker.conf
use_storage_id = false
storage_ids_filename = storage_ids.conf
id_type_in_filename = ip

# (3) storage.conf
group_name=group1 # 需要与上面的组名对应

# (4) client.conf 中也有两处需要修改:
use_storage_id = false
storage_ids_filename = storage_ids.conf


  • Step 8.两台机器的mod_fastdfs模块主要配置, 可选配置如果Master与Slave的机器只是作为存储而非web服务器时此处可以省略。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
$ vim /etc/fdfs/mod_fastdfs.conf
# - Master 端- #
# mod_fastdfs 日志存储目录
base_path=/tmp
# 本地存储服务器组名
group_name=group1
# URL 中是否带组名
url_have_group_name = true
# 本地存储服务器服务端口
storage_server_port=23000
# 本地存储服务器服务数据目录 必须和storage.conf配置一致。
store_path0=/home/fdfs/storage
# FastDFS tracker_server
tracker_server=file1.weiyigeek.top:22122
tracker_server=file2.weiyigeek.top:22122


# - Slave 端- #
base_path=/tmp
group_name=group1
url_have_group_name = true
storage_server_port=23000
store_path0=/home/fdfs/data
tracker_server=file1.weiyigeek.top:22122
tracker_server=file2.weiyigeek.top:22122


  • Step 8.两台机器的nginx.conf配置,可选配置如果Master与Slave的机器只是作为存储而非web服务器时此处可以省略。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    # Master Slave 配置是一致的除了server_name。
    $vim /usr/local/nginx/conf/nginx.conf
    user fdfs;
    worker_processes 1;
    pid logs/nginx.pid;
    server {
    listen 8888;
    server_name file1.weiyigeek.top;
    location ~/group[0-9]/ {
    ngx_fastdfs_module;
    }

    location / {
    root html;
    index index.html index.htm;
    }
    error_page 500 502 503 504 /50x.html;
    location = /50x.html {
    root html;
    }
    }


  • Step 9.设置目录所属权限以及防火墙规则设置。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # (1) 相关目录文件所属组赋予,防止权限问题导致不能运行相关服务。
    chown -R fdfs:fdfs /home/fdfs
    chown -R fdfs:fdfs /usr/local/nginx

    # (2) 防火墙设置
    # - Master 端- #
    sudo ufw allow proto tcp from 10.10.107.0/24 to port 10.10.107.225 22122
    sudo ufw allow proto tcp from 10.10.107.0/24 to port 10.10.107.225 23000
    sudo ufw allow 8888/tcp

    # - Slave 端- #
    sudo ufw allow proto tcp from 10.10.107.0/24 to port 10.10.107.226 22122
    sudo ufw allow proto tcp from 10.10.107.0/24 to port 10.10.107.226 23000
    sudo ufw allow 8888/tcp


  • Step 10.分别启动两台主机中tracker、storage、nginx三个服务。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 1.分别启动三个服务(先Master启动后在启动Slave的)
systemctl start fdfs_trackerd.service && systemctl status fdfs_trackerd.service
# ● fdfs_trackerd.service - FastDFS trackerd service
# Loaded: loaded (/lib/systemd/system/fdfs_trackerd.service; disabled; vendor preset: enabled)
# Active: active (running) since Sat 2021-10-30 23:01:56 CST; 7ms ago

systemctl start fdfs_storaged.service && systemctl status fdfs_storaged.service
# ● fdfs_storaged.service - FastDFS storaged service
# Loaded: loaded (/lib/systemd/system/fdfs_storaged.service; disabled; vendor preset: enabled)
# Active: active (running) since Sat 2021-10-30 23:21:18 CST; 7ms ago
# Oct 30 23:21:18 elk1 systemd[1]: Starting FastDFS storaged service...
# Oct 30 23:21:18 elk1 systemd[1]: fdfs_storaged.service: Can't open PID file /home/fdfs/storage/data/fdfs_storaged.pid (yet?) after start: Operation not permitted # 总说我没得权限感觉是Bug
# Oct 30 23:21:18 elk1 systemd[1]: Started FastDFS storaged service.

systemctl start nginx.service && systemctl status nginx.service

# 2.fastdfs相关进程查看
$ ps aux | grep "fdfs"
fdfs 1304830 0.0 0.3 145704 6140 ? Sl 22:55 0:00 /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf start
fdfs 1305056 1.8 0.2 141184 4036 ? Sl 22:56 0:00 /usr/bin/fdfs_storaged /etc/fdfs/storage.conf start
fdfs 1305106 0.0 0.0 6372 424 ? Ss 22:57 0:00 nginx: master process /usr/local/nginx/sbin/nginx -c /usr/local/nginx/conf/nginx.conf
fdfs 1305107 0.0 0.1 7288 3736 ? S 22:57 0:00 nginx: worker process
root 1305136 0.0 0.0 6300 664 pts/0 S+ 22:57 0:00 grep --color=auto fdfs


  • Step 11.fastdfs 主从同步状态以及节点监控。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    $ /usr/bin/fdfs_monitor /etc/fdfs/storage.conf

    # 1.未启用anti_steal_token校验
    [2021-10-30 16:10:01] DEBUG - base_path=/home/fdfs/client, connect_timeout=5, network_timeout=60, tracker_server_count=2, 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
    server_count=2, server_index=0

    # 2.tracker 主服务节点相关信息
    tracker server is 10.10.107.225:22122
    group count: 1
    Group 1:
    group name = group1
    disk total space = 98,265 MB
    disk free space = 78,322 MB
    trunk free space = 0 MB
    storage server count = 2
    active server count = 2
    storage server port = 23000
    storage HTTP port = 8888
    store path count = 1
    subdir count per path = 256
    current write server index = 0
    current trunk file id = 0

    # 3.主从节点存储状态信息以及同步状态(下述针对关键的参数进行说明)
    # 会显示会有几台服务器 有3台就会 显示 Storage 1-Storage 3的详细信息
    Storage 1:
    id = 10.10.107.225
    ip_addr = 10.10.107.225 ACTIVE # 表示节点在线活动
    http domain = file1.weiyigeek.top # 配置文件中设置域名
    version = 6.07 # storage 服务版本
    join time = 2021-10-30 12:55:03
    up time = 2021-10-30 16:06:38
    total storage = 98,265 MB # 存储总空间大小
    free storage = 78,322 MB
    upload priority = 10
    store_path_count = 1
    subdir_count_per_path = 256
    storage_port = 23000
    storage_http_port = 8888
    current_write_path = 0
    source storage id = # 来源storage 由于本身是主所以为空。
    if_trunk_server = 0
    connection.alloc_count = 256 # 连接相关配置。
    connection.current_count = 1
    connection.max_count = 1
    total_upload_count = 1 # fastdfs 系列操作统计。
    success_upload_count = 1
    total_append_count = 0
    success_append_count = 0
    total_modify_count = 0
    success_modify_count = 0
    total_truncate_count = 0
    success_truncate_count = 0
    total_set_meta_count = 0
    success_set_meta_count = 0
    total_delete_count = 0
    success_delete_count = 0
    total_download_count = 0
    success_download_count = 0
    total_get_meta_count = 0
    success_get_meta_count = 0
    total_create_link_count = 0
    success_create_link_count = 0
    total_delete_link_count = 0
    success_delete_link_count = 0
    total_upload_bytes = 595
    success_upload_bytes = 595
    total_append_bytes = 0
    success_append_bytes = 0
    total_modify_bytes = 0
    success_modify_bytes = 0
    stotal_download_bytes = 0
    success_download_bytes = 0
    total_sync_in_bytes = 0
    success_sync_in_bytes = 0
    total_sync_out_bytes = 0
    success_sync_out_bytes = 0
    total_file_open_count = 1
    success_file_open_count = 1
    total_file_read_count = 0
    success_file_read_count = 0
    total_file_write_count = 1
    success_file_write_count = 1
    last_heart_beat_time = 2021-10-30 16:09:39 # 最后一次心跳监测时间
    last_source_update = 2021-10-30 13:16:23 # 最后一次异常来源更新
    last_sync_update = 1970-01-01 08:00:00
    last_synced_timestamp = 1970-01-01 08:00:00

    Storage 2:
    id = 10.10.107.226
    ip_addr = 10.10.107.226 ACTIVE
    http domain = file2.weiyigeek.top
    version = 6.07
    join time = 2021-10-30 15:37:13
    up time = 2021-10-30 16:07:34
    total storage = 98,265 MB
    free storage = 84,390 MB
    upload priority = 10
    store_path_count = 1
    subdir_count_per_path = 256
    storage_port = 23000
    storage_http_port = 8888
    current_write_path = 0
    source storage id = 10.10.107.225 # 由于本节点是从,所以其源节点为10.10.107.225
    if_trunk_server = 0
    connection.alloc_count = 256
    connection.current_count = 1
    connection.max_count = 1
    total_upload_count = 0
    success_upload_count = 0
    total_append_count = 0
    success_append_count = 0
    total_modify_count = 0
    success_modify_count = 0
    total_truncate_count = 0
    success_truncate_count = 0
    total_set_meta_count = 0
    success_set_meta_count = 0
    total_delete_count = 0
    success_delete_count = 0
    total_download_count = 0
    success_download_count = 0
    total_get_meta_count = 0
    success_get_meta_count = 0
    total_create_link_count = 0
    success_create_link_count = 0
    total_delete_link_count = 0
    success_delete_link_count = 0
    total_upload_bytes = 0
    success_upload_bytes = 0
    total_append_bytes = 0
    success_append_bytes = 0
    total_modify_bytes = 0
    success_modify_bytes = 0
    stotal_download_bytes = 0
    success_download_bytes = 0
    total_sync_in_bytes = 595
    success_sync_in_bytes = 595
    total_sync_out_bytes = 0
    success_sync_out_bytes = 0
    total_file_open_count = 1
    success_file_open_count = 1
    total_file_read_count = 0
    success_file_read_count = 0
    total_file_write_count = 1
    success_file_write_count = 1
    last_heart_beat_time = 2021-10-30 16:09:34
    last_source_update = 1970-01-01 08:00:00
    last_sync_update = 2021-10-30 16:07:40 # 最后一次同步更新时间
    last_synced_timestamp = 2021-10-30 13:16:23 (0s delay) # 上次同步时间戳


  • Step 12.进行 fastdfs 服务验证我们准备如下文件进行上传测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 准备的上传的文件
$ ls /tmp/1021/21500122111685 && cd /tmp/1021/21500122111685
10.jpg 11.jpg 12.jpg 1.jpg 2.jpg 3.jpg 4.jpg 5.jpg 6.jpg 7.jpg 8.jpg 9.jpg

# 显示执行上传所占用的时间信息,并且由fastdfs返回
$ time ls | xargs -n 1 -I {} -P 256 sh -c "/usr/bin/fdfs_upload_file /etc/fdfs/client.conf {}"
group1/M00/00/00/Cgpr4WF9Z1qAD-1kAALCR9qk6tY282.jpg
group1/M00/00/00/Cgpr4WF9Z1qAPuRNAAC5TGFpmYc275.jpg
group1/M00/00/00/Cgpr4WF9Z1qAXV3hAAHgDlFbt0w747.jpg
group1/M00/00/00/Cgpr4WF9Z1qAbg4zAAIMU22Vmv0167.jpg
group1/M00/00/00/Cgpr4WF9Z1qAGT_9AAM88j2xb3c943.jpg
group1/M00/00/00/Cgpr4mF9Z1qABz5WAAEZU9S6U0A142.jpg
group1/M00/00/00/Cgpr4mF9Z1qAEKxMAAK1nu1_3i4915.jpg
group1/M00/00/00/Cgpr4WF9Z1qAJcPTAAEti0emwI8838.jpg
group1/M00/00/00/Cgpr4mF9Z1uAfqqfAAJEhY4K8tk859.jpg
group1/M00/00/00/Cgpr4mF9Z1uADQKdAAHpbZKkwZM746.jpg
group1/M00/00/00/Cgpr4mF9Z1uAcHhMAAFdgfModII395.jpg
group1/M00/00/00/Cgpr4mF9Z1uAJlVGAAFIRg4hpEg369.jpg

real 0m0.014s
user 0m0.020s
sys 0m0.006s

# 验证上传的文件
wget -I http://10.10.107.225:8888/group1/M00/00/00/Cgpr4WF9Z1qAD-1kAALCR9qk6tY282.jpg


  • Step 13.Tracker 与 storage 服务数据存储目录结构说明,当前面两个服务运行时将会自动创建data、logs这个两个目录:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# Tracker 服务目录
/home/fdfs/tracker# tree
├── data
│   ├── fdfs_trackerd.pid # systemd 监听的PID文件
│   ├── storage_changelog.dat # storage 改变记录文件
│   ├── storage_groups_new.dat # storage 分组信息记录文件
│   ├── storage_servers_new.dat # storage 服务节点信息记录文件
│   └── storage_sync_timestamp.dat # storage 同步的时间戳
└── logs
└── trackerd.log # trackerd 运行日志文件,默认级别 info、
2 directories, 6 files

# Storage 服务目录 (Master 和 Slave 各自存储一份文件)
/home/fdfs/storage# tree . | more
.
├── data
│   ├── 00
│   │   ├── 00 # 0
│   │   │   ├── Cgpr4mF9Z1qABz5WAAEZU9S6U0A142.jpg
│   │   │   ├── Cgpr4mF9Z1qAEKxMAAK1nu1_3i4915.jpg
│   │   │   ├── Cgpr4mF9Z1uAcHhMAAFdgfModII395.jpg
│   │   │   ├── Cgpr4mF9Z1uADQKdAAHpbZKkwZM746.jpg
│   │   │   ├── Cgpr4mF9Z1uAfqqfAAJEhY4K8tk859.jpg
│   │   │   ├── Cgpr4mF9Z1uAJlVGAAFIRg4hpEg369.jpg
│   │   │   ├── Cgpr4WF9Z1qAbg4zAAIMU22Vmv0167.jpg
│   │   │   ├── Cgpr4WF9Z1qAD-1kAALCR9qk6tY282.jpg
│   │   │   ├── Cgpr4WF9Z1qAGT_9AAM88j2xb3c943.jpg
│   │   │   ├── Cgpr4WF9Z1qAJcPTAAEti0emwI8838.jpg
│   │   │   ├── Cgpr4WF9Z1qAPuRNAAC5TGFpmYc275.jpg
│   │   │   └── Cgpr4WF9Z1qAXV3hAAHgDlFbt0w747.jpg
...................................................
│   ├── storage_stat.dat # 当前storage server统计信息  
│   └── sync # 存放数据同步相关文件
│   ├── 10.10.107.226_23000.mark # 存放各个节点间同步的完成情况 
│   ├── binlog.000 # 当前的binlog文件索引号(类似于MySQL)
│   └── binlog_index.dat # 存放更新操作记录(日志)
└── logs
└── storaged.log # storaged 运行日志文件,默认级别 info、

Tips: 线上环境千万不要使用 kill -9 命令强杀 FastDFS 进程,否则可能会导致 binlog 数据丢失。

Tips: 针对于data/sync/10.10.107.226_23000.mark文件内同步情况进行查看,下面对其参数进行解析:

1
2
3
4
5
6
7
binlog_index=0      //binlog索引id
binlog_offset=3173 //当前时间binlog 大小
need_sync_old=0 //是否需要同步老数据
sync_old_done=0 //是否同步完成
until_timestamp=0 //时间戳单元
scan_row_count=97 //扫描记录数
sync_row_count=52 //同步记录数

至此已经搭起了一个简单的集群模式,其中上面的配置需要根据实际情况进行调整。


2.Docker 安装

Hub仓库fastDFS相关镜像

操作流程:

1
2
3
4
5
6
7
8
9
10
# docker 搜索相关镜像
docker search fastdfs
# 拉取delron/fastdfs
docker pull delron/fastdfs
# 查看拉取的镜像镜像
docker images
#使用docker镜像构建tracker容器(跟踪服务器,起到调度的作用)
docker run -d --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
# 使用docker镜像构建storage容器(存储服务器,提供容量和备份服务)
docker run -d --network=host --name storage -e TRACKER_SERVER=ip:22122 -v /var/fdfs/storage:/var/fdfs -e GROUP_NAME=group1 delron/fastdfs storage

我们再来复习一哈FastDFS原理,此处tracker和storage我们使用docker进行安装部署。

WeiyiGeek.FastDFS原理图

WeiyiGeek.FastDFS原理图


自定义FastDFS基础镜像

描述: 我们可以自定义FastDFS基础镜像并将其运行起来。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# centos 7
FROM centos:7
# 添加配置文件
# add profiles
ADD conf/client.conf /etc/fdfs/
ADD conf/http.conf /etc/fdfs/
ADD conf/mime.types /etc/fdfs/
ADD conf/storage.conf /etc/fdfs/
ADD conf/tracker.conf /etc/fdfs/
ADD fastdfs.sh /home
ADD conf/nginx.conf /etc/fdfs/
ADD conf/mod_fastdfs.conf /etc/fdfs

# 添加源文件
# add source code
ADD source/libfastcommon.tar.gz /usr/local/src/
ADD source/fastdfs.tar.gz /usr/local/src/
ADD source/fastdfs-nginx-module.tar.gz /usr/local/src/
ADD source/nginx-1.15.4.tar.gz /usr/local/src/

# Run
RUN yum install git gcc gcc-c++ make automake autoconf libtool pcre pcre-devel zlib zlib-devel openssl-devel wget vim -y \
&& mkdir /home/dfs \
&& cd /usr/local/src/ \
&& cd libfastcommon/ \
&& ./make.sh && ./make.sh install \
&& cd ../ \
&& cd fastdfs/ \
&& ./make.sh && ./make.sh install \
&& cd ../ \
&& cd nginx-1.15.4/ \
&& ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ \
&& make && make install \
&& chmod +x /home/fastdfs.sh
# export config
VOLUME /etc/fdfs

EXPOSE 22122 23000 8888 80
ENTRYPOINT ["/home/fastdfs.sh"]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
FROM alpine:3.10

RUN set -x \
&& echo "http://mirrors.aliyun.com/alpine/latest-stable/main/" > /etc/apk/repositories \
&& echo "http://mirrors.aliyun.com/alpine/latest-stable/community/" >> /etc/apk/repositories \
&& apk update \
&& apk add --no-cache --virtual .build-deps gcc libc-dev make perl-dev openssl-dev pcre-dev zlib-dev git \
&& mkdir -p /usr/local/src \
&& cd /usr/local/src \
&& git clone https://github.com/happyfish100/libfastcommon.git --depth 1 \
&& git clone https://github.com/happyfish100/fastdfs.git --depth 1 \
&& git clone https://github.com/happyfish100/fastdfs-nginx-module.git --depth 1 \
&& wget http://nginx.org/download/nginx-1.15.4.tar.gz \
&& tar -xf nginx-1.15.4.tar.gz \
&& cd /usr/local/src/libfastcommon \
&& ./make.sh \
&& ./make.sh install \
&& cd /usr/local/src/fastdfs/ \
&& ./make.sh \
&& ./make.sh install \
&& cd /usr/local/src/nginx-1.15.4/ \
&& ./configure --add-module=/usr/local/src/fastdfs-nginx-module/src/ \
&& make && make install \
&& apk del .build-deps \
&& apk add --no-cache pcre-dev bash \
&& mkdir -p /home/dfs \
&& mv /usr/local/src/fastdfs/docker/dockerfile_network/fastdfs.sh /home \
&& mv /usr/local/src/fastdfs/docker/dockerfile_network/conf/* /etc/fdfs \
&& chmod +x /home/fastdfs.sh
# && rm -rf /usr/local/src*
VOLUME /home/dfs
EXPOSE 22122 23000 8888 8080
CMD ["/home/fastdfs.sh"]


Tips: 指定版本Alpine版本echo -e "https://mirrors.aliyun.com/alpine/v3.8/main" > /etc/apk/repositories仓库。