基于Django+FastDFS文件管理系统搭建

FastDFS 介绍

    1. 简介

      FastDFS是一款类Google FS的开源分布式文件系统,它用纯C语言实现,支持Linux、FreeBSD、AIX等UNIX系统。它只能通过 专有API对文件进行存取访问,不支持POSIX接口方式,不能mount使用。准确地讲,Google FS以及FastDFS、mogileFS、 HDFS、TFS等类Google FS都不是系统级的分布式文件系统,而是应用级的分布式文件存储服务。

      FastDFS 是一个开源的高性能分布式文件系统(DFS)。 它的主要功能包括:文件存储,文件同步和文件访问,以及高容量和负载平衡。主要解决了海量数据存储问题,特别适合以中小文件(建议范围:4KB < file_size <500MB)为载体的在线服务。

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

      FastDFS 系统有三个角色:跟踪服务器(Tracker Server)、存储服务器(Storage Server)和客户端 (Client)。

      Tracker Server:跟踪服务器,主要做调度工作,起到均衡的作用;负责管理所有的 storage server和 group,每个 storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。通过Trackerserver在文件上传时可以根据一些策略找到Storageserver提供文件上传服务。

      Storage Server:存储服务器,主要提供容量和备份服务;以 group 为单位,每个 group 内可以有多台 storage server,数据互为备份。Storage server没有实现自己的文件系统而是利用操作系统 的文件系统来管理文件。

      Client:客户端,上传下载数据的服务器,也就是我们自己的项目所部署在的服务器。

    3. FastDFS 安装
      1、 安装FastDFS Linux依赖包

      yum install libevent libevent-devel gcc* -y
      

      2、 安装FastDFS的官方依赖包

      wget -O libfastcommon-1.0.39.tar.gz  https://codeload.github.com/happyfish100/libfastcommon/tar.gz/V1.0.39
      
      #解压依赖包
      tar -zxvf libfastcommon-1.0.39.tar.gz
      #编译安装
      cd libfastcommon-1.0.39 ./make.sh ./make.sh install 

      3、 配置tracker
      Tracker的配置文件在/etc/fdfs/下,首先为了稳定考虑对配置文件进行备份

      cd /etc/fdfs/
      cp tracker.conf.sample tracker.conf
      vim tracker.conf
      
      #重点修改下面的几个点
      	1、	确保disable是打开的
      	disable=false
      	2、	查看提供服务的端口
      	port=22122
      	3、	指定生产tracker数据和日志的目录
      	base_path=/fastdfs/tracker
      	4、	修改默认的http端口(目的为了防止冲突)
      	http.server_port=9080 5、 创建tracker_base的目录 mkdir -p /fastdfs/tracker 4、 启动tracker #关闭防火墙 systemctl stop firewalld 
      #启动命令
      systemctl start fdfs_trackerd
      
      #查看状态
      systemctl status fdfs_trackerd
      	```
      
      ```bash #如下: fdfs_trackerd.service - LSB: FastDFS tracker server Loaded: loaded (/etc/rc.d/init.d/fdfs_trackerd; bad; vendor preset: disabled) Active: active (running) since Mon 2020-06-22 01:53:40 EDT; 47min ago Docs: man:systemd-sysv-generator(8) Process: 1017 ExecStart=/etc/rc.d/init.d/fdfs_trackerd start (code=exited, status=0/SUCCESS) CGroup: /system.slice/fdfs_trackerd.service └─1034 /usr/bin/fdfs_trackerd /etc/fdfs/tracker.conf Jun 22 01:53:40 localhost.localdomain systemd[1]: Starting LSB: FastDFS tracker server... Jun 22 01:53:40 localhost.localdomain fdfs_trackerd[1017]: Starting FastDFS tracker server: Jun 22 01:53:40 localhost.localdomain systemd[1]: Started LSB: FastDFS tracker server. #查看端口 netstat -tulnp|grep fdfs #如下: tcp 0 0 0.0.0.0:22122 0.0.0.0:* LISTEN 1034/fdfs_trackerd #设置tracker开机自启动 chkconfig fdfs_trackerd on #关闭tracker /etc/init.d/fdfs_trackerd stop service fdfs_trackerd stop systemctl stop fdfs_trackerd 

      5、 配置storage
      storage的配置文件目录同样在/etc/fdfs/

      #配置storage
      cd /etc/fdfs/
      cp storage.conf.sample storage.conf
      vim storage.conf
      确保日志当中的以下配置
      disable=false
      group_name=group1 port=23000 heart_beat_interval=30 base_path=/fastdfs/storage/base store_path_count=1 store_path0=/fastdfs/storage subdir_count_per_path=256 tracker_server=192.168.194.158:22122 sync_start_time=00:00 sysc_end_time=23:59 http.server_port=9888 #创建对应的配置目录 makedir -p /fastdfs/storage/base 

      6、 启动storage

      #启动storage
      /etc/init.d/fdfs_storaged start
      service fdfs_storaged start
      systemctl start fdfs_storaged
      
      #查看状态
      systemctl status fdfs_storaged
      #如下
      ● fdfs_storaged.service - LSB: FastDFS storage server
         Loaded: loaded (/etc/rc.d/init.d/fdfs_storaged; bad; vendor preset: disabled) Active: active (running) since Mon 2020-06-22 01:53:40 EDT; 1h 15min ago Docs: man:systemd-sysv-generator(8) Process: 1018 ExecStart=/etc/rc.d/init.d/fdfs_storaged start (code=exited, status=0/SUCCESS) CGroup: /system.slice/fdfs_storaged.service └─1031 /usr/bin/fdfs_storaged /etc/fdfs/storage.conf Jun 22 01:53:40 localhost.localdomain systemd[1]: Starting LSB: FastDFS storage server... Jun 22 01:53:40 localhost.localdomain fdfs_storaged[1018]: Starting FastDFS storage server: Jun 22 01:53:40 localhost.localdomain systemd[1]: Started LSB: FastDFS storage server. #查看端口 netstat -unltp|grep fdfs tcp 0 0 0.0.0.0:23000 0.0.0.0:* LISTEN 1031/fdfs_storaged #查看tracker和storage是否通信 fdfs_monitor /etc/fdfs/storage.conf #如下 …… server_count=1, server_index=0 tracker server is 192.168.194.158:22122 group count: 1 Group 1: group name = group1 disk total space = 17394 MB disk free space = 15770 MB trunk free space = 0 MB storage server count = 1 active server count = 1 storage server port = 23000 storage HTTP port = 9888 store path count = 1 …… #配置storage开机启动 chkconfig fdfs_storaged on #关闭storage /etc/init.d/fdfs_storaged stop service fdfs_storaged stop systemctl stop fdfs_storaged 7、 配置client client的配置文件同样是存放在/etc/fdfs/下 cd /etc/fdfs/ cp client.conf.sample client.conf vim client.conf #配置如下 base_path=/fastdfs/client tracker_server=192.168.194.158:22122 

      8、 测试上传

      cd /opt/
      fdfs_upload_file /etc/fdfs/client.conf bjh.jpg
      效果如下
      group1/M00/00/00/wKjCnl7wXLSAT0pPAA8GO9kg11w732.jpg 
      Django_FastDFS使用
      	Django fastDFS有两个模块可以选择
      		py3fdfs
      		fdfs_client-py
      其中在windows下,python3环境当中使用fdfs_client-py有大概率遇到兼容问题,所以采用py3fdfs文件。
      pip install py3fdfs
      	文件上传
      
      from fdfs_client.client import Fdfs_client, get_tracker_conf
      
      tracker_path = get_tracker_conf('./client.conf') client = Fdfs_client(tracker_path) ret = client.upload_by_filename('./by.jpg') print(ret) #效果如下: {'Group name': b'group1', 'Remote file_id': b'group1/M00/00/00/wKjCnl7wcgCAS13GAAA6-XV4BMg226.jpg', 'Status': 'Upload successed.', 'Local file name': './by.jpg', 'Uploaded size': '14.74KB', 'Storage IP': b'192.168.194.158'} 与django进行结合 from django.shortcuts import render from fdfs_client.client import Fdfs_client, get_tracker_conf def index(request): if request.method == "POST": file = request.FILES.get("tfile") tracker_path = get_tracker_conf('./client.conf') client = Fdfs_client(tracker_path) ret = client.upload_by_buffer(file.read(),file_ext_name=file.name) print(ret) return render(request,"index.html") 

      文件下载
      文件修改和文件下载文件删除都需要有文件的remote_file_id,这个id在文件上传的时候回返回

      #保存文件返回的数据
      {'Group name': b'group1', 'Remote file_id': b'group1/M00/00/00/wKjCnl7wcgCAS13GAAA6-XV4BMg226.jpg', 'Status': 'Upload successed.', 'Local file name': './by.jpg', 'Uploaded size': '14.74KB', 'Storage IP': b'192.168.194.158'} from fdfs_client.client import Fdfs_client, get_tracker_conf tracker_path = get_tracker_conf('./client.conf') client = Fdfs_client(tracker_path) ret = client.download_to_buffer(remote_name) print(ret) 与django进行结合 #数据建模 from django.db import models class FileManager(models.Model): file_name = models.CharField(max_length = 128) remote_name = models.CharField(max_length = 128) upload_size = models.CharField(max_length = 32) file_type = models.CharField(max_length = 32) upload_time = models.DateTimeField() change_time = models.DateTimeField() group_name = models.CharField(max_length = 32) storage_ip = models.CharField(max_length = 64) #视图文件文件上传 import os import datetime from django.shortcuts import render from django.http import JsonResponse from fdfs_client.client import Fdfs_client, get_tracker_conf from FileManager.models import FileManager def upload(request): result = {"code": "","data": [],"state": ""} if request.method == "POST": file = request.FILES.get("file") file_name = file.name client = os.path.join( os.path.dirname(__file__),"client.conf" ) tracker_path = get_tracker_conf(client) try: client = Fdfs_client(tracker_path) ret = client.upload_by_buffer(file.read(), file_ext_name = file_name) except Exception as e: result["code"] = 500 result["state"] = str(e) result["data"].append(str(e)) else: f = FileManager() f.file_name = file_name f.remote_name = ret.get("Remote file_id").decode() f.upload_size = ret.get("Uploaded size") f.file_type = "图片" f.upload_time = datetime.datetime.now() f.change_time = datetime.datetime.now() f.group_name = ret.get("Group name").decode() f.storage_ip = ret.get("Storage IP").decode() f.save() result["code"] = 200 result["state"] = "上传成功" result["data"].append({ "file_name": file_name, "file_size": f.upload_size, "file_id": f.id }) else: result["code"] = 403 result["state"] = "请求失败" result["data"].append("请求失败") return JsonResponse(result) #文件下载 def download(request): result = {"code": "", "data": [], "state": ""} id_list = request.GET.getlist("file") for id in id_list: file = FileManager.objects.filter(id=id).first() if file: client = os.path.join( os.path.dirname(__file__), "client.conf" ) tracker_path = get_tracker_conf(client) client = Fdfs_client(tracker_path) filename = file.file_name remote_name = file.remote_name.replace("b'","").replace("'","") with open(filename,"wb") as f: content = client.download_to_buffer(remote_name.encode()) f.write(content["Content"]) result["code"] = 200 result["data"].append("下载完成") result["state"] = "下载完成" else: result["code"] = 400 result["data"].append("id 为 %s的文件不存在"%id) result["state"] = "不完整下载" continue return JsonResponse(result) 

      版本迭代思路:
             下载文件的路径设置
              基于文件管理的用户管理系统

    4. 源码见:https://gitee.com/dazejz

你可能感兴趣的:(基于Django+FastDFS文件管理系统搭建)