FastDFS_分布式文件系统&python与fastdfs交互

一、FastDFS简介

FastDFS是一款用C语言实现的开源的轻量级分布式文件系统,功能主要包括:文件存储、文件同步、文件访问(文件上传、文件下载)等,支持Linux、FreeBSD、MacOS等类UNIX系统。

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

FastDFS属于应用级文件系统,不是通用的文件系统,只能通过专有API访问,目前提供了C、Java和PHP API为互联网应用量身定做,解决大容量文件存储问题,追求高性能和高扩展性FastDFS可以看做是基于文件的key value pair存储系统,称作分布式文件存储服务更为合适。

FastDFS特性

  • 分组存储,简单灵活
  • 对等结构,不存在单点
  • 文件ID由FastDFS生成,作为文件访问凭证。FastDFS不需要传统的name server或meta server
  • 大、中、小文件均可以很好支持,可以存储海量小文件
  • 一台storage支持多块磁盘,支持单盘数据恢复
  • 提供了nginx扩展模块,可以和nginx无缝衔接
  • 支持多线程方式上传和下载文件,支持断点续传
  • 存储服务器上可以保存文件附加属性。

二、FastDFS架构说明

FastDFS系统由跟踪服务器(Tracker server)、存储服务器(Storage server)和客户端(Client)构成。

 

2.1 跟踪服务器(Tracker server)

Tracker server 主要做调度工作,起负载均衡的作用。在内存中记录集群中所有存储组和存储服务器的状态信息,但不记录文件索引信息,占用的内存量很少,是客户端和数据服务器交互的枢纽。

Tracker是FastDFS的协调者,负责管理所有的Storage server和group,每个Storage在启动后会连接Tracker,同步自己所属的group等信息,并保持周期性的心跳,tracker根据storage的心跳信息,建立group==>[storage server list]的映射表。

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

2.2 存储服务器(Storage server)

Storage server 主要提供容量和备份服务,文件和文件属性(Meta Data)都保存到存储服务器上,Storage server直接利用OS的文件系统调用管理文件。
Storage server(后简称storage)以组(卷,group或volume)为单位组织,一个group内包含多台storage机器,数据互为备份,存储空间以group内容量最小的storage为准,所以建议group内的多个storage尽量配置相同,以免造成存储空间的浪费。
以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的方式被路由到其中某个子目录下,然后将文件数据直接作为一个本地文件存储到该目录中。

2.3 客户端(Client)

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

2.4 上传流程

首先Clinet客户端请求Tracker服务获取到存储服务器的ip地址和端口,然后客户端根据返回的IP地址和端口号请求上传文件,存储服务器接收到请求后生产文件,并且将文件内容写入磁盘并返回给客户端file_id、路径信息、文件名等信息,客户端保存相关信息上传完毕。

内部机制如下:

1、选择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优先

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、生成文件名

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

2.5 下载机制

客户端带上文件名信息请求Tracker服务获取到存储服务器的ip地址和端口,然后客户端根据返回的IP地址和端口号请求下载文件,存储服务器接收到请求后返回文件给客户端。

跟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. (当前时间-文件创建时间戳) > 同步延迟阀值(如一天)。 - 经过同步延迟阈值时间,认为文件肯定已经同步了。

2.6 FastDFS的FID

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

三、部署FastDFS

3.1 环境准备

2台linux7服务器:192.168.3.66/67
安装包:libfastcommon-master.zipfastdfs-master.zipnginx-1.8.1.tar.gzfastdfs-nginx-module-master.zip。安装包下载地址
服务器规划:tracker服务器:192.168.3.67 storage服务器:192.168.3.66

3.2 安装Fastdfs(所有服务器)

安装FastDFS和Nginx之前,需确保gcc、gcc-c++、 libstdc++-devel、make等依赖库和工具已经安装

安装libfastcommon类库

安装FastDFS必须先安装libfastcommon类库,否则会导致报错,安装步骤如下:

unzip libfastcommon-master.zip
cd libfastcommon-master
./make.sh
./make.sh install

安装FastDFS

unzip fastdfs-master.zip
cd fastdfs-master
./make.sh
./make.sh install

FastDFS安装好之后,在/usr/bin目录下,可以看fdfs开头的命令工具

所有配置文件全在/etc/fdfs目录下,tracker需要tracker.conf配置文件,storage需要storage.conf配置文件。

3.3 配置tracker(192.168.3.67)

创建存储数据和日志的目录
mkdir -p /usr/local/fastdfs/tracker

将/etc/fdfs/tracker.conf.sample文件重命名为tracker.conf

cd /etc/fdfs
cp tracker.conf.sample tracker.conf

然后修改配置文件/etc/fdfs/tracker.conf

vi tracker.conf
base_path=/usr/local/fastdfs/tracker

配置文件中有这几个参数需要注意:

#启用配置文件
disabled=false
#设置tracker的端口号
port=22122
#设置tracker的数据文件和日志目录(需手动创建)
base_path=/usr/local/fastdfs/tracker
#设置http端口号,默认8080
http.server_port=8080

启动tracker服务

service fdfs_trackerd start

查看端口22122是否开始监听,确认启动是否成功

也可以查看tracker的日志是否启动成功

cat /usr/local/fastdfs/tracker/logs/trackerd.log

至此,一个简单的的tracker配置就完成了,Tracker也成功启动~

如果tracker和storage部署在不同的服务器上,防火墙还需要开放22122端口

否则后面启动storage时,会报错: connect to tracker server 192.168.3.67:22122 fail, errno: 113, error info: No route to host

3.4 配置storage(192.168.3.66)

创建存储数据和日志的目录
mkdir -p /usr/local/fastdfs/storage

将/etc/fdfs/tracker.conf.sample文件重命名为tracker.conf

cd /etc/fdfs
cp storage.conf.sample storage.conf

然后修改配置文件/etc/fdfs/storage.conf的base_path,store_path以及tracker的连接地址以及storage的http服务端口配置等。

主要有如下几个参数:

vi /etc/fdfs/storage.conf

group_name=group1  # 组名(第一组为group1,第二组为group2,依次类推...),主要时在组集群时区分storage组
base_path=/usr/local/fastdfs/storage   # 数据和日志文件存储根目录
store_path0=/usr/local/fastdfs/storage  # 第一个存储目录,第二个存储目录起名为:store_path1=xxx,其它存储目录名依次类推... 
store_path_count=1 # 存储路径个数,需要和store_path个数匹配 
tracker_server=192.168.66.67:22122 # tracker服务器IP和端口 
tracker_server=192.168.66.xx:22122 # 如果是tracker集群就写多个tracker配置

启动storage服务

service fdfs_storaged start

查看端口或日志验证是否启动成功

在任意storage节点使用fdfs_monitor /etc/fdfs/storage.conf,查看storage服务器是否已经登记到tracker服务器。

如果出现ip_addr = Active, 则表明storage服务器已经登记到tracker服务器,如下:

防火墙开放23000端口

否则上传文件时会提示

至此,tracker、storage等配置都完成并成功启动

3.5 在storage上安装nginx

 注意:fastdfs-nginx-module模块只需要安装到storage上

 在/usr/local/目录下解压 nginx-1.8.1.tar.gz 和 fastdfs-nginx-module-master.zip

cd /usr/local
tar -zxvf nginx-1.8.1.tar.gz
unzip fastdfs-nginx-module-master.zip

安装nginx

cd nginx-1.8.1
./configure --prefix=/usr/local/nginx --add-module=/usr/local/fastdfs-nginx-module-master/src/    # 注意:--add-module的路径
make
make install

注意:如果make时报错 [objs/Makefile:469: objs/src/core/ngx_murmurhash.o] Error ,打开./nginx-1.8.1/objs/Makefile文件,删除-Werror,重新执行make后的步骤即可。

安装成功,查看版本信息

/usr/local/nginx/sbin/nginx -V

配置fastdfs-nginx-module

进入fastdfs-nginx-module-master的src目录,将md_fastdfs.conf配置文件拷贝到/etc/fdfs/目录中

cd /usr/local/fastdfs-nginx-module-master/src/
cp mod_fastdfs.conf /etc/fdfs/

修改/etc/fdfs/mod_fastdfs.conf配置一般只需改动以下几个参数即可:

base_path=/usr/local/fastdfs/storage   #保存日志目录
tracker_server=192.168.3.67:22122  # tracker服务ip和端口
tracker_server=192.168.3.xx:22122  # 如果有多个tracker就配置多个
storage_server_port=23000 #storage服务器的端口号
group_name=group1 #当前服务器的group名
url_have_group_name=true #文件url中是否有group名 
store_path_count=1 #存储路径个数,需要和store_path个数匹配 
store_path0=/usr/local/fastdfs/storage #存储路径 
group_count=1 #组数

在末尾增加组的具体信息

