Facebook存储65亿张照片的存储框架
从未用过Facebook,但是还是对Facebook应对大容量的非结构化数据存储方案感兴趣。本文是通过在线网络广播(webcast)经本人翻译得来的,因此,本人并不能确保本文中叙述的内容与原文webcast不存在偏差。
本文严禁在未征得本人同意的情况下以任何形式进行转载。本人直接受在邮件中的转载申请,如需转载,请发送邮件至 betteryou@126.com。
Facebook概况
? Facebook目前拥有65亿张照片,每张照片分别会保存为4~5种尺寸的文件,所以大概会有300亿个文件,大约占据540TB的存储空间。
? Facebook平均的请求流量是475,000张图片/秒;其中,关于概况(Profile)的照片请求量大约是200,000张/秒。
? Facebook每周大约会收到1亿次上载请求。
所以,Facebook需要在海量的数据存储中高效读取和存储数据。Facebook目前有25名开发工程师负责开发,他们大部分的工作都集中在如何让Facebook的数据库性能更优化,如何让Facebook的数据库可扩展性更好,等等方面的工作上。
目前,Facebook拥有数千台服务器(虽然webcast的片子上有一则新闻说已经达到10,000台服务器,但webcast上Jason还是说的是数千台??thousands of servers),这些服务器大部分都有明确的分工,各司其职;使用MySQL数据库;PHP运行在Apache上,并且用C开发了一些扩展和封装;在Facebook的应用层和数据库层之间,他们使用了Memcached技术,作为缓存。
小贴士:何谓Memcached?
Memcached是首先由Danga Interactive为Live Journal开发的通用分布式内存缓存系统。它通常通过将对象和数据缓存至内存的方法来加快动态数据库驱动网站的速度,减少了数据库访问的次数。Memcached缺少安全认证特性,这就意味着它必须在正确配置的防火墙内运行。Memcached的API提供了分布在多台计算机上的巨大哈希表(Hash Table)。当哈希表满了之后,新插入的数据会使用LRU算法(最近最少使用算法)将较老的数据擦洗掉。YouTube、LiveJournal、Wikipedia、SourceForge、Facebook、NYTimes.com等知名网站都使用了Memcached。
Facebook当前存储架构
注:我暂且称之为当前存储架构,原因有二:第一是webcast的PPT当中出现的是”State of the World”字样,表明现在的状况;第二是新的存储架构Haystack并未在webcast中明确表示已经进入生产环境。如描述有错误,欢迎各位积极指正。
Facebook的存储架构需要应对两方面的问题:读和写。我们分开来观察。
写:
当用户需要上载照片,也就是对Facebook的存储进行写入操作的时候,Facebook会指定一台上载服务器来进行工作。上载服务器会对上载的照片进行处理,每张照片会按照4~5种不同的尺寸进行存储。
读:
当用户需要对照片进行读取时,架构会稍微复杂一些:
当用户点击某张照片后,请求将通过HTTP传到CDN (Content Delivery Network),CDN中已经缓存了一些照片,如果请求的照片在CDN中,就可以将照片返回给用户。如果照片未在CDN中,那么就有两种情况发生。
- 如果请求的是普通照片,则请求会传递到不同的照片服务器(Photo Server),照片服务器去读取后台Netapp存储的数据。
- 如果请求的是基本资料(Profile)上的照片,那么读取该照片的请求会到一个叫“Cachr”,Cachr是一个超轻量级的服务器,专门负责缓存基本资料相关的照片。如果在Cachr中依然没有找到照片,就需要通过照片服务器(Photo Server)去读取后台Netapp存储的数据了。
目前,Facebook的Cachr可扩展性和稳定性良好,对基本资料(Profile)上照片的请求大概在200,000次/秒,占总请求数量的一半还强,Facebook大约有40个Cachr节点,运行了4年多,并未出现大问题。照片服务器(Photo Server)采用文件处理缓存(File Handle Cache)技术,旨在提高照片的读取性能。
架构上的问题
刚才简单介绍了整个Facebook存储架构,但这个架构存在着一些问题:
- 第一,无论是Netapp还是别的文件系统都会造成元数据(metadata)爆炸性增长。他们使用一个文件一个元数据(metadata)的方式,而且每个文件系统都强制使用目录等层次性结构,这样就势必增加了与真正所需数据无关的内容。所以,对于Facebook来说,大约需要进行3次磁盘IO才能成功读取一张图片(在刚刚设计之初,IO的次数需要达到15次,所以3次已经是非常优化的结果了)。
- 第二,正是由于对文件系统中图片读取的代价增大,所以Facebook不得不更加依赖于高效的数据缓存来解决磁盘IO造成的矛盾。目前,Facebook的CDN中的基本资料访问命中率达99.8%,普通图片的访问命中率达92%,这样才降低了对文件系统的访问量
Haystack
Facebook引入Haystack的原因是为了减少元数据(metadata)的使用。对于Haystack来说,可以将一些图片捆绑在一起,然后这些文件统一使用一个单独的元数据(metadata)。那么这样的话,怎么能够保证真正从这些文件中读取到真正需要的数据呢?Haystack使用独立索引文件来对文件系统的数据建立索引。所以这样的话,就可以通过索引里的键(Key)指向所需要的图片文件了。通常,1GB的图片数据需要RAM中的1M元数据(metadata)内存缓存。因为Haystack能确保索引内容肯定驻留在RAM中,所以Facebook就能确保对每张图片的IO次数最多为1次。
Haystack的存储模式
Haystack在磁盘上表现为一系列重复的数据块,包含数据头(Header)和数据段(Segment)两个部分。下图是Facebook中使用Haystack的存储方式。
下图是Haystack中的索引情况:
其中,start代表了在Haystack文件系统中该文件的起始地址,length就是文件的长度。
新的存储架构
如果放弃使用Netapp,转而使用Haystack,那么Facebook的读取场景就会发生一定的变化。我们重新来观察一下:
写:
读取:
原webcast观看:Facebook ? Needle in a Haystack: Efficient Storage of Billions of Photos