首页 网站导航 回忆录 留言板 关于
悬浮目录

· item.c ·

22
0
一个分享py的博主 2022年11月15日

自定义文件存储FDFS

浏览量(408) 评论量(0) 点赞量(22)

文件存储方案FastDFS

FastDFS介绍和工作流程

用c语言编写的一款开源的轻量级分布式文件系统。 功能包括:文件存储、文件访问(文件上传、文件下载)、文件同步等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等。 为互联网量身定制,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标。 可以帮助我们搭建一套高性能的文件服务器集群,并提供文件上传、下载等服务。

FastDFS文件索引

  • 文件索引(file_id)是客户端上传文件后Storage返回给客户端的一个字符串,是以后访问该文件的索引信息。

  • 文件索引(file_id)信息包括:组名、虚拟磁盘路径、数据两级目录、文件名等信息。

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

容器化方案docker

FastDFS的安装步骤非常的多,涉及的依赖包也很多,当新的机器需要安装FastDFS时,需要从头开始安装,所有我们这里采用docker安装

1.获取FastDFS镜像
# 从仓库拉取镜像
sudo docker image pull delron/fastdfs
2.开启tracker容器
  • 我们将 tracker 运行目录映射到宿主机的 /var/fdfs/tracker目录中。
sudo docker run -dit --name tracker --network=host -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
3.开启storage容器
  • TRACKER_SERVER=Tracker的ip地址:22122(Tracker的ip地址不要使用127.0.0.1)
  • 我们将 storage 运行目录映射到宿主机的 /var/fdfs/storage目录中。
sudo docker run -dti --name storage --network=host -e TRACKER_SERVER=192.168.103.158:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage
4.修改storage服务器端口号(默认是8888)
#进入storage容器,到storage的配置文件中配置http访问的端口,配置文件在/etc/fdfs目录下的storage.conf。
docker exec -it  storage或容器id bash 
vi /etc/fdfs/storage.conf

5.http.server_port=8888如果修改,这里也要修改,否则可不修改

进入storage,配置nginx,在/usr/local/nginx目录下,修改nginx.conf文件

docker exec -it  storage容器id bash 
vi /usr/local/nginx/nginx.conf

FastDFS客户端上传文件

1.安装FastDFS客户端扩展

  • 安装准备好fdfs_client-py到虚拟环境中
$ pip install fdfs_client-py
$ pip install mutagen
$ pip isntall requests

2.准备FastDFS客户端扩展的配置文件

# connect timeout in seconds
# default value is 30s
connect_timeout=30

# network timeout in seconds
# default value is 30s
network_timeout=60

# the base path to store log files
base_path=/Users/gax/Desktop

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=你的服务器ip:22122

#standard log level as syslog, case insensitive, value list:
### emerg for emergency
### alert
### crit for critical
### error
### warn for warning
### notice
### info
### debug
log_level=info

# if use connection pool
# default value is false
# since V4.05
use_connection_pool = false

# connections whose the idle time exceeds this time will be closed
# unit: second
# default value is 3600
# since V4.05
connection_pool_max_idle_time = 3600

# if load FastDFS parameters from tracker server
# since V4.05
# default value is false
load_fdfs_parameters_from_tracker=false

# if use storage ID instead of IP address
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# default value is false
# since V4.05
use_storage_id = false

# specify storage ids filename, can use relative or absolute path
# same as tracker.conf
# valid only when load_fdfs_parameters_from_tracker is false
# since V4.05
storage_ids_filename = storage_ids.conf

#HTTP settings
http.tracker_server_port=80

#use "#include" directive to include HTTP other settiongs
##include http.conf

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

3.FastDFS客户端实现文件存储

