Facebook Haystack图片存储架构

发表于:2013-12-06来源:IT博客大学习作者:chuanhui点击数: 标签:Facebook
Facebook Haystack图片存储架构.OSDI 10中有一篇Facebook图片存储系统Haystack的论文,名称为”Finding a needle in Haystack: Facebook’s photo storage”。从这篇论文可以看出,数据量大的应用有时也并不复杂。

  OSDI 10中有一篇Facebook图片存储系统Haystack的论文,名称为”Finding a needle in Haystack: Facebook’s photo storage”。从这篇论文可以看出,数据量大的应用有时也并不复杂。

  我们先给Facebook图片存储系统算一笔账。Facebook目前存储了260 billion图片,总大小为20PB,通过计算可以得出每张图片的平均大小为20PB / 260GB,约为800KB。用户每周新增图片数为1 billion (总大小为60TB),平均每秒钟新增的图片数为10^9 / 7 / 40000 (按每天40000s计),约为每秒3500次写操作,读操作峰值可以达到每秒百万次。另外,图片应用的特点是写一次以后图片只读,图片可能被删除但不会修改。

  图片应用系统有两个关键点:

  1, Metadata信息存储。由于图片数量巨大,单机存放不了所有的Metadata信息,假设每个图片文件的Metadata占用100字节,260 billion图片Metadata占用的空间为260G * 100 = 26000GB。

  2, 减少图片读取的IO次数。在普通的Linux文件系统中,读取一个文件包括三次磁盘IO:读取目录元数据到内存,把文件的inode节点装载到内存,最后读取实际的文件内容。由于文件数太多,无法将所有目录及文件的inode信息缓存到内存,因此磁盘IO次数很难达到每个图片读取只需要一次磁盘IO的理想状态。

  3, 图片缓存。图片写入以后就不再修改,因此,需要对图片进行缓存并且将缓存放到离用户最近的位置,一般会使用CDN技术。

  Facebook图片系统初期的架构如下:

Facebook_NAS.PNG

  这个架构采用CDN作为图片缓存,底层使用基于NAS的存储,Photo Store Server 通过NFS挂载NAS中的图片文件提供服务。用户的图片请求首先调度到最近的CDN节点,如果CDN缓存命中,直接将图片内容返回用户;否则CDN请求后端的存储系统,缓存并将图片内容返回用户。Facebook的经验表明,SNS社交网站中CDN缓存的效果有限,存在大量的”长尾”请求。虽然user profile图片请求的CDN命中率高达99.8%,但是其它图片请求CDN命中率只有92%,大约1/10的请求最后落到了后端的存储系统。这个架构的问题如下:

  1, 图片存储的IO次数过多。这个架构没有解决图片物理文件个数太多的问题,因此,无法将目录和文件的inode信息全部装载到内存中,且后端存储系统的访问比较分散,很难缓存,每次图片读取需要多次(一般为3次)IO操作。

  2, 依赖于CDN提供商。Facebook使用Akamai & Limelight的CDN服务,不可控因素较多,成本也比较高。

  Facebook Haystack新架构主要解决图片存取IO次数过多的文件,主要的思路是多个逻辑文件共享同一个物理文件。Haystack架构及读请求处理流程图如下:

Facebook_Haystack.PNG

  Haystack架构主要有三个部分:Haystack Directory,Haystack Store以及Haystack Cache。Haystack Store是物理存储节点,以物理卷轴(physical volume)的形式组织存储空间,每个物理卷轴一般很大,比如100GB,这样10TB的数据也只有100个物理卷轴。每个物理卷轴对应一个物理文件,因此,每个存储节点上的物理文件元信息都很小。多个物理存储节点上的物理卷轴组成一个逻辑卷轴(logical volume),用于备份。Haystack Directory存放逻辑卷轴和物理卷轴的对应关系,假设每个卷轴的大小为100GB,对应关系的条数为20PB / 100GB = 0.2MB,占用的内存可以忽略。Haystack cache主要用于解决对CDN提供商过于依赖的问题,提供最近增加的图片的缓存服务。

  Haystack图片读取请求大致流程为:用户访问一个页面时,Web Server请求Haystack Directory构造一个URL:http:// / / / ,后续根据各个部分的信息依次访问CDN,Cache和后端的Haystack Store存储节点。Haystack Directory构造URL时可以省略部分从而使得用户直接请求Haystack Cache而不必经过CDN。Haystack cache收到的请求包含两个部分:用户Browser的请求及CDN的请求,Haystack cache只缓存用户Browser发送的请求且要求请求的Haystack Store存储节点是可写的。一般来说,Haystack Store的存储节点写一段时间以后达到容量上限变为只读,因此,可写节点的图片为最近增加的图片,是热点数据。

  Haystack的写请求(图片上传)处理流程为:Web Server首先请求Haystack Directory获取图片的id和可写的逻辑卷轴,接着将数据写入对应的每一个物理卷轴(备份数一般为3)。

  Haystack Directory

  Haystack Directory的功能如下:

  1, 提供逻辑卷轴到物理卷轴的映射,为写请求分配图片id;

  2, 提供负载均衡,为写操作选择逻辑卷轴,读操作选择物理卷轴;

  3, 屏蔽CDN服务,可以选择某些图片请求直接走Haystack Cache;

  4, 标记某些逻辑卷轴为read-only;

  根据前面的计算结果,Facebook图片系统每秒的写操作大约为3500,每秒的读请求大约为100万。每个写请求都需要通过 Haystack Directory分配图片id并获取可写的卷轴,每个读请求需要通过Haystack Directory查找图片所属的物理卷轴。这里需要注意,图片id到逻辑卷轴的映射的数据量太大,单机内存无法存放,可以推测存放在外部的Mysql Sharding集群中,图片系统的读取操作同时带有图片id和逻辑卷轴两个参数。

  Haystack Directory的实现较为简单,采用Replicated Database做持久化存储,前面增加一个Memcache集群满足查询需求

  Haystack Store

  Haystack Store存储物理卷轴,每个物理卷轴对应文件系统中的一个物理文件,每个物理文件的格式如下:

Facebook_Store.PNG

  多个图片文件存放在一个物理卷轴中,每个图片文件是一个Needle,包含实际数据及逻辑图片的元数据。部分元数据需要装载到内存中用于图片查找,包括Key(图片id,8字节), Alternate Key(图片规格,包括Thumbnail, Small, Medium及Large,4字节),图片在物理卷轴的偏移Offset(4字节),图片的大小Size(4字节),每张图片占用8 + 8 + 4 = 20字节的空间,假设每台机器的可用磁盘为8TB,图片平均大小为800KB,单机存储的图片数为8TB / 800KB = 10MB,占用内存200MB。

原文转自:http://blogread.cn/it/article/3127?f=wb