littleatp2008的专栏

1. 背景

在大多数业务场景中,往往需要为FastDFS存储的文件提供http下载服务,而尽管FastDFS在其storage及tracker都内置了http服务, 但性能表现却不尽如人意;作者余庆在后来的版本中增加了基于当前主流web服务器的扩展模块(包括nginx/apache),其用意在于利用web服务器直接对本机storage数据文件提供http服务,以提高文件下载的性能。

2. 概要介绍

关于FastDFS的架构原理不再赘述,有兴趣可以参考:

2.1 参考架构

使用FastDFS整合Nginx的参考架构如下所示

说明: 在每一台storage服务器主机上部署Nginx及FastDFS扩展模块,由Nginx模块对storage存储的文件提供http下载服务, 仅当当前storage节点找不到文件时会向源storage主机发起redirect或proxy动作。注:图中的tracker可能为多个tracker组成的集群;且当前FastDFS的Nginx扩展模块支持单机多个group的情况

2.2 几个概念

storage_id:指storage server的id,从FastDFS4.x版本开始,tracker可以对storage定义一组ip到id的映射,以id的形式对storage进行管理。而文件名写入的不再是storage的ip而是id,这样的方式对于数据迁移十分有利。storage_sync_file_max_delay:指storage节点同步一个文件最大的时间延迟,是一个阈值;如果当前时间与文件创建时间的差距超过该值则认为同步已经完成。anti_steal_token:指文件ID防盗链的方式,FastDFS采用token认证的方式进行文件防盗链检查。

3. 实现原理3.1源码包说明

下载后的源码包很小,仅包括以下文件:

ngx_http_fastdfs_module.c //nginx-module接口实现文件,用于接入fastdfs-module核心模块逻辑 common.c//fastdfs-module核心模块,实现了初始化、文件下载的主要逻辑 common.h//对应于common.c的头文件 config//编译模块所用的配置,里面定义了一些重要的常量,如扩展配置文件路径、文件下载chunk大小 mod_fastdfs.conf//扩展配置文件的demo

3.2 初始化

3.2.1加载配置文件

目标文件:/etc/fdfs/mod_fastdfs.conf

3.2.2读取扩展模块配置

一些重要参数包括:

group_count//group个数url_have_group_name //url中是否包含groupgroup.store_path//group对应的存储路径connect_timeout//连接超时network_timeout//接收或发送超时storage_server_port //storage_server端口,用于在找不到文件情况下连接源storage下载文件(该做法已过时)response_mode//响应模式,proxy或redirectload_fdfs_parameters_from_tracker //是否从tracker下载服务端配置

3.2.3 加载服务端配置

根据load_fdfs_parameters_from_tracker参数确定是否从tracker获取server端的配置信息

load_fdfs_parameters_from_tracker=true:load_fdfs_parameters_from_tracker=false:从mod_fastdfs.conf加载所需配置:storage_sync_file_max_delay、use_storage_id;如果use_storage_id为true,则根据storage_ids_filename获取storage_ids映射表(调用方法:fdfs_load_storage_ids_from_file)

3.3 下载过程

3.3.1 解析访问路径

得到group和file_id_without_group两个参数;

3.3.2防盗链检查根据g_http_params.anti_steal_token配置(见http.conf文件),判断是否进行防盗链检查;采用token的方式实现防盗链, 该方式要求下载地址带上token,且token具有时效性(由ts参数指明);

检查方式:

md5(fileid_without_group + privKey + ts) = token; 同时ts没有超过ttl范围 (可参考JavaClient CommonProtocol)

调用方法:fdfs_http_check_token关于FastDFS的防盗链可参考:

3.3.3 获取文件元数据

根据文件ID 获取元数据信息, 包括:源storage ip,文件路径、名称,大小代码:

if ((result=fdfs_get_file_info_ex1(file_id, false, &file_info)) != 0)…

在fdfs_get_file_info_ex1的实现中,存在一个取巧的逻辑:当获得文件的ip段之后,仍然需要确定该段落是storage的id还是ip。代码:

fdfs_shared.func.c -> fdfs_get_server_id_type(ip_addr.s_addr) == FDFS_ID_TYPE_SERVER_ID …if (id > 0 && id <= FDFS_MAX_SERVER_ID) {return FDFS_ID_TYPE_SERVER_ID;} else {return FDFS_ID_TYPE_IP_ADDRESS;}

判断标准为ip段的整数值是否在 0 到 ->FDFS_MAX_SERVER_ID(见tracker_types.h)之间;其中FDFS_MAX_SERVER_ID = (1 << 24) – 1,该做法利用了ipv4地址的特点(由4*8个二进制位组成),即ipv4地址数值务必大于该阈值

3.3.4 检查本地文件是否存在

调用trunk_file_stat_ex1获取本地文件信息,该方法将实现:

代码:

if (bSameGroup){FDFSTrunkHeader trunkHeader;if ((result=trunk_file_stat_ex1(pStorePaths, store_path_index, \true_filename, filename_len, &file_stat, \&;trunkInfo, &trunkHeader, &fd)) != 0){bFileExists = false;}else{bFileExists = true;}}else{bFileExists = false;memset(&trunkInfo, 0, sizeof(trunkInfo));}

3.3.5 文件不存在的处理进行有效性检查

检查项有二:

A. 源storage是本机或者当前时间与文件创建时间的差距已经超过阈值,报错;

代码:

那段雨骤风狂。人生之旅本就是风雨兼程,是要说曾经拥有,

littleatp2008的专栏

相关文章:

你感兴趣的文章:

标签云: