您所在的位置:开发 > 架构&设计 > Facebook图片存储架构技术全解析(2)

Facebook图片存储架构技术全解析(2)

2009-05-13 09:10 Alpha 编译 51CTO.com 我要评论(0) 字号:T | T
一键收藏,随时查看,分享好友!

Haystack提出了一种通用的基于HTTP的对象存储,它含有指针,映射到存储对象。在Haystack中以指针储存照片,把数以十万计的图像聚集到一个Haystack存储文件,从而消除了元数据负荷。这就使得元数据的开销非常小,并且使我们能够在存储文件和内存索引中存储每个指针的位置。这就使得能用少量的I/O操作来完成图像数据的检索,可以消除一切不必要的元数据开销。

AD:

文件系统

Haystack对象存储实现于一个文件之上,该文件存储在一个单一文件系统上,该文件系统建立于10TB volume(卷)大小的空间之上。

照片读取请求导致read()系统调用请求读取文件中不同偏移量的信息,但为了执行读取操作,文件系统必须首先在实际物理卷上找到数据。在文件系统中,每个文件的是由一个名为inode的结构所描述,该结构包含一个块映射,可以把逻辑文件偏移量映射到物理卷中的物理块偏离量。对于大文件,根据所使用的文件系统类型的不同,块映射可能会相当庞大。

基于块的文件系统为每个逻辑块维护其映射信息,对于大文件,这些映射信息将不会像通常那样存入缓存的inode,而是储存在间接地址块,读取文件数据时需要进行转换。间接转化可能存在好几个层次,因此,根据间接地址块是否被缓存,单一的读取可能会导致若干个I/O操作。

基于范围的文件系统只为连续的块(区域)维护映射信息。对于一个连续大文件的块映射只由一个区域组成,此区域的大小正好可以装入inode之中。但是,如果该文件是严重地分散和不连续的,其区块在卷中不连续,那么其块映射可以随之增长。有了基于范围的文件系统,就可以通过积极分配一大块空间来减少碎片。

目前,所选择的文件系统是的XFS,基于范围的文件系统提供有效文件预分配。

Haystack对象存储

Haystack是一个简单日志结构(只追加)的对象存储,包含描述存储对象的指针。一个Haystack包括两个文件——实际的包含指针的Haystack存储文件,以及一个索引文件。下图显示了Haystack存储文件的结构布局:

第一个8KB的Haystack存储由超级块所占用。紧接着超级块的是指针,每个指针由页眉、数据、和页脚组成。

一个指针是由其﹤Offset(偏移量), Key, Alternate Key(替换键),Cookie﹥元组唯一确定,其中偏移量是指在Haystack存储中的指针偏移量。Haystack对于关键字的值没有任何限制,有的指针可以有多个关键字。下图显示的是索引文件的结构布局—

在Haystack存储文件中,每个指针有一个相应的索引纪录,而且指针索引纪录的顺序必须与Haystack存储文件中相关的指针顺序相匹配。索引文件提供查找Haystack存储文件中某一特定指针所需的最小元数据。为了快速查找,把索引记录载入并组织到一个数据结构中,这是Haystack应用程序(在我们的情况下是照片存储)的职责。索引文件不是至关重要的,因为它可以根据所需从Haystack存储文件中重建。索引的主要目的是可以快速加载指针元数据到内存中,而无须遍历庞大的Haystack存储文件,这是因为索引的大小通常还不到存储文件的1%。

Haystack写操作

Haystack写操作同步添加新的指针到Haystack存储文件中。当指针成功添加到庞大的Haystack存储文件中之后,相应的索引记录也被写入索引文件。由于索引文件不是至关重要的,为了达到更快的性能,该索引记录是异步写。

索引文件还会定期被刷新到下面的存储设备,以便限制由硬件故障所引起的恢复操作的程度。在系统崩溃或突然断电的情况下,Haystack恢复程序丢弃所有存储中的不完整的指针,同时截断Haystack存储文件直到最后一个有效的指针,然后,在Haystack存储文件最后为所有跟踪的孤立指针写入丢失的索引记录。

Haystack不允许覆盖已存在的指针偏移量,因此,如果某个指针的数据需要修改,其修改后的新版本必须使用相同的﹤Key, Alternate Key, Cookie﹥元组。然后应用程序就可以认为,在那些有着多个关键字的指针中,具有最大偏移量的指针就是最新添加的指针。

Haystack读操作

