FastDFS分布式系统在Docker和Python中的应用

系统 1704 0

fastdfs分布式系统在docker和python中的应用

  • 一、什么是FastDFS:
    • 1.文件上传交互过程:
    • 2.文件下载交互过程:
  • 二、Docker安装FastDFS
    • 1.通过镜像下载
    • 2.将容器上的文件夹映射到本地路径,启动tracker和storage服务器
    • 3.查看tracker和storage服务器是否开启
  • 三、FastDFS的Python客户端
    • 1.下载环境包
    • 2.定义自己的配置文件
    • 3.上传文件例子
  • 四、自定义django文件存储并且保存到FDFS服务器上
    • 1.在刚才的fastdfs目录中建一个fdfs_client.py文件用来自定义文件管理
    • 2.在Django配置文件中设置自定义文件存储类
    • 3.配置系统路径
    • 4.测试上传以及文件服务器域名

一、什么是FastDFS:

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

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

1.文件上传交互过程:

  1. Storage server 定时向Tracker server 上传状态信息
  2. Client 向 Tracker server 发送连接请求
  3. Tracker server 查询可用的storage
  4. Tracker server 返回storage的IP和端口给Client
  5. Client 上传文件到Storage server
  6. Storage server 将文件写入磁盘,同时生成文件id
  7. Storage server 返回文件id(路径信息和文件名)给Client
  8. Client 存储文件信息

2.文件下载交互过程:

  1. Storage server 定时向Tracker server 上传状态信息
  2. Client 向 Tracker server 发送连接请求
  3. Tracker server 查询可用的storage
  4. Tracker server 返回storage的IP和端口给Client
  5. Client 发送文件id(路径信息和文件名)给 Storage server
  6. Storage server 根据信息进行查找文件
  7. Storage server 将文件返回给Client

二、Docker安装FastDFS

1.通过镜像下载

            
              sudo docker image pull delron
              
                /
              
              fastdfs

            
          

2.将容器上的文件夹映射到本地路径,启动tracker和storage服务器

            
              sudo docker run 
              
                -
              
              dit 
              
                -
              
              
                -
              
              network
              
                =
              
              host 
              
                -
              
              
                -
              
              name
              
                =
              
              tracker 
              
                -
              
              v 
              
                /
              
              var
              
                /
              
              fdfs
              
                /
              
              tracker
              
                :
              
              
                /
              
              var
              
                /
              
              fdfs delron
              
                /
              
              fastdfs tracker

            
          
            
              sudo docker run 
              
                -
              
              dit 
              
                -
              
              
                -
              
              network
              
                =
              
              host 
              
                -
              
              
                -
              
              name
              
                =
              
              storage 
              
                -
              
              e TRACKER_SERVER
              
                =
              
              
                192.168
              
              
                .149
              
              
                .129
              
              
                :
              
              
                22122
              
              
                -
              
              v 
              
                /
              
              var
              
                /
              
              fdfs
              
                /
              
              storage
              
                :
              
              
                /
              
              var
              
                /
              
              fdfs delron
              
                /
              
              fastdfs storage

            
          

注意:storage服务器需要指定tracker调度服务器的地址和端口,端口默认是22122

3.查看tracker和storage服务器是否开启

            
              sudo docker ps

            
          

效果图:
在这里插入图片描述

如果俩个都有,那就代表都已经开启了。如果没有可以使用下面指令开启

            
              sudo docker container start 容器名

            
          

如果输入上面的开启代码,但是容器还是没有开启,就执行下面的操作:

            
              cd 
              
                /
              
              var
              
                /
              
              fdfs
              
                /
              
              storage
              
                /
              
              data
              
                /
              
              
sudo rm 
              
                -
              
              rf fdfs_storaged
              
                .
              
              pid

            
          

然后在使用start指令重新启动容器
效果图:

FastDFS分布式系统在Docker和Python中的应用_第1张图片

三、FastDFS的Python客户端

1.下载环境包

先在GitHub下载:https://github.com/JaceHo/fdfs_client-py 然后在自己对应的环境安装。

            
              pip install fdfs_client
              
                -
              
              py
              
                -
              
              master
              
                .
              
              
                zip
              
              
pip install mutagen
pip isntall requests

            
          

2.定义自己的配置文件

使用FastDFS 客户端,需要有配置文件,在项目目录下创建fastdfs文件夹,然后在里面创建一个client.conf配置文件,主要修改tracker_server 和base_path:

            
              
                # 连接超时时间 默认30秒
              
              