# 使用 shell 进入 Python交互环境
$ python manage.py shell
# 1. 导入FastDFS客户端扩展
from fdfs_client.client import Fdfs_client
# 2. 创建FastDFS客户端实例
client = Fdfs_client('meiduo_mall/utils/fastdfs/client.conf')
# 3. 调用FastDFS客户端上传文件方法
ret = client.upload_by_filename('/Users/zhangjie/Desktop/kk.jpeg')
ret = {
'Group name': 'group1',
'Remote file_id': 'group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg',
'Status': 'Upload successed.',
'Local file name': '/Users/zhangjie/Desktop/kk.jpeg',
'Uploaded size': '69.00KB',
'Storage IP': '192.168.103.158'
 }
ret = {
'Group name': 'Storage组名',
'Remote file_id': '文件索引,可用于下载',
'Status': '文件上传结果反馈',
'Local file name': '上传文件全路径',
'Uploaded size': '文件大小',
'Storage IP': 'Storage地址'
 }

浏览器下载并渲染图片

  • 协议:

    • http
  • IP地址:

    192.168.103.158

    • Nginx服务器的IP地址。
    • 因为 FastDFS 擅长存储静态文件,但是不擅长提供静态文件的下载服务,所以我们一般会将 Nginx 服务器绑定到 Storage ,提升下载性能。
  • 端口:

    8888 #可以自己修改

    • Nginx服务器的端口。
  • 路径:

    group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg

    • 文件在Storage上的文件索引。
  • 完整图片下载地址

    • http://192.168.103.158:8888/group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg

自定义django的文件存储类将其修改为FDFS

# 指定自定义的Django文件存储类
DEFAULT_FILE_STORAGE = 'blog.utils.fastdfs.fdfs_storage.FastDFSStorage'
# 配置fastdfs图片服务器的地址
FDFS_URL = 'http://127.0.0.1:8888/'
# 配置fastdfs配置文件路径
FASTDFS_PATH = os.path.join(BASE_DIR, 'utils/fastdfs/client.conf')
# -*- coding: utf-8 -*-
# time: 2022/9/29 9:44
# file: model.py
# author: 201
from django.conf import settings
from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client


class FastDFSStorage(Storage):
    """FastDFS文件存储类"""

    def __init__(self, client_conf=None, nginx_url=None):
        self.client_conf = client_conf or settings.FDFS_CLIENT_CONF
        self.nginx_url = nginx_url or settings.NGINX_URL

    def _open(self, name, mode='rb'):
        """
        用于打开文件
        :param name: 要打开的文件的名字
        :param mode: 打开文件方式
        :return: None
        """
        # 打开文件时使用的,此时不需要,而文档告诉说明必须实现,所以pass
        pass

    def _save(self, name, content):
        """
        用于保存文件
        :param name: 要保存的文件名字
        :param content: 要保存的文件的内容
        :return: None
        """
        # 创建一个Fdfs_client对象, 需要client配置文件
        client = Fdfs_client(self.client_conf)

        # 上传文件到fastdfs系统中
        ret_dict = client.upload_by_buffer(content.read())
        # ret_dict返回的是一个字典,类型如下
        """
        {
            'Group name': 'group1',
            'Local file name': '02.png',
            'Remote file_id': 'group1/M00/00/00/wKgNgF9uzVuAd7JlAAS-_JN9ZAI299.png',
            'Status': 'Upload successed.',
            'Storage IP': '192.168.13.128',
            'Uploaded size': '303.00KB'
        }
        """
        if ret_dict.get("Status") != "Upload successed.":
            # 上传失败
            raise Exception("上传文件到fastdfs失败")

        # 获取返回的文件id
        file_id = ret_dict.get("Remote file_id")

        # 返回什么内容,最终在image属性对应的表中的字段保存的就是什么内容
        return file_id

    def url(self, name):
        """
        返回name所指文件的绝对URL
        :param name: 文件的id
        :return: 文件的url
        """
        # return 'http://ip:port/' + name
        return self.nginx_url + name

    def exists(self, name):
        """ Django判断文件名是否可用, 必须重写"""
        return False

好了现在我们就能使用fdfs来存文件了

你觉得文章怎么样:

0 人参与,0 条评论