|
4.3 Facebook Haystack
* b. X {9 E8 b4 H$ ?% AFacebook目前存储了2600亿张照片,总大小为20PB,通过计算可以得出每张照
3 B' G3 V f" P4 j9 S9 L, m片的平均大小为20PB/260GB,约为80KB。用户每周新增照片数为10亿(总大小为+ ^" P5 W, F" i4 |% \
60TB),平均每秒新增的照片数为10 9 /7/40000(按每天40000s计),约为每秒3500
" p- A7 Z H$ f& ?次写操作,读操作峰值可以达到每秒百万次。1 x+ Y2 Y5 h q3 v6 b2 D
Facebook相册后端早期采用基于NAS的存储,通过NFS挂载NAS中的照片文件来+ i+ @- V* K7 {& P. j
提供服务。后来出于性能和成本考虑,自主研发了Facebook Haystack存储相册数据。
[# B9 [. r# X+ D* ~4.3.1 系统架构
U3 h. W, T( iFacebook Haystack的思路与TFS类似,也是多个逻辑文件共享一个物理文件。
/ K- r5 E# D" F( W) m8 \Haystack架构及读请求处理流程如图4-6所示。 c; B" h) s, z0 w f
图 4-6 Haystack架构图
" b# a( r* n, H* w" ~3 W( rHaystack系统主要包括三个部分:目录(Directory)、存储(Store)以及缓存- s- `' X& {. F' Q4 p
(Cache)。Haystack存储是物理存储节点,以物理卷轴(physical volume)的形式组
& K) B% L+ {: k织存储空间,每个物理卷轴一般都很大,比如100GB,这样10TB的数据也只需100个
) R- U9 F2 ^. s* b物理卷轴。每个物理卷轴对应一个物理文件,因此,每个存储节点上的物理文件元
. z) U2 h6 g! g9 C' g3 n9 V5 {数据都很小。多个物理存储节点上的物理卷轴组成一个逻辑卷轴(logical
- {, C3 {* X5 W# Xvolume),用于备份。Haystack目录存放逻辑卷轴和物理卷轴的对应关系,以及照片
7 @; |" j& X# o8 W# B) h1 b* Qid到逻辑卷轴之间的映射关系。Haystack缓存主要用于解决对CDN提供商过于依赖的4 `3 r3 i, v4 ` D6 R P8 K
问题,提供最近增加的照片的缓存服务。6 L# E! F& n3 M1 |
Haystack照片读取请求大致流程为:用户访问一个页面时,Web服务器请求
8 T) x2 _ f% b5 ~) `7 a; EHaystack目录构造一个URL:http://<CDN>/<Cache>/<Machine id>/<Logical4 B7 K+ m8 l- R4 x& B
volume,Photo>,后续根据各个部分的信息依次访问CDN、Haystack缓存和后端的
8 Q6 l w) g: a3 g; xHaystack存储节点。Haystack目录构造URL时可以省略<CDN>部分从而使得用户直7 j- F; F1 P% ]( V9 t
接请求Haystack缓存而不必经过CDN。Haystack缓存收到的请求包含两个部分:用户6 l( A5 y1 Z: k4 G2 g( ?/ r
浏览器的请求及CDN的请求,Haystack缓存只缓存用户浏览器发送的请求且要求请求
u7 a) u' U' w9 I的Haystack存储节点是可写的。一般来说,Haystack后端的存储节点写一段时间以后( f/ P7 i' N, C% d
达到容量上限变为只读,因此,可写节点的照片为最近增加的照片,是热点数据。
' [ H( R$ g4 k9 Z! k4 Q本节暂不讨论CDN,只讨论Haystack后端存储系统,包括Haystack目录和Haystack缓' O/ T% B1 K1 C) P: C: @ F
存两个部分。
+ g! _9 x( A" s* u1.写流程
. j8 Z* Q" O- M( R: Q如图4-7所示,Haystack的写请求(照片上传)处理流程为:Web服务器首先请求, F# Q! F2 ^, ^5 B. q8 I, i2 q
Haystack目录获取可写的逻辑卷轴,接着生成照片唯一id并将数据写入每一个对应的
H% z* [$ s. p4 J2 f r5 ^物理卷轴(备份数一般为3)。写操作成功要求所有的物理卷轴都成功,如果中间出
0 ^+ z6 `* w9 \! ^) j/ o现故障,需要重试。7 m6 R( x/ _$ S9 s9 k( ~
图 4-7 Haystack写流程* N5 [: c2 n3 ?+ i8 i4 }
Haystack的一致性模型保证只要写操作成功,逻辑卷轴对应的所有物理卷轴都存: p& s7 e' @4 p! T M _
在一个有效的照片文件,但有效照片文件在不同物理卷轴中的偏移(offset)可能不
B$ K2 o" D: r6 u6 @同。( ?; ?& X N; \1 d8 j
Haystack存储节点只支持追加操作,如果需要更新一张照片,可以新增一张编号# b; w/ g/ r. H- M
相同的照片到系统中,如果新增照片和原有的照片在不同的逻辑卷轴,Haystack目录
& c- h9 K( p4 R& ^) @& F- L( x的元数据会更新为最新的逻辑卷轴;如果新增照片和原有的照片在相同的逻辑卷
b. z# r$ P$ |) A轴,Haystack存储会以偏移更大的照片文件为准。
6 v6 Z$ _; k# ^* B# ]2.容错处理; L; ]/ z) L5 q% g* ^
(1)Haystack存储节点容错, m& P) ^: D: z2 Z K
检测到存储节点故障时,所有物理卷轴对应的逻辑卷轴都被标记为只读。存储
/ m8 C6 n" K0 ]) c2 N节点上的未完成的写操作全部失败,写操作将重试;如果发生故障的存储节点不可8 r) R, f- I! K7 e7 {) h
恢复,需要执行一个拷贝任务,从其他副本所在的存储节点拷贝丢失的物理卷轴的8 e3 ^' z# [# @8 ]
数据;由于物理卷轴一般很大,比如100GB,所以拷贝的过程会很长,一般为小时3 X9 F7 L" a6 H
级别。
2 D. e/ s7 A. |/ Z/ a% b+ j(2)Haystack目录容错
3 r& z( |3 e: d$ i" n- }1 p& B' uHaystack目录采用主备数据库(Replicated Database)做持久化存储,由主备数据
( X- a' A O" a) n2 [. H) R& Y* R库提供容错机制。
B6 b2 E. t$ v0 Y1 O3.Haystack目录
, f/ n8 k& c; V5 _; {9 i& n4 hHaystack目录的功能如下:8 v, h5 k9 r0 P7 Z7 K
1)提供逻辑卷轴到物理卷轴的映射,维护照片id到逻辑卷轴的映射;
0 Q" [7 R3 V9 M4 V: O2)提供负载均衡,为写操作选择逻辑卷轴,读操作选择物理卷轴;
* I, [* K. K. o4 j1 Q3 Q6 L1 ]3)屏蔽CDN服务,可以选择某些图片请求直接走Haystack缓存;
7 W. D/ u2 |6 n! e4)标记某些逻辑卷轴为只读。
" B6 \6 R3 _( U6 l$ \( X- D- F _. v4 z根据前面的计算结果可知,Facebook相册系统每秒的写操作大约为3500次,每9 X) S' ~1 a6 W( C
秒的读请求大约为100万次。每个写请求都需要通过Haystack缓存获取可写的卷轴," X8 \- T' m1 ~
每个读请求需要通过Haystack缓存构造读取URL。这里需要注意,照片id到逻辑卷轴: m/ V( _) v6 _9 ]# h6 ]! @
的映射的数据量太大,单机内存无法存放,笔者猜测内部使用了MySQL Sharding集5 ?) v8 @. K6 m5 E7 E" K
群,另外,还增加了一个Memcache集群满足查询需求。
S( S+ n3 A* q. c2 L: }. I/ @4 \4.Haystack存储
% E) m( h% V- ^3 `0 u: {+ W9 z% PHaystack存储保存物理卷轴,每个物理卷轴对应文件系统中的一个物理文件,每7 z; p) X! b5 I7 L! o/ |
个物理文件的格式如图4-8所示。
' r: l# Z& p6 k5 v+ s# q% |+ }2 z图 4-8 Haystack数据块格式
6 \3 G: i0 T. S8 R% Y. B多个照片文件存放在一个物理卷轴中,每个照片文件是一个Needle,包含实际/ G' k& K/ t. m% G
数据及逻辑照片文件的元数据。部分元数据需要装载到内存中用于照片查找,包括: B0 t7 _0 j" ]5 T! v& S# |
Key(照片id,8字节),Alternate Key(照片规格,包括Thumbnail、Small、Medium% r" J, s& h' {
及Large,4字节),照片在物理卷轴的偏移Offset(4字节),照片的大小Size(4字. e+ @, V$ o0 @" @ t
节),每张照片占用8+8+4=20字节的空间,假设每台机器的可用磁盘为8TB,照片
4 n y9 C& L$ W+ F$ U& u" c平均大小为80KB,单机存储的照片数为8TB/80KB=100MB,占用内存
; _- q# |5 X' I" X100MB×20=2GB。
* Z d, A0 C! ] b7 X存储节点宕机时,需要恢复内存中的逻辑照片查找表,扫描整个物理卷轴耗时
# H. }/ `3 L1 J6 Q太长,因此,对每个物理卷轴维护了一个索引文件(Index File),保存每个Needle
2 m. r; U* i& b- q6 k4 C查找相关的元数据。写操作首先更新物理卷轴文件,然后异步更新索引文件。由于4 l% v* n6 H, w; }5 p! `
更新索引文件是异步的,所以可能出现索引文件和物理卷轴文件不一致的情况,不+ A2 v8 h5 O* |6 V
过由于对物理卷轴文件和索引文件的操作都是追加操作,只需要扫描物理卷轴文件
}! Z3 q1 Y" N8 z; X最后写入的几个Needle,然后补全索引文件即可。这种技术在仅支持追加的文件系
: L$ C! `& [8 k! T* B2 @! L统很常见。
' K5 S( a+ W9 |2 x& IHaystack Store存储节点采用延迟删除的回收策略,删除照片只是向卷轴中追加
* }" `9 J- ]' a8 |0 X6 j一个带有删除标记的Needle,定时执行Compaction任务回收已删除空间。所谓) g- B9 A- H" u9 P, @
Compaction操作,即将所有老数据文件中的数据扫描一遍,以保留最新一个照片的原
+ W% N( O5 p+ ^' {1 L则进行删除,并生成新的数据文件。
+ r1 o6 M/ N/ h; Y& X' v4.3.2 讨论- N+ V T. W, R' B9 @# D- j. v
相比TFS,Haystack的一大特色就是磁盘空间回收。Blob文件在TFS中通过<Block
, |6 T4 R$ T/ ] E+ did,Block offset>标识,因此,不能对TFS中的数据块进行重整操作;而Haystack中的
3 x0 P. E- J$ J* ~元信息只能定位到Blob文件所在的逻辑卷轴,Haystack存储节点可以根据情况对物理
% `" `+ i" |" D9 c卷轴进行Compaction操作以回收磁盘空间。# r! n. `% B, ]' G! a) j9 w
Facebook Haystack中每个逻辑卷轴的大小为100GB,这样减少了元信息,但是增
6 ?8 {9 V2 S' z0 l, `加了迁移的时间。假设限制内部网络带宽为20MB/s,那么迁移100GB的数据需要的
: }! Y& i1 O- X7 b% v! \. W& G; H时间为100GB/20MB/s=5000s,大约是一个半小时。而TFS设计的数据规模相比
) P9 j1 u0 i' `3 ^6 ZHaystack要小,因此,可以选择64MB的块大小,有利于负载均衡。
( b6 i3 \. x2 t6 H* x) y4 T& I' l$ j另外,Haystack使用RAID 6,并且底层文件系统使用性能更好的XFS,淘宝TFS8 i- a+ U/ H- a# u
不使用RAID机制,文件系统使用Ext3,由应用程序负责管理多个磁盘。Haystack使用* N; w: N y# U" p9 _. n
了Akamai&Limelight的CDN服务,而淘宝已经使用自建的CDN,当然,Facebook也在
1 |* r/ b' M9 f0 N考虑自建CDN。4 d. b* S! R9 u) s, _: k) m. i
9 i/ f9 U# m9 K& x2 x9 y/ L* l4 T* t' x
|
|