文章目录
1.什么是FastDFS
定义
- FastDFS(Fast Distributed file system)用
c语言
编写的一款开源的轻量级分布式文件系统
功能:
- 文件存储,文件访问(文件上传,文件下载)文件同步等,解决了大容量存储和负载均衡的问题
优点:
-
有利于冗余备份,负载均衡,线性扩容,高可用,高性能
-
实现了软RAID(redundant array of independent disks独立磁盘冗余阵列)
缺点
-
通过API下载,存在单点的性能瓶颈
-
不支持断点续传,对大文件将是噩梦
应用场景
- 适合以文件为载体的图片和视频的存储,因为没做分块存储,不太适合分布式计算场景
2.FastDFS的组成
FastDFS架构由Client
,Tracker server
和Storage server
组成
-
Client
客户端,业务请求的发起方,通过专有接口,使用TCP/IP协议与
Tracker
或Storage
进行数据交互,FastDFS提供了upload
,download
,delete
等接口供客户端使用. -
Tracker server
跟踪服务器,主要做调度工作,起负载均衡的作用在内存中记录集群中所有存储组和存储服务器的状态信息,是客户端和数据服务器交互的枢纽
-
Storage server
存储服务器(存储节点或数据服务器),文件和文件属性都保存到存储服务器上.Storage server直接利用OS的文件系统调用管理文件,Storage群中的横向可以扩容,纵向可以备份
3.上传和下载流程
上传
下载
4.FastDFS文件索引
FastDFS上传和下载流程可以看出都涉及到一个数据叫文件索引(file_id)
文件索引(file_id)是客户端上传文件后Storage返回给客户端的一个字符串,是以后访问该文件的索引信息
- 文件索引(file_id)信息包括:组名,虚拟磁盘路径,数据两级目录,文件名等信息
- 组名:文件上传后所在的Storage组名称
- 虚拟磁盘路径:Storage 配置的虚拟路径,与磁盘选项
store_path*
对应.如果配置了store_path0
则是M00
,如果配置了store_path1
则是M01
,以此类推 - 数据两级目录:Storage 服务器在每个虚拟磁盘路径下创建的两级目录,用于存储数据文件.
- 文件名:由存储服务器根据特定信息生成,文件名包含:源存储服务器IP地址,文件创建时间戳,文件大小,随机数和文件拓展名等信息
5.安装FastDFS
方式一:docker安装
# tracker服务
sudo docker run -dit --name tracker --network=host -v /var/fdfs/tracker:/var/fdfs delron/fastdfs tracker
# storage服务
sudo docker run -dti --name storage --network=host -e TRACKER_SERVER=服务器公网IP地址:22122 -v /var/fdfs/storage:/var/fdfs delron/fastdfs storage
方式二:docker-compose安装
docker-compose.yaml
version: '3'
services:
tracker:
image: delron/fastdfs
container_name: tracker
network_mode: host
volumes:
- /var/fdfs/tracker:/var/fdfs
command: tracker
storage:
image: delron/fastdfs
container_name: storage
network_mode: host
volumes:
- /var/fdfs/storage:/var/fdfs
depends_on:
- tracker
environment:
TRACKER_SERVER: 公网ip地址:22122
command: storage
6. 安装fdfs-client-py
1.下载 fdfs_client-py-master1.2.6.zip
2.安装
pip install fdfs_client-py-master1.2.6.zip
7.测试
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=本地日志文件位置
# 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
test.py
from fdfs_client.client import Fdfs_client
client = Fdfs_client(r"client.conf路径")
ret = client.upload_by_filename(r"图片地址")
print(ret)
# 结果
{'Group name': 'group1', 'Remote file_id': '/group1//M00/00/00/CgAQDmX25cyAX733AAAI4k7b2R4759.png', 'Status': 'Upload successed.', 'Local file name': '图片地址', 'Uploaded size': '2.00KB', 'Storage IP': '公网IP地址'}
浏览器正常访问http://公网IP地址:8888/group1//M00/00/00/CgAQDmX25cyAX733AAAI4k7b2R4759.png
8.对接Django框架
-
创建相关表且将图片相关的字段类型设置为
models.ImageField
-
将上传的图片的文件索引存入数据库
-
进行模板渲染时将时调用
{{查出来的对象.image.url}}
渲染出图片访问的地址
因为image字段存储的是文件索引,不是完整访问的url,所以无法下载,解决方法如下
-
重写Django文件存储类的url()方法
-
在重写时拼接完整的图片下载地址(协议,IP,端口,文件索引)
自定义Django文件存储类
class FastDFSStorage(Storage):
"""自定义文件存储系统,修改存储的方案"""
def __init__(self, fdfs_base_url=None):
"""
构造方法,可以不带参数,也可以携带参数
:param base_url: Storage的IP
"""
self.fdfs_base_url = fdfs_base_url or settings.FDFS_BASE_URL
def _open(self, name, mode='rb'):
......
def _save(self, name, content):
......
def url(self, name):
"""
返回name所指文件的绝对URL
:param name: 要读取文件的引用:group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg
:return: http://192.168.103.158:8888/group1/M00/00/00/wKhnnlxw_gmAcoWmAAEXU5wmjPs35.jpeg
"""
# return 'http://192.168.103.158:8888/' + name
# return 'http://image.meiduo.site:8888/' + name
return self.fdfs_base_url + name
settings.py
# 指定自定义的Django文件存储类
DEFAULT_FILE_STORAGE = 'FastDFSStorage文件所在的路径'
# FastDFS相关参数
FDFS_BASE_URL = 'http://192.168.103.158:8888/'