分布式文件系统-FastDFS(附使用实例)

共计 4093 个字符,预计需要花费 11 分钟才能阅读完成。

什么是FastDFS

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

FastDFS 架构包括两个部分:

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

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

文件上传流程

分布式文件系统-FastDFS(附使用实例)

客户端上传文件后存储服务器将文件 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

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

或者直接拉国外的镜像

docker image pull delron/fastdfs

2.运行tracker

执行如下命令开启tracker 服务

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

3.运行storage

执行如下命令开启storage服务

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版本的客户端

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

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

3.使用

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后返回的结果如下例子:

{
    '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存储类

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项目配置文件中添加设置

# 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服务器的域名

127.0.0.1   image.aaa.site
正文完
 
Dustin
版权声明:本站原创文章,由 Dustin 2019-10-14发表,共计4093字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。