Facebook兆级别图片存储及每秒百万级别图片查询原理
前言
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,可以完全避免检索文件系统导致的磁盘操作。
Facebook兆级别图片存储及每秒百万级别图片查询原理的更多相关文章
- 如何生成每秒百万级别的 HTTP 请求?
第一篇:<如何生成每秒百万级别的 HTTP 请求?> 第二篇:<为最佳性能调优 Nginx> 第三篇:<用 LVS 搭建一个负载均衡集群> 本文是构建能够每秒处理 ...
- epoll的内部实现 & 百万级别句柄监听 & lt和et模式非常好的解释
epoll是Linux高效网络的基础,比如event poll(例如nodejs),是使用libev,而libev的底层就是epoll(只不过不同的平台可能用epoll,可能用kqueue). epo ...
- 使用表类型(Table Type-SqlServer)实现百万级别的数据一次性毫秒级别插入
使用表类型(Table Type)实现百万级别的数据一次性插入 思路 1 创建表类型(TaBleType) 2 创建添加存储过程 3 使用C#语言构建一个DataTab ...
- JAVA使用POI如何导出百万级别数据(转)
https://blog.csdn.net/happyljw/article/details/52809244 用过POI的人都知道,在POI以前的版本中并不支持大数据量的处理,如果数据量过多还会 ...
- JAVA使用POI如何导出百万级别数据
用过POI的人都知道,在POI以前的版本中并不支持大数据量的处理,如果数据量过多还会常报OOM错误,这时候调整JVM的配置参数也不是一个好对策(注:jdk在32位系统中支持的内存不能超过2个G,而在6 ...
- JAVA使用POI如何导出百万级别数据(转载)
用过POI的人都知道,在POI以前的版本中并不支持大数据量的处理,如果数据量过多还会常报OOM错误,这时候调整JVM的配置参数也不是一个好对策(注:jdk在32位系统中支持的内存不能超过2个G,而在6 ...
- Excel如何快速渲染百万级别的数据
Excel主要经历1.查询2.渲染的方式 关于查询: 不同技术水平的人有不同的解决方案,目前我采用的是 1:多线程查询 2:一个异步后台线程每次查询100条便渲染,采用的“懒加载方式”,这样可以做到实 ...
- 百万级别数据Excel导出优化
前提 这篇文章不是标题党,下文会通过一个仿真例子分析如何优化百万级别数据Excel导出. 笔者负责维护的一个数据查询和数据导出服务是一个相对远古的单点应用,在上一次云迁移之后扩展为双节点部署,但是发现 ...
- oracle count 百万级 分页查询记要总数、总条数优化
oracle count 百万级 分页查询记录总数.总条数优化 oracle count 百万级 查询记录总数.总条数优化 最近做一个项目时,做分页时,发现分页查询速度很慢,分页我做的是两次查询,一次 ...
随机推荐
- dwr3+spring实现消息实时推送
最近项目要实现一个消息推送的功能,主要就是发送站内信或者系统主动推送消息给当前在线的用户.每次的消息内容保存数据库,方便用户下次登录后也能看到.如果当前用户在线,收到站内信就主动弹出提示.一开始想到的 ...
- Centos中hive/hbase/hadoop/mysql实际操作及问题总结
目录 Hive中文乱码问题 hive和hbase的版本不一致 Ambari hive插入Hbase出错 Hive0.12和Hbase0.96不兼容,重新编译hive0.12.0 hiveserver不 ...
- linux 存储技术 部署iSCSI NFS Multipath多路径
存储技术应用存储是根据不同的应用环境通过采取合理,安全,有效的方式将数据保存到某些介质上并能保证有效的访问另一方面,它是保证数据完整安全存放的方式或行为存储就是把这两方面结合起来,向客户提供一套数据存 ...
- linux虚拟化概述
虚拟化硬件虚拟化:一台物理机虚拟出多台逻辑上的计算机cpu,内存可分配给多个虚拟机软件虚拟化:一个LAMP平台支撑多个网站桌面虚拟化...... 虚拟机:通过软件平台模拟出的计算机对最终用户来说,感受 ...
- PyQt5多点触控写字板实现及困惑
Qt支持程序多点触控,就想使用PyQt5做一个触控画板,经过几番周折,查阅了TouchEvent官方文档,又参考了一篇QT for Android的例子,采用eventfilter过滤器来识别触屏事件 ...
- 使用simhash库来进行网页去重
首先感谢作者yanyiwu贡献的开源项目https://github.com/yanyiwu/simhash.在做项 目过程中,翻了一遍<这就是搜索引擎 核心技术详解>这本书的查重算法, ...
- Windows下基于ADS+J-Link 的ARM开发环境搭建
在一般ARM编程教学和实验环境里,一般采用 ADS加+并口转Jtag板+H-Jtag的开发环境.但是这种方法最大缺点是需要机器上有一个并口.现在无论PC还是笔记本都很难有并口,因此采用USB接口调试器 ...
- 问题解决了,可是为什么呢?could not find the main class.program will exitmain
今天重新学习socket编写简单的在线聊天,简单功能实现的情况下,一时心血来潮便想要把这程序打成可执行的jar包,以便于在桌面直接双击运行. 参照自己之前写的那篇<>打好两个jar包以后却 ...
- Flex中的FusionCharts 四图监听
<?xml version="1.0" encoding="utf-8"?> <s:Application xmlns:fx="ht ...
- setsockopt()用法(参数详细说明) recv、send的超时处理
源于recv send 阻塞和非阻塞 int setsockopt(SOCKET s,int level,int optname,const char* optval,int optlen); s(套 ...