wink

有的鸟是不会被关住的, 因为它们的羽毛太耀眼了.

  • main

wink

有的鸟是不会被关住的, 因为它们的羽毛太耀眼了.

  • main

facebook图片存储之Haystack

2016-04-11

论文在: 这里

一个golang开源版本实现: seaweed-FS

毛剑的版本叫bfs

动机

facebook原来的方案是把图片存在NFS上, 由于细小的文件太多, NFS的metadata比较大(which is hundreds of bytes large), 导致了无法把metadata都cache到内存中, 而且每次要读取一个图片, 至少需要3次磁盘IO, 第一次读取目录元信息, 第二次读取inode, 第三次读取图片

而且对于facebook的图片请求, 存在很多long tail请求, 就是很长时间以来都很冷门的图片.(个人相册并不是热门数据), 这就会导致很多请求都不能命中CDN或者自身的cache, 直接落到了磁盘.

所以它们做了haystack

haystack设计

haystack 减少了metadata的大小, 让所有的metadata都保存在内存中, 这样所有图片读取就只需要一次的磁盘IO

架构

核心组件:Haystack Directory, Haystack cache, Haystack store

Alt text

Store是由物理卷组成的,容量由物理卷的数量来控制,100个物理卷可提供10TB的存储空间(100G/volumn)。物理卷还会组合成一个逻辑卷,单个逻辑卷中的所有物理卷数据是相同的,冗余。Directory主要保存应用方面的数据信息,例如每张图片存放在哪个逻辑卷上,还有逻辑卷到物理卷的映射以及逻辑卷的剩余空间。Cache相当于一个内部的CDN。

获取图片的过程

Web Server会请求Haystack Directory为该图片生成相应的url, url格式如下:

1
http://CDN/Cache/Machine-id/<Logical-volume,Photo>

CDN部分指定了CDN的地址, CDN可以通过<Logical-volume,Photo>来找到cached在CDN的图片. 如果找不到, 那么它会通过这个URL中的Cache来把请求发到Haystack Cache组件, Cache组件做跟CDN类似的操作, 用<Logical-volume,Photo>查找图片, 如果找不到, 继续缩短url, 变成Machine-id, 去访问Store Machine.

当然, 请求也可以直接发到Haystack Cache, 这个由Haystack Directory来决定(因为URL是其生成的)

上传图片

Alt text

从 Haystack Directory请求一个 write-enabled的logical volumn, 然后web Server指定一个唯一的id给图片, 然后把它上传到逻辑卷相应的物理卷上去(通常是三个副本)

Haystack Directory

Directory提供四个主要功能:

  1. 提供Logical volume到physical volumes的映射关系 . Web Server在上传图片的时候利用这个映射关系以及在构建image URLs的时候.
  2. 负载均衡
  3. 决定图片请求是发到CDN还是发到Haystack Cache, 用来调整对CDN的依赖
  4. 那些达到容量限制的logical volumes或者为了易操作性, Directory将其标记为Read-only

Cache

分布式hash表,用图片id作为key定位cache数据。Cache只会在下面两种情况下都吻合的情况下才进行缓存:

  1. 请求来自用户而不是CDN
  2. 从可写的Store机器上读取的数据

对于1:CDN和cache其实是一样的。
对于2:为了保护可写Store机器,有两点,其一,通常新数据都会有较大的访问,其二,我们设计的filesystem在只读或者只写的时候会有更好的性能。

Haystack Store

每一个Store Machine管理着多个physical volumes. 你可以把physical volume想象成一个非常大的文件(100GB), 类似这种格式/hay/haystack_<logical volume id>. Store Machine可以快速地通过logical volume id和相应的file offset访问到图片. 这个认知对于Haystack来说是是里程碑式的: 通过文件名, offset和文件大小来获取指定的图片而不需要磁盘操作.

Haystack Store的文件格式如下:

Alt text

每个field的意义如下:
Alt text

cache到store读:

请求数据:logical volume id, key, alternate key, cookie

cache到store写:

上述 + data。数据是append-only的,对于某些修改,比如旋转,允许在原needle上修改,否则其余所有的修改都会以相同的key和alternate key追加一个needle,如果新的needle被追加到别的逻辑卷里,这些信息会被Directory感知,旧卷上的needle永远都不会被访问到了。如果是追加到相同的逻辑卷里, 那么会以file offset来区分, 更大的offset表示这是一个更新的图片

cache到store删除:

设置flags标志。是在compaction的时候回收这些删除的空间, 并且合并一些重复的图片(update导致)

索引

为了加快系统启动速度,store机器对每个卷都维护一个index文件。实际上是内存索引某个时刻的checkpoint。

Alt text

会引入问题:index文件可能是旧的。比如当delete照片时,是设置flag而没有升级index,index的升级是异步的,这样可以让写请求快速返回。
需要解决两个副作用:needles可能存在但没有对应的index记录,或者index记录没有反映出delete标志。
解决办法:

对于第一个副作用,系统启动时,从卷尾部往头部扫描,补充index。因为没有index的needles肯定是在最后追加的。
对于第二个副作用,延迟处理,也就是说没人读的话就不管它,有人读时再判断并更新index。

文件系统

根据Haystack的设计,对文件系统的需求是:不需要太多内存(例如保存文件的filemeta数据),在大文件里快速的随机seek。Haystack 选用的是XFS,好处:

  • blockmaps很小
  • 预分配,减少碎片等等。
赏

thanks

  • haystack
  • facebook
  • paper
  • tech

扫一扫,分享到微信

微信分享二维码
PingCAP 2018 校园招聘
etcd client DNS Discovery
© 2019 wink