FastDFS:文件系统从入门到应用

余庆老师在他的 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 所示。

    fastdfs_1-1

    图 1-1 FastDFS 的组织架构

FastDFS 文件传输

  • 通过时序图,分析 FastDFS 文件上传、文件下载等操作的流程,如图 1-2 所示。

    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 返回 文件内容

FastDFS 客户端

Java 客户端

Python 客户端

  • 安装环境:网上教程一般都是指 Python 2.7,在 Python 3.x 版本下跑不了,即使是通过 pip3 install fdfs-client-py 安装也跑不通,这里建议通过源码方式安装 $^{[3, 4]}$。

    源码地址:Hay86. fdfs_client-py. Last Updated on Sept.9, 2018

    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)

参考资料