django项目之集成FastDFS 分布式存储

一、准备可以联网的ubuntu系统或者是Centos系统至少一台

二、安装docker

  centos安装docker详见链接:https://www.cnblogs.com/shangguanruoling/p/11799597.html

  如下是关于ubuntu安装docker:

sudo apt-get update    #更新ubuntu的apt源索引

sudo dpkg --configure -a

sudo apt-get install apt-transport-https ca-certificates curl software-properties-common #安装包允许apt通过HTTPS使用仓库
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - # 添加Docker官方GPG key

sudo add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" #设置Docker稳定版仓库
sudo apt-get update #添加仓库后,更新ubuntu索引源
sudo apt-get install docker-ce #安装docker社区版
sudo docker search nginx #检查docker是否安装并启动

三、FastDFS 安装配置:

FastDFS 架构包括 Tracker serverStorage server。客户端请求 Tracker server 件上传、下载文 ,通过 Tracker server 调度最终由 Storage server 完成文件上传和下载。

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

  • Storage server 作用是文件存储,客户端上传的文件最终存储在 Storage 服务器上, Storage Serve利用操作系统 的文件系统来管理文件。可以将 storage 称为存储服务器

  1、再容器中安装配置FastDFS:

sudo docker search fastdfs    # 查找fastdfs镜像
sudo docker pull season/fastdfs #拉取镜像, 后面可以跟:1.2,这个版本是集成了nginx的,最新版的没用集成nginx
### 如果有下载好的镜像,可以直接导入, 使用如下的命令:
sudo docker load -i 文件路径/season_fastdfs.tar.gz

  2、运行tracker:

1、 查看fastdfs端口是否被占用:
sudo netstat -nlpt | grep 22122
2、创建一个tracker的运行目录:
cd /data01/fastdfs/
mkdir ./tracker_data/
3、启动tracker容器
sudo docker run -itd --name tracker -v /data01/fastdfs/tracker_data:/fastdfs/tracker/data --net=host season/fastdfs tracker
  ### --net = host 指的是告诉 Docker 不要将容器网络放到隔离的名字空间中,此时容器使用的是本地的网络
4、如果想要停止,可以用:
sudo docker container stop tracker
5、如果想要重启已经停止的容器,可以用:
sudo docker container start tracker

  3、运行storage:

1、storage不能运行再127.0.0.1上
cd /data01/fastdfs/
mkdir ./storage_data/     # 创建storage 的运行目录
mkdir ./store_path/        # 创建storage的数据存储目录
2、启动storage:
sudo docker run -itd --network=host --name storage -v /data01/fastdfs/storage_data:/fastdfs/storage/data -v /data01/fastdfs/store_path:/fastdfs/store_path  -e TRACKER_SERVER:本机ip:22122 season/fastdfs storage

  4、调整配置

  指定storage服务器注册到trakcer服务器的ip地址是没有生效的,所以我们需要手动设置storage的配置文件

  进入storage容器下,将fdfs_conf目录下的storage.conf文件拷贝到当前用户家目录下

sudo docker cp storage:/fdfs_conf/storage.conf ~/

  编辑文件,找到tracker_server配置项,修改为本地IP地址

sudo vim storage.conf
:set nu          # 显示行号
:114             # 跳转到111行
tracker_server=192.168.252.133:22122

  将编辑好的文件再从本机拷贝到容器storage内部,重启storage和tracker即可

四、FastDFS 客户端:

pip install https://github.com/JaceHo/fdfs_client-py/archive/master.zip
pip install mutagen
pip install requests

  使用FastDFS客户端,需要有配置文件。我们在renranapi/utils目录下新建fastdfs目录,创建 客户端配置文件client.conf放到这个目录中。

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

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

# the base path to store log files
base_path=/home/moluo/Desktop/renran/renranapi/logs

# tracker_server can ocur more than once, and tracker_server format is
#  "host:port", host can be hostname or ip address
tracker_server=192.168.252.133: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

  上传文件需要先创建fdfs_client.client.Fdfs_client的对象,并指明配置文件,如

# 进入django的终端下测试  python manage.py shell
from fdfs_client.client import Fdfs_client
client = Fdfs_client('renranapi/utils/fastdfs/client.conf')

  client对象的操作方法文档:https://github.com/JaceHo/fdfs_client-py

五、自定义django文件存储系统

  学习Django框架的文件存储在本地,我们接下来需要将文件保存到FastDFS服务器上,所以需要自定义文件存储系统。

  官方文档说明,指出自定义文件存储系统的方法如下:

1)需要继承自django.core.files.storage.Storage,如

 

from django.core.files.storage import Storage

class FastDFSStorage(Storage):
    ...

2)支持Django不带任何参数来实例化存储类,也就是说任何设置都应该从django.conf.settings中获取

from django.conf import settings
from django.core.files.storage import Storage

class FasfDFSStorage(Storage):
    def __init__(self, base_url=None, client_conf=None):
        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

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

4)需要为存储类添加django.utils.deconstruct.deconstructible装饰器

  示例:

from django.core.files.storage import Storage
from fdfs_client.client import Fdfs_client
from django.conf import settings

import logging
logger = logging.getLogger("django")


class FastDFSStorage(Storage):
    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 _open(self, name=None):
        """打开文件"""
        pass

    def _save(self, name, content):
        """
        在FastDFS中保存文件
        :param name: 传入的文件名
        :param content: 文件内容
        :return: 保存到数据库中的FastDFS的文件名
        """
        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 url(self, name):
        """
        返回文件的完整URL路径
        :param name: 数据库中保存的文件名
        :return: 完整的URL
        """
        return self.base_url + name

    def exists(self, name):
        """
        判断文件是否存在,FastDFS可以自行解决文件的重名问题
        所以此处返回False,告诉Django上传的都是新文件
        :param name:  文件名
        :return: False
        """
        return False

    def delete(self, name):
        """

        :param name:  传入的文件名
        :return: 删除的文件名
        """
        client = Fdfs_client(self.client_conf)
        try:
            ret_delete = client.delete_file(name)
            return ret_delete
        except Exception as e:
            logger.warning(u'文件删除失败,错误信息:%s' % repr(e))
            return None
View Code

5)再django中配置自定义存储类

# django文件存储
DEFAULT_FILE_STORAGE = 'renranapi.utils.fastdfs.fdfs_storage.FastDFSStorage'

# FastDFS
FDFS_URL = 'http://本机ip:8888/'  # 访问图片的路径域名 ip地址修改为自己机器的ip地址
FDFS_CLIENT_CONF = os.path.join(BASE_DIR, 'utils/fastdfs/client.conf')
世间安得双全法,不负如来不负卿
原文地址:https://www.cnblogs.com/shangguanruoling/p/12186100.html