1. 前言
互联网应用经常需要存储用户上传的文档,图片,视频数据,这些数据也称为Blob数据,存储Blob数据的文件系统也相应地称为Blob存储系统。其中Blob数据一般都比较大,且多个Blob数据之间没有关联。Blob文件这样的系统的特点是数据写入后基本都是只读,很少出现更新操作。
淘宝数据量大且增长很快,淘宝文件系统TFS中存储的图片规模已经达到百亿级别。TFS架构设计时候主要考虑以下两个问题:
- Metadata信息存储。由于图片数量巨大,单机存放不了所有的原数据信息,假设每个图片文件的元数据占用100字节,100亿图片的元数据占用的空间为10GX0.1KB=1TB,单台机器无法提供原数据服务
- 减少图片读取的IO次数。在普通的linux系统中,读取一个文件包括三次IO操作:首先读取目录元数据到内存,其次把文件的inode节点装载到内存,最后读取实际的文件内容,由于小文件个数太多,无法将所有目录及文件的inode信息缓存到内存,因此磁盘的IO次数很难达到每个图片只需要一次磁盘IO的理想状态
因此,TFS采用的思路:多个逻辑图片文件共享一个物理文件。
2. 系统架构
a) 架构综述
TFS借鉴了GFS但又有所不同。首先,TFS内部不维护文件目录树,每个小文件使用一个64位的编号表示;其次,TFS是一个读多写少的应用,其写流程可以更加简单。
一个TFS集群由两个NameServer节点(一主一备)和多个DataServer节点组成,NameServer通过心跳对DataServer的状态进行检测。每个DataServer运行多个dsp进程,一个dsp对应一个挂载点,一般对应一个独立磁盘,从而管理多块磁盘。
在TFS中,将大量的小文件也就是实际数据文件合并成一个大文件,称为Block(块),每个Block在集群中有唯一的编号,通过<块ID,块内偏移量>可唯一确定一个文件。TFS中的Block的实际数据都存储在DataServer中,大小一般为64MB,默认存储三份。应用客户端是TFS提供给应用程序的访问接口,应用客户端不缓存文件数据,只缓存NameServer的元数据。
b) 追加流程
TFS读多写少,即使每个写操作都经过NameNode也不会出现问题。如上图,客户端向NameServer发起写请求,NameServer需要根据DataServer上的可写块,容量,负载加权来选择一个可写的Block并且在该Block所在的多个DataServer中选择一个作为写入的主副本,其他作为备副本。其次,客户端向主副本写入数据,主副本将数据同步到多个备副本。如果所有的副本都修改成功,主副本会首先通知NameServer更新Block版本号,成功以后才会返回客户端操作结果。如果中间发生错误,客户端都可以从第一步开始重试。
相比GFS,TFS写流程不够优化:
u 每个写请求需要多次访问NameServer
u 数据推送没有采用流水线方式减少延迟
每个写操作返回后,会返回客户端两个信息,小文件在TFS中的Block编号以及Block偏移。应用系统会将这些信息保存到数据库中,图片读取的时候首先根据Block编号从NameServer查找Block所在的DataServer,然后根据Block偏移读取图片数据。
TFS的一致性模型保证所有返回给客户端的<Block id,Block offset>表示的图片数据在TFS中的所有副本都是有效的。
c) NameServer
NameServer的主要功能是:Block管理,DataServer管理以及二者的映射关系。NameServer采用HA结构,主NameServer出现故障,可以实时切换到备NameServer。
3. 讨论
在图片应用中,有两个主要的问题。一是图片去重,二是图片更新与删除。
由于用户可能上传大量相同的图片,因此图片上传到TFS前需要去重。一般在外部维护一套文件级别的去重系统(Dedup),采用MD5或者SHA1等hash算法为图片计算指纹。图片写入TFS之前首先到文件去重系统中查找是否存在指纹,如果存在基本可以认为是重复文件。图片写入TFS后也需要将图片的指纹以及在TFS中的位置信息保存到去重系统。去重是一个键值存储系统,淘宝文件系统采用的是Tair分布式键值系统来实现的。
图片的更新操作是在TFS中写入新图片,并在应用系统的数据库中保存新图片的位置,图片的删除操作仅仅在应用系统中将图片删除。图片通过<Block id,Block offset>标识,且Block偏移就是Block文件中的物理偏移。因此只要Block中只要还有一个有效的图片文件就无法回收,也无法对Block进行重整。如果系统的更新和删除比较频繁,需要考虑磁盘空间的回收。这在Haystack中有所体现。
欢迎扫描二维码关注微信公众号 深度学习与数学 [每天获取免费的大数据、AI等相关的学习资源、经典和最新的深度学习相关的论文研读,算法和其他互联网技能的学习,概率论、线性代数等高等数学知识的回顾]