余庆老师在他的 Github 上介绍关于 FastDFS 开源项目的描述:FastDFS 是一个开源的高性能分布式文件系统 ( DFS )。 它的主要功能包括文件存储,文件同步和文件访问,以及高容量和负载平衡。
FastDFS 简单介绍
FastDFS 核心组件
Tracker Server
:跟踪服务器,负责维持集群的信息;负责管理所有的 Storage Server 和 Group,每个 Storage 在启动后会连接 Tracker,告知自己所属 group 等信息,并保持周期性心跳。Storage server
:存储服务器,以 Group 为单位进行组织,任何一个 Storage Server 都应该属于某个 Group;一个 Group 可含多个 Storage server;在同一个 Group 内部,各 Storage Server 的数据自行同步、备份。Client
:客户端,上传、下载数据的服务器,也就是我们自己的项目所部署在的服务器。核心组件的介绍参考了 [1]、[2] 的概念叙述。
FastDFS 组织架构
结合组件的功能描述可知,FastDFS 的组织架构 $^{[2]}$ 如图 1-1 所示。
图 1-1 FastDFS 的组织架构
FastDFS 文件传输
通过时序图,分析 FastDFS 文件上传、文件下载等操作的流程,如图 1-2 所示。
图 1-2 FastDFS 文件上传、下载的时序图 文件上传流程:
- 1) Client 询问 Tracker,发送上传文件的请求;
- 2) Tracker 返回可调用的
Storage ID: Port
; - 3) Client 直接与目标 Storage 通讯,完成文件上传;
- 4) Storage 返回
文件ID
,文件ID 为Group ID + FileName
。
- 文件下载流程:
- 1) Client 询问 Tracker 下载文件所在的 Storage ( 参数为
文件ID
); - 2) Tracker 返回可调用的
Storage ID: Port
; - 3) Client 直接与目标 Storage 通讯,完成文件下载;
- 4) Storage 返回
文件内容
。
- 1) Client 询问 Tracker 下载文件所在的 Storage ( 参数为
FastDFS 客户端
Java 客户端
- 调用余庆老师封装的 FastDFS Client Java SDK,即可实现客户端访问 FastDFS。
Python 客户端
安装环境
:网上教程一般都是指 Python 2.7,在 Python 3.x 版本下跑不了,即使是通过pip3 install fdfs-client-py
安装也跑不通,这里建议通过源码方式安装 $^{[3, 4]}$。1
2
3
4
5
6
7
8
9
10# Case.01.通过 pip 安装
pip install fdfs_client-py-master.zip
'''
Case.02.通过 python 安装
解压 fdfs_client-py-master.zip,进入目录 /fdfs_client-py-master
python steup.py install
'''
# 安装完成后,若导入时提示缺少 mutagen、requests,请继续安装依赖包
pip install mutagen
pip install requests安装指南
:当然,安装指南和 API Reference 请参考源码的官方文档。生成配置
:在测试代码前夕,我们还需要创建一配置文件client.conf
。注意配置文件名称就是 client.conf,更改为其他名称好像行不通。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61# connect timeout in seconds
# default value is 30s
connect_timeout=30
# network timeout in seconds
# default value is 30s
network_timeout=30
# the base path to store log files
base_path=log
# 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.200.221:22122
# standard log level as syslog, case insensitive, value list:
### emerge 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 settings
## include http.conf测试代码
:这里假设你已成功安装了fdfs-client-py
,那么以一段测试代码正式开始使用。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19# Step.01. import fdfs_client.client module
# Step.02. instantiate class Fdfs_client
# Step.03. call memeber functions
from fdfs_client.client import *
# client.conf 配置文件放在 .py 文件同目录下
client = Fdfs_client('client.conf')
# 上传文件
ret = client.upload_by_filename('upload.txt')
print(ret)
## 等待 3 秒,否则下载时会报错文件不存在
time.sleep(3)
## 新版本文件存放 Remote file_id 格式变化
file_id = ret['Remote file_id'].replace('\\', '/')
# 下载文件
ret_download = client.download_to_file('download.txt', file_id)
print(ret_download)说明文档
:关于Fdfs_client
类的成员函数详细说明请参考 API Reference:- upload_by_filename(self, filename, meta_dict = None)
- upload_by_buffer(self, filebuffer, file_ext_name = None, meta_dict = None)
- upload_slave_by_filename(self, filename, remote_file_id, prefix_name, meta_dict = None)
- upload_slave_by_buffer(self, filebuffer, remote_file_id, meta_dict = None, file_ext_name = None)
- upload_appender_by_filename(self, local_filename, meta_dict = None)
- upload_appender_by_buffer(self, filebuffer, file_ext_name = None, meta_dict = None)
- delete_file(self, remote_file_id)
- download_to_file(self, local_filename, remote_file_id, offset = 0, down_bytes = 0)
- download_to_buffer(self, remote_file_id, offset = 0, down_bytes = 0)
- list_one_group(self, group_name)
- list_all_groups(self)
- list_servers(self, group_name, storage_ip = None)
- get_meta_data(self, remote_file_id)
- append_by_filename(self, local_filename, remote_fileid)
- append_by_buffer(self, file_buffer, remote_fileid)
- truncate_file(self, truncated_filesize, appender_fileid)
- modify_by_filename(self, filename, appender_fileid, offset = 0)
- modify_by_buffer(self, filebuffer, appender_fileid, offset = 0)