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.文件上传交互过程:
- Storage server 定时向Tracker server 上传状态信息
- Client 向 Tracker server 发送连接请求
- Tracker server 查询可用的storage
- Tracker server 返回storage的IP和端口给Client
- Client 上传文件到Storage server
- Storage server 将文件写入磁盘,同时生成文件id
- Storage server 返回文件id(路径信息和文件名)给Client
- Client 存储文件信息
2.文件下载交互过程:
- Storage server 定时向Tracker server 上传状态信息
- Client 向 Tracker server 发送连接请求
- Tracker server 查询可用的storage
- Tracker server 返回storage的IP和端口给Client
- Client 发送文件id(路径信息和文件名)给 Storage server
- Storage server 根据信息进行查找文件
- 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的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文件路径
上次文件:
‘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进行测试:
上传成功后浏览器打开image.shanghui.site:8888/ 后面在拼接上面ret返回的值