connect_timeout
              
                =
              
              
                30
              
              
                # 网络超时时间
              
              
                # default value is 30s
              
              
network_timeout
              
                =
              
              
                60
              
              
                # 工作文件夹,日志存在此
              
              
base_path
              
                =
              
              
                /
              
              home
              
                /
              
              hadoop
              
                /
              
              桌面
              
                /
              
              shanghui
              
                /
              
              shanghuishop
              
                /
              
              shanghuiproject
              
                /
              
              logs

              
                # tracer server列表,多个tracer server的话,分行列出
              
              
tracker_server
              
                =
              
              
                192.168
              
              
                .149
              
              
                .129
              
              
                :
              
              
                22122
              
              
                #日志级别
              
              
                ### emerg for emergency
              
              
                ### alert
              
              
                ### crit for critical
              
              
                ### error
              
              
                ### warn for warning
              
              
                ### notice
              
              
                ### info
              
              
                ### debug
              
              
log_level
              
                =
              
              info


              
                # 是否使用连接池
              
              
use_connection_pool 
              
                =
              
               false


              
                # 连接闲置超时时间,连接如果闲置的时间超过本配置,则关闭次连接,单位秒
              
              
connection_pool_max_idle_time 
              
                =
              
              
                3600
              
              
                # 是否从tracer server读取fastdfs的参数,默认为false
              
              
load_fdfs_parameters_from_tracker
              
                =
              
              false


              
                # 是否使用storage id 替换 ip,默认为false
              
              
                # 和tracker.conf该参数含义一样
              
              
                # 本配置只有在load_fdfs_parameters_from_tracker=false时生效
              
              
                # 本配置默认为false
              
              
use_storage_id 
              
                =
              
               false


              
                # 指定storage id的文件名,允许使用绝对路径
              
              
                # 和tracker.conf该参数含义一样
              
              
                # 本配置只有在load_fdfs_parameters_from_tracker=false时生效
              
              
storage_ids_filename 
              
                =
              
               storage_ids
              
                .
              
              conf


              
                #HTTP settings
              
              
                #http.tracker_server_port=8080
              
              
                #引入HTTP相关配置
              
              
                ##include http.conf
              
            
          

3.上传文件例子

            
              
                from
              
               fdfs_client
              
                .
              
              client 
              
                import
              
               Fdfs_client


              
                # 下面参数为client.conf的文件地址
              
              
client 
              
                =
              
               Fdfs_client
              
                (
              
              
                'fastdfs/client.conf'
              
              
                )
              
              
                # 通过创建的客户端对象执行上传文件的方法:
              
              
client
              
                .
              
              upload_by_filename
              
                (
              
              
                '文件名'
              
              
                )
              
              
                # 或
              
              
client
              
                .
              
              upload_by_buffer
              
                (
              
              文件
              
                bytes
              
              数据
              
                )
              
            
          

通过Python测试:
先找到client.conf文件路径
在这里插入图片描述
上次文件:
FastDFS分布式系统在Docker和Python中的应用_第2张图片
‘Remote file_id’: ‘group1/M00/00/00/wKiVgV0UKeGAeXeKAABPHvQkMfU978.jpg’

说明:
group1 : 文件上传之后storage组的名称
M00: storage 配置的虚拟路径
/00/00/ : 数据的俩级目录,用来存放数据
wKiVgV0UKeGAeXeKAABPHvQkMfU978.jpg :文件上传之后的名字,它和上传的时候的已经不一样了,它是由服务器根据特定的信息生成的,文件名包括:源存储服务器的IP地址、文件创建的时间戳、文件的大小、随机数和文件的扩展名等信息

四、自定义django文件存储并且保存到FDFS服务器上

Django是自带文件存储系统的,但是默认的文件存储到本地,在本项目中,需要将文件保存到FastDFS服务器上,所以需要自定义文件存储系统。

1.在刚才的fastdfs目录中建一个fdfs_client.py文件用来自定义文件管理

  • 需要继承自django.core.files.storage.Storage

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

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

  • 需要为存储类添加django.utils.deconstruct.deconstructible装饰器,以便在迁移中的字段上使用它时可以序列化,只要你的字段有自己的参数可以自动序列化。

