前言
Facebook(后面简称 fb) 是世界最大的社交平台, 需要存储的数据时刻都在剧增 (占比最大为图片, 每天存储约 20 亿张, 大概是微信的三倍)
那么问题来了, fb 是如何存储兆级别的图片? 并且又是如何处理每秒百万级别的图片查询?
本文以简单易懂, 图文并茂的方式来解释其中的原理, 并不涉及空洞, 难解的框架, 也没有大篇章的废话铺陈, 只有痛点与反思; 就如同 fb 的架构师所说: fb 的存储架构就像高速公路上换轮胎, 没有最完美的设计, 我们最求的只是如何让它变得更简单
短篇介绍
fb 的图片存储系统叫做 HayStack, 目前已存储超过 120PB 的数据, 用户每天会上传 20 亿张图片 fb 图片搜索峰值, 需要提供每秒 100-200 万张的图片搜索这些数据还再不断地增加
稍微分析下用户使用场景, 图片写入一次, 频繁读取, 从不修改, 很少删除传统的文件系统: 每个图片都会有一些元数据, 在我们的需求中, 这些信息无用, 且浪费存储空间, 更大的性能消耗是文件的元数据需要从磁盘读到内存中来定位图片位置, 在 fb 的量级上, 元数据的吞吐量便是一个巨大的瓶颈
高吞吐量, 低延迟是 HayStack 所追求的, 所以 HayStack 希望每个图片读取操作至多需要一个磁盘, 并且减少每个图片的必要元数据, 并将它们保存至内存中为了做好容灾, HayStack 会将图片复制多张并保存至不通数据中心, 以确保不反回 404,error 给客户
典型的设计方案
上图为典型的设计方案:
1. 用户通过浏览器发送图片信息请求至 web server;2.web server 构造一个 url, 引导浏览器到对应位置下载图片; 3. 通常这个 url 指向一个 CDN, 如果 CDN 有缓存相关图片的话, 它会将图片立刻返回给浏览器; 4. 否则, 会解析 url, 并在 Photo Storage 中找到对应的图片; 5.6. 返回给用户
NAS-NFS
在 fb 的服务中, 只有 CDN 不足以解决全部需求, 对于新图片, 热门图片 CDN 确实很高效但是对于一些个人上传的老图片请求, CDN 基本上会全部命中失败, 又没有办法将图片全部缓存起来所以这里, 可以采用 NAS-NFS 来解决问题
基本操作与上面相同, 5.6.photo store server 解析 url 得出完整的卷和路径信息, 在 NFS 上读取数据, 然后返回给 CDN
这种设计的瓶颈: NFS 卷的每个目录下存储上千张图片, 导致读取时产生了过多的磁盘操作
HayStack
HayStack 架构包含 3 个核心组件: HayStack Store,HayStack Directory 和 HayStack Cache Store 是存储系统, 负责管理图片的元数据不同机器上的物理卷对应一个逻辑卷, HayStack 将一个图片保存至一个逻辑卷时, 那么图片便对应写入所有物理卷 Directory 维护了逻辑到物理卷的映射以及相应的元数据, 例如说, 某张图片保存在哪个物理卷里, 某个物理卷的存储空间等 Cache 的功能, 类似内部的 CDN, 它帮 Store 挡住热门搜索
上图描述了 3 个核心组件的相互作用在 HayStack 架构中, 浏览器的请求被引导至 CDN 中 (或 Cache 上),Cache 本质就是 CDN, 为了避免冲突, 我们使用 CDN 来表示外部系统, 使用 Cache 表示内部系统
1. 当用户发出请求给 web server,2.web server 使用 Directory 来构建图片的 url,3.4.5.6.7.8.9.10.url 包含一段信息, 如下:
http(s)://CDN/Cache/machine_id/volume_ID_Photo
一目了然, url 包含 CDN 地址信息, Cache 信息, 以及保存图片的物理卷 ID, 以及图片信息
图 4, 位用户上传图片的流程, 1. 用户发送请求至 web server;2.web server 请求 Directory 一个可用的逻辑卷, 物理卷, 并将图片信息记录下; 3. 将相关信息发送至 web server;4.web server 将图片上传至 Store;5. 返回成功信息
Directory
主要有 4 个功能:
1. 它提供了逻辑卷到物理卷的映射, web 服务器上传或读取图片时需要使用这个映射
2. 它在分配写请求, 读请求到物理卷时, 需保证负载均衡
3. 它决定一个图片的请求, 是发送至 CDN 或 Cache, 这个决定可以动态调整是否依赖 CDN
4. 它指定哪些卷是只读的
当我们增加 Store 的时候, 那些卷都是可写的, 可写的机器会收到上传信息当它们到达容量上限时, 标记它们为只读
Cache
Cache 的实现可以理解为一个分布式 Hash Table, 以图片 ID 为 key, 定位缓存的图片数据如果 Cache 未命中, 那么 Cache 则根据 URL 到指定的 Store 中, 读取图片数据
Store
很简单, 根据提供的一些元数据信息, 包括图片 ID, 逻辑卷 ID, 物理卷 ID, 找到对应的图片, 未找到则返回错误信息
下面简单描述一下物理卷与映射的结构, 一个物理卷可以理解为一个大型文件, 包含一系列的 needle, 每个 needle 就是一张图片如下图所示
为了快速索引 needle,Store 需要为每个卷提供一个内存中的 key-value 映射
HayStack 文件系统
HayStack 可以理解成基于 Unix 文件系统搭建的对象存储架构 Store 使用的文件系统是 XFS,XFS 有两个优点, 首先, XFS 中的临近大型文件的 blockmap 很小, 可放入内存存储再者, XFS 提供高效的文件预分配, 减少磁盘碎片问题使用 XFS, 可以完全避免检索文件系统导致的磁盘操作
来源: https://www.cnblogs.com/peiyu1988/p/8608194.html