许金财
(厦门身份宝网络科技有限公司 福建 厦门 361008)
随着互联网的高速发展,分布式文件系统的应用越来越广泛。FastDFS是为互联网应用量身定做的分布式文件系统,充分考虑了冗余备份、负载均衡、线性扩容等机制,并注重高可用、高性能等指标,适合用来存储大量的图片、视频、电子文档等文件。本文对分布式文件系统FastDFS进行研究,并提出了文件编码到文件地址的转换算法,有效地提升了文件地址的检索速度[1]。
FastDFS是一个开源的轻量级分布式文件系统,采用C语言开发,支持Linux、FreeBSD等UNIX系统,充分考虑了冗余备份、负载均衡、线性扩容等机制,简单、灵活、高效。2008年7月FastDFS发布第一个版本V1.00,截至目前最新版本是V6.07。FastDFS由跟踪服务器(tracker server)、存储服务器(storage server)和客户端(client)3个部分组成,包括文件存储、文件同步、文件访问以及高容量和负载均衡,主要解决海量数据存储问题。跟踪服务器主要做调度工作,起到均衡的作用;存储服务器主要采用分组方式提供容量和备份服务。FastDFS文件地址由FastDFS服务端生成并返回,包含了组名、文件目录和文件名。
FastDFS客户端与服务端采用TCP通信协议,协议包由header和body两部分组成,其中header由8字节的消息体长度、1字节的命令字和1字节的状态码组成,消息体由不同的命令字确定,允许空内容[2]。
FastDFS应用中主要包括文件上传和文件下载两种应用流程。
文件上传时,由FastDFS客户端向跟踪服务器发送带有101命令字的消息请求,跟踪服务器按照负载均衡算法返回可用的存储服务器Socket地址,再由FastDFS客户端向指定的Socket地址发送带有11命令字和文件内容(可携带文件信息)的消息请求完成文件的上传,存储节点返回带有组名和文件地址的文件标识,例如:group2/M07/1B/D8/ClhYsVz0lV6AWXPXAABKRaBPLb0897.jpg,见图1。
图1 文件上传流程
在FastDFS中,上传后的文件标识不是由客户端指定,而是由Storage节点生成后返回给客户端的,文件标识作为文件访问凭证。
文件下载时,由FastDFS客户端向Tracker服务器发送带有102命令字和文件标识的消息请求,Tracker按照文件标识找到匹配的Storage存储节点服务器Socket地址,再由FastDFS客户端向指定的Socket地址发送带有14命令字和文件标识的消息请求,存储节点返回文件内容,见图2。
图2 文件下载流程
FastDFS返回的文件标识,其表现形式类似于文件路径,字符长度在46~61,与业务系统整合应用时,常规做法是增加UUID唯一识别码与文件标识进行映射,然后将UUID唯一标识码作为业务数据对应的文件编码进行存储。文件标识映射需要使用到数据库或Redis缓存,在高并发查询检索时会给服务器带来不小的负担。
结合FastDFS系统特点,本文采用了几种常见的Base编码方案来研究FastDFS文件寻址算法。文件上传时,将服务端返回的FastDFS文件标识解析为210 bit数据内容,经过Base编码后生成36个字节的文件编码作为文件的业务标识。文件下载时,将文件编码经过Base解码为210 bit数据内容,再转换为文件标识。目前已在多个项目的生产环境中使用FastDFS分布式文件系统和文件寻址算法。
把二进制数据转化为可打印字符集数据称为base encoding,编码后的数据方便用于存储和网络传输,本文中涉及Base32、Base64和Base62 3种编码方案。
Base32基于32个包括字母A~V、数字0~9的可打印字符。
Base64按照bit流进行编码,24(6和8的最小公倍数)bit为一组。
Base62是一种基于62个可打印字符来表示二进制数据的表示方法,可打印字符包括字母A~Z、a~z、数字0~9,共有62个字符。Base62提供了一种无符号输出的Base64的编码方案,在许多应用场合其纯字母和数字的输出形式,可以有效规避因为符号带来的各种负面影响,并能够有效削减或兼容各种Base64的变种形式。
FastDFS文件标识由组名、主目录索引、一级子目录、二级子目录、文件名5个部分组成。
(1)最大支持512个分组(V2.06之前的版本最大支持64个分组);
(2)最大支持256个主目录;
(3)最大支持256×256个子目录;
(4)文件名固定为34个字符,可包含“-”和“_”半角符号;
(5)支持不超过6个字符的文件扩展名(允许无扩展名)。
文件名的前27个字符是base64编码字符,文件名可解析为以下6个信息。
(1)存储节点服务器IPv4(32位整数);
(2)文件创建时间(UNIX时间戳,32位整数);
(3)文件大小(64位整数);
(4)文件CRC32校验码(32位整数);
(5)文件扩展名(例如.jpg);
(6)随机数(用来填补文件编号长度,其长度与文件扩展名的长度加起来等于7)。
前4个信息组合起来的160 bit数据内容经过base64编码后形成27个字符的唯一识别码,FastDFS支持不超过6个字符的文件扩展名,为了保持长度的一致性,当文件扩展名小于6个字符时,FastDFS将随机生成的阿拉伯数字填入文件标识中。
FastDFS文件标识编码原则,见图3。
图3 FastDFS文件标识编码图解
(1)使用group1至group512对分组名称进行统一命名(不支持其他自定义命名的组名),编码时仅保留分组索引;
(2)对通用的文件扩展名进行映射管理,最多可设置36个通用的文件扩展名映射编码;
(3)使用Base编码后的文件编码长度固定为36个字符;
(4)支持未设置映射编码的文件扩展名(此时应使用文件编码.后缀名完成文件寻址)。
FastDFS文件标识编码方式如下。
(1)使用2个32进制编码装载10位二进制(方便快速识别分组信息);
(2)使用7个62进制编码装载41位二进制;
(3)使用9个62进制编码装载53位二进制。
FastDFS文件编码寻址过程如下。
(1)使用Base32将文件编码的前两个字符解码为10 bit数据内容;
(2)使用Base62将文件编码的第3~9个字符解码为41 bit数据内容;
(3)使用Base62将文件编码的剩余27个字符分3次解码为3组53 bit数据内容;
(4)将开头的10 bit数据内容转换为分组索引并加上group分组前缀(见图3的group2);
(5)从41 bit数据内容中取出前3个字节,转换为文件目录(见图3的M07/1B/D8);
(6)从41 bit数据内容中取出1 bit,其他3个53 bit数据内容中分别取出5 bit,按顺序组成扩展数据项,其中十进制的第1个数据位为预定义文件扩展名(见图3的.jpg),其他数值为文件标识中扩展部分的随机阿拉伯数字(见图3的897);
(7)其他剩下的160 bit数据内容,使用Base64解码为27个字符的唯一识别码(见图3的ClhYsVz0lV6AWXP XAABKRaBPLb0);
(8)最终寻址结果:group2/M07/1B/D8/ClhYsVz0lV6 AWXPXAABKRaBPLb0897.jpg。
本文结合公司多个项目开发过程中碰到的图片存储服务文件编码和检索问题,研究了基于FastDFS分布式文件系统的文件编码到文件地址的转换算法,有效提升了文件地址的检索速度[3]。