[group1]
group_name=group1
storage_server_port=23000
store_path_count=1
store_path0=/usr/local/fastdfs/storage

建立M00至存储目录的符号连接

ln -s /usr/local/fastdfs/storage/data /usr/local/fastdfs/storage/data/M00

配置nginx

编辑/usr/local/nginx/conf配置文件目录下的nginx.conf,设置添加storage信息并保存。

vi /usr/local/nginx/conf/nginx.conf

将server段中的listen端口号改为8080,并在server段中添加:

location ~/group[0-9]/M00{
    root /usr/local/fastdfs/storage/data;
    ngx_fastdfs_module; 
}

防火墙开放8080端口

复制 fastdfs-master解压文件目录中的conf下http.conf、mime.types文件到/etc/fdfs

至此,nginx以及FastDFS插件模块设置完成。

启动nginx

启动nginx,查看8080是否开始监听确认启动是否成功。

/usr/local/nginx/sbin/nginx

打开浏览器,直接访问http://192.168.3.66:8080,查看是否弹出nginx欢迎页面。

3.6 在tracker上安装nginx

在tracker上安装的nginx主要为了提供http访问的反向代理、负载均衡以及缓存服务。

在/usr/local/目录下解压 nginx-1.8.1.tar.gz

cd /usr/local
tar -zxvf nginx-1.8.1.tar.gz

安装nginx

cd nginx-1.8.1
./configure --prefix=/usr/local/nginx
make
make install

配置

编辑/usr/local/nginx/conf配置文件目录下的nginx.conf,设置负载均衡

vi /usr/local/nginx/conf/nginx.conf

修改下面配置

worker_processes  4;                  #根据CPU核心数而定
events {
  worker_connections  65535;        #最大链接数
  use epoll;                        #新版本的Linux可使用epoll加快处理性能
}
http {
    #设置group1的服务器
  upstream fdfs_group1 {
     # ip和port填写storage上部署的nginx信息
     server 192.168.3.66:8080 weight=1 max_fails=2 fail_timeout=30s;
   }
  server {
    #设置服务器端口
       listen       8080;
       #设置group1的负载均衡参数
       location ~/group[0-9]/M00 {
            proxy_pass http://fdfs_group1;
       }
  }
}   

防火墙开放8080端口

至此,nginx设置完成。

启动nginx

启动nginx,查看8080是否开始监听确认启动是否成功。

/usr/local/nginx/sbin/nginx

打开浏览器,直接访问http://192.168.3.67:8080,查看是否弹出nginx欢迎页面。

3.7 上传图片并在浏览器查看图片

在tracker服务器上将/etc/fdfs/client.conf.sample文件重命名为client.conf

cd /etc/fdfs
cp client.conf.sample client.conf

然后修改配置文件/etc/fdfs/client.conf

vi client.conf

base_path=/usr/local/fastdfs/tracker
tracker_server=192.168.3.67:22122  # tracker服务器ip和port
http.tracker_server_port=8080  # 默认80,需修改为tracker.conf配置文件中http.server_port的值

上传文件测试

fdfs_upload_file /etc/fdfs/client.conf 文件名称

如果返回类似group1/M00/00/00/wKgDQmKOQJqAafJFAADOnyAS7QE843.jpg的文件id则说明文件上传成功

因为tracker的nginx配置了反向代理,使用storage的ip或tracker的ip都可以在浏览器访问图片。

http://192.168.3.66:8080/group1/M00/00/00/wKgDQmKOQJqAafJFAADOnyAS7QE843.jpg

四、使用python上传图片

安装FastDFS的python模块

pip install fdfs-client-py3

创建fdfs_tracker.conf配置文件,添加tracker配置项

connect_timeout=30
network_timeout=60
tracker_server = 192.168.3.67:22122 # tracker节点的ip和port
http.tracker_server_port = 8080     # tracker服务器上部署的nginx的端口

代码如下

from fdfs_client.client import Fdfs_client

tracker_conf_path = "./fdfs_tracker.conf"   # tracker配置文件的地址
client = Fdfs_client(client=tracker_conf_path)
# 上传图片
ret = client.upload_by_filename("./20191023111957.png")
print(ret)

# 删除图片
file_id = ret["Remote file_id"]     # 删除图片需要上传时返回的id
ret = client.delete_file(remote_file_id=file_id.encode("utf-8"))
print(ret)

执行结果如下

 

posted @ 2022-05-23 21:56  码上测  阅读(780)  评论(0编辑  收藏  举报