Django集成古老的分布式文件存储系统fastdfs,解决文件存储难问题

前言

这几年一直在it行业里摸爬滚打,一路走来,不少总结了一些python行业里的高频面试,看到大部分初入行的新鲜血液,还在为各样的面试题答案或收录有各种困难问题

于是乎,我自己开发了一款面试宝典,希望能帮到大家,也希望有更多的Python新人真正加入从事到这个行业里,让python火不只是停留在广告上。

微信小程序搜索:Python面试宝典

或可关注原创个人博客:https://lienze.tech

也可关注微信公众号,不定时发送各类有趣猎奇的技术文章:Python编程学习

FDFS

什么是Fastdfs

FastDFS是一个开源的轻量级分布式文件系统,它对文件进行管理,功能包括:文件存储文件同步文件访问(文件上传、文件下载)等,解决了大容量存储和负载均衡的问题。特别适合以文件为载体的在线服务,如相册网站、视频网站等等

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


FastDFS架构包括 Tracker serverStorage server

客户端请求Trackerserver进行过文件上传、下载

通过Tracker server调度最终由Storage server完成文件上传、下载


Tracker server

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

Storage server

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

安装FDFS

  • 采用docker的方式进行安装,便捷简单
sudo docker image pull delron/fastdfs

启动Tracker&Storage

  • 开启fastdfstracker服务
docker run -dti --network=host --name tracker -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
  • 开启fastdfsstorage服务
docker run -dti --network=host --name storage -e TRACKER_SERVER=123.57.61.168:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage

配置FDFS

  • 下载安装fastdfs的python客户端:https://github.com/JaceHo/fdfs_client-py>

Windows兼容问题

解压下载好的压缩包,提取fdfs_client文件夹

将该文件夹放入python的三方包目录下

C:\Python37\Lib\site-packages

  • 安装所需的两个额外模块
pip install mutagen 
pip install requests 
  • 注释fdfs_client/storage_client.py文件中的第十二行
#from fdfs_client.sendfile import *
  • 创建client.conf文件到django下
# project/client.conf
# 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=\static #FastDFS客户端存放日志文件的目录

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=123.57.61.168:22122 #运行tracker服务的机器IP地址

#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
  • 上传测试代码
#client.upload_by_filename(文件名)
#client.upload_by_buffer(文件bytes数据)
from fdfs_client.client import Fdfs_client
client = Fdfs_client("client.conf")

ret = client.upload_by_filename('1.jpg')
print(ret)

其中返回结果中的Remote file_id就是上传成功的保存文件名

{
	'Group name': 'group1', 
	'Remote file_id': 'group1\\M00/00/00/rBEUWlz_HzSAPPzBAAQ2UAPajsU035.jpg', 
	'Status': 'Upload successed.', 
	'Local file name': '1.jpg', 
	'Uploaded size': '269.00KB', 
	'Storage IP': '123.57.61.168\x008'
}

集成文件引擎

  • 重构django文件上传引擎

存储类中必须实现_open()和_save()方法,以及任何后续使用中可能用到的其他方法。

  • _open(name, mode = ‘rb’):被Storage.open()调用,在打开文件时被调用
  • save(name, content):被Storage.save()调用,name是传入的文件名,content是Django接收到的文件内容,该方法需要将content文件内容保存。Django会将该方法的返回值保存到数据库中对应的文件字段,也就是说该方法应该返回要保存在数据库中的文件名信息。
  • exists(name):如果名为name的文件在文件系统中存在,按返回True,否则返回Flase
  • url(name):返回文件的完整访问URL
  • delete(name):删除name文件
  • listdir(path):列出指定路径的文件
  • size(name):返回name文件的总大小
from django.conf import settings
from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
class FastDFSStroage(Storage):
    """定义FastDFS客户端类"""
    def __init__(self, base_url = None, client_conf = None):
        """
        初始化对象
        :param base_url:
        :param client_conf:
        """
        if base_url is None:
            base_url = settings.FDAS_URL
            # 'http://123.57.61.168:8888' 
        self.base_url = base_url

        if client_conf is None:
            client_conf = settings.FDFS_CLIENT_CONF
            # FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'client.conf')
        self.client_conf = client_conf

    def _open(self, name, mode = 'rb'):
        """
        打开文件
        :param name:
        :param mode:
        :return:
        """
        pass

    def _save(self, name, content):
        """
        保存文件
        :param name: 传入文件名
        :param content: 文件内容
        :return:保存到数据库中的FastDFSDE文件名
        """
        client = Fdfs_client(self.client_conf)
        ret = client.upload_by_buffer(content.read())
        if ret.get("Status") != "Upload successed.":
            raise Exception("upload file failed")
        file_name = ret.get("Remote file_id")
        return file_name
    
    def exists(self, name):
        """
        检查文件是否重复, FastDFS自动区分重复文件
        :param name:
        :return:
        """
        return False

    def url(self, name):
        """
        获取name文件的完整url
        :param name:
        :return:
        """
        return self.base_url + name
  • 将文件引擎设置到settings中
#settings.py
DEFAULT_FILE_STORAGE = 'goods.views.FastDFSStorage'
  • 上传成功后的访问地址

在服务器IP地址的8888端口,记得打开对应阿里云的端口规则

  • 注意:在新版本的Remote file_id,由\\斜杠变为了/
['Remote file_id'].replace('\\','/')
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

李恩泽的技术博客

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值