FastDFS 分布式文件系统

什么是FastDFS

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

美女.png

FastDFS 架构包括两个部分:

Tracker server:作用是负载均衡和调度,通过 Tracker server 在文件上传时可以根据一些 策略找到 Storage server 提供文件上传服务。可以将 tracker 称为追踪服务器调度服务器

Storage server:作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上,客户端上传的文件最终存储在 Storage 服务器上, Storageserver 没有实现自己的文件系统而是利用操作系统 的文件系统来管理文件。可以将 storage 称为存储服务器

文件上传流程

FDFS.png

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

文件ID就像这样:group1/M00/00/00/wKjKh1uGr16AWpRfAAC20R6ytQc507.jpg

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

使用Docker安装FastDFS

1.安装

可以直接下载这个FDFS的镜像备份文件

FDFS的镜像链接: https://pan.baidu.com/s/1N3GWvujrYo0Yqhi4xhw5TQ 密码: 1yjg

下载好了之后,使用 docker 来加载,前提是你的系统里装了docker

1
docker load -i 文件路径/fastdfs_docker.tar

或者直接拉国外的镜像

1
docker image pull delron/fastdfs

2.运行tracker

执行如下命令开启tracker 服务

1
2
# 这里是将fastDFS tracker运行目录映射到本机的 /var/fdfs/tracker目录中。
docker run -dti --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker

3.运行storage

执行如下命令开启storage服务

1
docker run -dti --network=host --name storage -e TRACKER_SERVER=192.168.202.135:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage
  • TRACKER_SERVER=本机的ip地址:22122 ,需要更改为你的ip地址。本机ip地址不要使用127.0.0.1

注意:如果无法重新运行,可以删除/var/fdfs/storage/data目录下的fdfs_storaged.pid 文件,然后重新运行storage。

使用 FastDFS 的 Python 客户端

python版本的FastDFS客户端使用说明参考https://github.com/jefforeilly/fdfs_client-py

1.安装python版本的客户端

1
2
3
pip install fdfs_client-py-master.zip  
pip install mutagen
pip install requests

fdfs_client-py-master 也可以下载下面这个来安装

链接: https://pan.baidu.com/s/15NbswzD9H8EzCBXUgRYQ2Q 密码: 9w5u

2.修改客户端的配置

配置文件client.conf: 链接: https://pan.baidu.com/s/1AcR5vrJ2eudXsfSFbE28GQ 密码: 4sjc

1
2
base_path=FastDFS客户端存放日志文件的目录
tracker_server=运行tracker服务的机器ip:22122

3.使用

1
2
3
4
5
6
7
8
9
from fdfs_client.client import Fdfs_client

# 上传文件需要先创建fdfs_client.client.Fdfs_client的对象,并指明配置文件
client = Fdfs_client('client.conf文件的路径')

# 上传
client.upload_by_filename(文件名)
# 或
client.upload_by_buffer(文件bytes数据)

上传到storage后返回的结果如下例子:

1
2
3
4
5
6
7
8
{
'Group name': 'group1', # 组名
'Local file name': '/home/python/Desktop/avatar.jpg', # 本地路径
'Uploaded size': '45.00KB', # 上传大小
'Remote file_id': 'group1/M00/00/00/wKjKh1uGr16AWpRfAAC20R6ytQc507.jpg', # file_id
'Storage IP': '192.168.202.135', # Storage服务器所在的ip地址
'Status': 'Upload successed.' # 上传状态
}

Django项目使用FDFS来自定义文件存储系统

Django自带文件存储系统,使用的类:FileSystemStorage ,继承至django.core.files.storage.Storage

但是默认文件存储在本地,在本项目中,我们需要将文件保存到FastDFS服务器上,所以需要自定义文件存储系统,同样需要继承至 Storage 类, 并重写有用到的相关方法,其他方法可以看一下源代码

自定义FDFS存储类

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
from django.core.files.storage import Storage
from django.conf import settings
from fdfs_client.client import Fdfs_client
from django.utils.deconstruct import deconstructible

@deconstructible
class FDFSStorage(Storage):
"""FDFS文件存储类"""
# 支持Django不带任何参数来实例化存储类,也就是说任何设置都应该从django.conf.settings中获取
def __init__(self,base_url=None,client_conf=None):
"""
初始化
:param base_url: 用于构造图片完整路径使用,图片服务器的域名
:param client_conf: FastDFS客户端配置文件的路径
"""
if base_url is None:
base_url = settings.FDFS_URL

self.base_url = base_url

if client_conf is None:
client_conf = settings.FDFS_CLIENT_CONF

self.client_conf = client_conf

def _save(self, name, content):
"""
被Storage.save()调用
:param name: 用户选择上传文件的名称: 1.jpg
:param content: 包含上传文件内容的File对象,通过content.read()获取内容
:return: 'Remote file_id': 'group1/M00/00/00/wKjKh1uGr16AWpRfAAC20R6ytQc507.jpg'
"""
# 创建Fdfs客户端对象
client = Fdfs_client(self.client_conf)
# 使用文件bytes数据上传
res = client.upload_by_buffer(content.read())

# 判断上传是否成功
if res.get('Status') != 'Upload successed.':
raise Exception('上传文件到FDFS系统失败')

# 上传成功,获取文件id
file_id = res.get('Remote file_id')

return file_id

def exists(self, name):
"""
判断用户上传文件的名字和文件存储系统已有的文件是否有冲突
:param name: 用户选择上传文件的名字:1.jpg
:return: Flase
"""
return False

def url(self, name):
"""
返回可访问到文件的完整url地址
:param name: storage中为上传文件自动生成的名字-->'Remote file_id'
:return:
"""
return self.base_url + name

在Django配置中设置自定义文件存储类

在django项目配置文件中添加设置

1
2
3
4
5
6
# django文件存储
DEFAULT_FILE_STORAGE = 'FDFS文件存储类的路径'

# FastDFS
FDFS_URL = 'http://image.aaa.site:8888/' # 指定访问 FDFS服务器 的 host & port
FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'utils/fastdfs/client.conf') # 拼接client.conf文件的路径

添加域名

在/etc/hosts中添加访问FastDFS storage服务器的域名

1
127.0.0.1   image.aaa.site
------ 本文结束------
坚持原创技术分享,您的支持将鼓励我继续创作!
0%