本文主要是介绍Facebook photo-storage [haystack],希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Facebook photo-storage
毕竟现在的趋势是工业界走在学校之前,抽时间看看工业界的解决方案还是不错的,看了face-book用于存储照片的存储系统。参考的资料为:论文 《Finding a needle in Haystack: Facebook’s photo storage》
(0)haystack 架构与处理流程
(1) haystack架构
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提供商过于依赖的问题,提供最近增加的图片的缓存服务。
(2)Haystack图片读取请求流程
Haystack图片读取请求大致流程为:用户访问一个页面时,Web Server请求Haystack Directory构造一个URL:http:// <CDN> / <Cache> / <Machine id> / <Logical volume, Photo>,后续根据各个部分的信息依次访问CDN,Cache和后端的Haystack Store存储节点。Haystack Directory构造URL时可以省略<CDN>部分从而使得用户直接请求Haystack Cache而不必经过CDN。Haystack cache收到的请求包含两个部分:用户Browser的请求及CDN的请求,Haystack cache只缓存用户Browser发送的请求且要求请求的Haystack Store存储节点是可写的。一般来说,Haystack Store的存储节点写一段时间以后达到容量上限变为只读,因此,可写节点的图片为最近增加的图片,是热点数据。
Haystack的写请求(图片上传)处理流程为:Web Server首先请求Haystack Directory获取图片的id和可写的逻辑卷轴,接着将数据写入对应的每一个物理卷轴(备份数一般为3)。
疑问:web server拿着什么信息去haystack directory呢?即web server上存的什么信息。photo id ??,那么是不是haystack 要处理海量的id 到 logical volume等的信息。haystack directory是如何设计的呢?不知道这个访问的详细流程和directory的设计。不知道有人是否能解答。
1:研究背景与动机
facebook上有海量的图片/照片读写需求,针对这种海量的小文件的存储,使用传统的本地ext2/ext3等文件系统和nfs网络协议的访问但是很容易成为瓶颈,原因有以下几个:
a:ext3等本地文件系统对每个文件都要3处磁盘管理,即目录项/inode/文件内容。所以小文件的访问也需要3次磁盘访问甚至更多。
b: 为了加速小文件的存取,需要将对应元数据全部放入内存(使得基本上读取文件只进行一次磁盘操作),但是ext3 inode大小256B,非常大,包含了可能很多对于应用来讲无用
的信息。并且导致内存不能容纳所有的元数据缓存。
2:Haystack Directory与Haystack Store
Directory与store功能类似于pnfs三方架构中的元数据服务器和数据服务器。但是pnfs文件系统还是一种面向general存储特别的大文件的存储。对于海量小文件存储没有优势,反倒是缺陷。
(1) Haystack Directory
Haystack Directory的主要功能如下:
(a) 提供逻辑卷轴到物理卷轴的映射,为写请求分配图片id;
(b) 提供负载均衡,为写操作选择逻辑卷轴,读操作选择物理卷轴;
(c) 屏蔽CDN服务,可以选择某些图片请求直接走HayStack Cache;
(d) 标记某些逻辑卷轴为read-only;
疑问:
根据前面的计算结果,Facebook图片系统每秒的写操作大约为3500,每秒的读请求大约为100万。每个写请求都需要通过Haystack Directory分配图片id并获取可写的卷轴,每个读请求需要通过Haystack Directory查找图片所属的物理卷轴。这里需要注意,图片id到逻辑卷轴的映射的数据量太大,单机内存无法存放,可以推测存放在外部的Mysql Sharding集群中,图片系统的读取操作同时带有图片id和逻辑卷轴两个参数。
Haystack Directory的实现较为简单,采用Replicated Database做持久化存储,前面增加一个Memcache集群满足查询需求。
(2) Haystack Store
(a)图片存储
haystack store的存储方式应该是比较适合小文件的[小文件也应该普遍使用这种方式]。以一个文件一个文件形式来存储小文件,效率比较低。所以使用一个大文件来存储.HayStack中的图片顺序的存放在大文件中,获取图片在大文件中的偏移即可读取图片,图片的存储结构如下所示(每张图片称为一个needle)。
(b)索引问题
如何查找定位最终读取文件内容呢?
HayStack为每张图在内存中维护图片与其实际内容位置的映射表来索引图片,在图片被写入时更新映射关系,每次系统启动时可通过读取物理卷并构造映射表,但这样做很耗时间,HayStack通过为每张图片构造index并存放在index file中的方式来简化了系统启动时映射表的构建,index file的结构如下所示:(其主要包含key与对应图片位置的映射关系,系统启动时,通过读取index file便能很快的构造映射表。)
结合数据分析:多个图片文件存放在一个物理卷轴中,每个图片文件是一个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。
综合性能的可用性haystack store引入以下两个亮点
- 写操作首先更新物理卷轴文件,然后异步更新索引文件。由于更新索引文件是异步的,可能出现索引文件和物理卷轴文件不一致的情况,不过由于对物理卷轴文件和索引文件的操作都是Append操作,只需要扫描物理卷轴文件最后写入的几个Needle补全索引文件即可。这种技术在Append-only的文件系统很常见。
- Haystack Store存储节点采用延迟删除的回收策略,删除图片仅仅往卷轴中追加一个带有删除标记的Needle,定时执行Compaction任务回收已删除空间。
- facebock使用 NVRAM,所以RAID的配置模式为 write back ,即写回到raid的内存即结束,所以写性能有较大的提升
(3)经验与思考
1:文中说道对象存储的设计思想。The Haystack Directory and Store are perhaps most similar to the File and Storage Manager concepts,respectively, in NASD that separate the logical storage units from the physical ones。
2:思想不能太固化,很多本地文件系统一般都是以gerneral purpose为目的而设计的。对于special purpse的存储系统很多时候显然捉襟见肘,不尽人意,另外对存储系统有比较全面了解才能设计高性能的 special storage system
(4)资料
1:英文论文:http://www.google.com.hk/url?sa=t&rct=j&q=Finding+a+needle+in+Haystack&source=web&cd=1&ved=0CCcQFjAA&url=http%3A%2F%2Fwww.usenix.org%2Fevent%2Fosdi10%2Ftech%2Ffull_papers%2FBeaver.pdf&ei=bMQCT4vZJMeviQea9anTAQ&usg=AFQjCNGBpnEQ6S2uVDEuDX5KeV5bEKeY0w
2:中文分析:http://www.nosqlnotes.net/archives/116
这篇关于Facebook photo-storage [haystack]的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!