代码如下:

            
              
                from
              
               fdfs_client
              
                .
              
              client 
              
                import
              
               Fdfs_client

              
                from
              
               django
              
                .
              
              core
              
                .
              
              files
              
                .
              
              storage 
              
                import
              
               Storage
              
                ,
              
               FileSystemStorage

              
                from
              
               django
              
                .
              
              conf 
              
                import
              
               settings

              
                from
              
               django
              
                .
              
              utils
              
                .
              
              deconstruct 
              
                import
              
               deconstructible


              
                # 装饰器的作用: 序列化
              
              
@deconstructible

              
                class
              
              
                FastDfsStorage
              
              
                (
              
              Storage
              
                )
              
              
                :
              
              
                '''定义FSATDFS客户端'''
              
              
                def
              
              
                __init__
              
              
                (
              
              self
              
                ,
              
               base_url
              
                =
              
              
                None
              
              
                ,
              
               client_conf
              
                =
              
              
                None
              
              
                )
              
              
                :
              
              
                """
        初始化对象
        :param base_url: 将来用来构建图片、文件等的完整路径
        :param client_conf: fdfs客户端的配置文件的完整路径
        """
              
              
                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
              
                ,
              
               mode
              
                =
              
              
                'rb'
              
              
                )
              
              
                :
              
              
                """
        打开文件

		将来会被stroage.open()调用,在打开文件的时候调用
        :param name:
        :param mode:
        :return:
        """
              
              
                pass
              
              
                def
              
              
                _save
              
              
                (
              
              self
              
                ,
              
               name
              
                =
              
              
                None
              
              
                ,
              
               content
              
                =
              
              
                None
              
              
                ,
              
               max_length
              
                =
              
              
                None
              
              
                )
              
              
                :
              
              
                """
        保存文件,只需要传入一个name或者content即可
        
        将来会被storage.save() 调用,实现在fdfs里面保存数据
        :param name: 传入文件名
        :param content: 文件对象
        :return:保存到数据库中的FastDFSDE文件名
        """
              
              
        client 
              
                =
              
               Fdfs_client
              
                (
              
              self
              
                .
              
              client_conf
              
                )
              
              
                if
              
               name 
              
                is
              
              
                None
              
              
                :
              
              
            ret 
              
                =
              
               client
              
                .
              
              upload_by_buffer
              
                (
              
              content
              
                .
              
              read
              
                (
              
              
                )
              
              
                )
              
              
                else
              
              
                :
              
              
            ret 
              
                =
              
               client
              
                .
              
              upload_by_filename
              
                (
              
              name
              
                )
              
              
                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

    
              
                def
              
              
                delete
              
              
                (
              
              self
              
                ,
              
               name
              
                )
              
              
                :
              
              
                '''
        删除文件
        :param name: Remote file_id
        :return:
        '''
              
              

        client 
              
                =
              
               Fdfs_client
              
                (
              
              self
              
                .
              
              client_conf
              
                )
              
              
        client
              
                .
              
              delete_file
              
                (
              
              name
              
                )
              
            
          

注意:并不是这些方法全部都要实现,可以省略用不到的方法

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

在settings/dev.py 中添加设置:

            
              
                # django 文件储存
              
              
DEFAULT_FILE_STORAGE 
              
                =
              
              
                'shanghuiproject.fastdfs.fdfs_client.FastDfsStorage'
              
              
                # FastDFS
              
              
FDFS_URL 
              
                =
              
              
                'http://image.shanghui.site:8888/'
              
              
LAST_BASE_DIR 
              
                =
              
               os
              
                .
              
              path
              
                .
              
              dirname
              
                (
              
              os
              
                .
              
              path
              
                .
              
              dirname
              
                (
              
              os
              
                .
              
              path
              
                .
              
              dirname
              
                (
              
              os
              
                .
              
              path
              
                .
              
              abspath
              
                (
              
              __file__
              
                )
              
              
                )
              
              
                )
              
              
                )
              
              
FDFS_CLIENT_CONF 
              
                =
              
               os
              
                .
              
              path
              
                .
              
              join
              
                (
              
              LAST_BASE_DIR
              
                ,
              
              
                'fastdfs/client.conf'
              
              
                )
              
            
          

3.配置系统路径

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

            
              
                127.0
              
              
                .0
              
              
                .1
              
                 image
              
                .
              
              shanghuiproject
              
                .
              
              site

            
          

4.测试上传以及文件服务器域名

在django里面的shell进行测试:
FastDFS分布式系统在Docker和Python中的应用_第3张图片
上传成功后浏览器打开image.shanghui.site:8888/ 后面在拼接上面ret返回的值

效果图:
FastDFS分布式系统在Docker和Python中的应用_第4张图片


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论