传递给Haystack读操作的参数包括指针偏移量、关键字、替换键、Cookie和数据大小。然后Haystack添加页眉和页脚的大小到数据大小中,并从文件中读取整个指针。只有当关键字、替换键和Cookie符合参数类型,所传递的数据通过校验,并且指针没有被之前的操作删除时,读操作才能成功(见下文)。

Haystack删除操作

删除操作很简单——通过设置指针的标记域中的一个“deleted(已删除)”标记位,标记Haystack存储中的指针为已删除。然而,相关的索引记录并不进行任何方式的修改,因此一个应用程序可能会结束于引用某个已删除的指针。对于这样的指针的读操作会注意到“deleted”标记,然后终止操作,提示操作错误,给出错误信息。已删除的指针的空间不会以任何方式回收。回收已删除指针的空间的唯一方法是压缩c(见下文) 。

照片存储服务器

照片存储服务器负责接收HTTP请求,并转化成相应的Haystack存储操作。为了尽量减少读取照片所需的I/ O操作次数,服务器在内存中保存一个Haystack存储文件中所有照片偏移量的索引。启动时,服务器读取Haystack索引文件并生成一个内存中的索引。由于每个节点数以亿计的照片(并且该数字只会随着更大容量的驱动器而增加),我们必须确保该索引能够装入可用的内存中。这是通过在内存中保留最少数量的元数据来实现,只保留查找照片所需的信息。

当用户上传一个照片,该照片就被分配一个唯一的64位编号。然后将照片转化为4个不同大小的图片。每个图片具有相同的随机Cookie和64位关键字,合理的图像大小(大,中,小,缩略图)是储存在替换键中。然后上传服务器调用照片存储服务器,把所有4个图像存储在Haystack中。

内存中的索引为每张照片保存以下信息:

Haystack使用开源Google稀疏散列数据结构来减小内存中的索引,因为使用它,每条记录只占2位。

照片存储写/修改操作

写操作写入照片到Haystack,并更新内存索引。如果该索引中已经包含了具有相同关键字的记录,那么这就是一个修改现有照片的操作,那么只修改索引记录偏移量,以反映新图像在Haystack存储文件中的位置。照片存储总是假设存在重复的照片(具有相同关键字的照片),只有存储在最大偏移量位置的照片是有效的。

照片存储读操作

传递到读操作的参数包括Haystack id 和照片关键字、大小和COOKIE 。服务器根据照片关键字,执行一个在内存索引上的查找操作,然后得到含有所需照片的指针偏移量。如果发现调用的是Haystack读操作来读取照片,那么如上所述,Haystack删除操作并不更新Haystack索引文件记录。因此,一个新的内存索引可能会包含之前删除的照片的旧记录。读取之前删除的照片将会导致操作失败,并且内存中的索引会自动更新,设置已经删除图像的偏移量为0。

照片存储删除操作

在调用Haystack删除操作之后,内存中的索引被更新,设置特定图像的偏移量为0来表示该图像已经被删除。

压缩

压缩是一个联机操作,可以回收已被删除的指针和重复指针(具有相同关键字的指针)所占用的空间。它通过复制指针创建一个新的Haystack,跳过所有重复和已删除的指针。每次这样做,就会交换文件和内存中文件的结构。

HTTP服务器

我们使用的HTTP框架是由开源lib event图书馆所提供的简单的evhttp服务器。我们使用多线程,同一时间内,每个线程能够处理一个HTTP请求。因为我们的工作量最主要是由I/O操作产生,因此HTTP服务器的性能并不是至关重要的。

【编辑推荐】

  1. 高性能、高流量互联网应用架构设计实战原则
  2. 大型网站架构不得不考虑的10个问题
  3. 大型Web2.0站点构建技术初探
【责任编辑:杨赛 TEL:(010)68476606】

内容导航
 第 1 页:两种基础架构比较  第 2 页:文件系统和架构

分享到:

网友评论TOP5

查看所有评论(

提交评论

  1. 专题:JVM编程语言,你的选择?
  2. 宅男程序员给老婆课程之11:域模型

文章排行

本月本周24小时

热点专题

更多>>

读书

基于Eclipse的开源框架技术与实战
当前,开源框架层出不穷,它为用户提供了通用的解决方案,同时也增加了用户的学习难度。开源是一把“双刃剑”,一方面它共享了资

51CTO旗下网站

领先的IT技术网站 51CTO 领先的中文存储媒体 WatchStor 中国首个CIO网站 CIOage 中国首家数字医疗网站 HC3i 移动互联网生活门户 灵客风LinkPhone