手机浏览 RSS 2.0 订阅 膘叔的简单人生 , 腾讯云RDS购买 | 超便宜的Vultr , 注册 | 登陆
浏览模式: 标准 | 列表Tag:老王

Facebook图片管理架构(转帖学习一下)

Facebook 的照片分享很受欢迎,迄今,Facebook 用户已经上传了150亿张照片,加上缩略图,总容量超过1.5PB,而每周新增的照片为2亿2000万张,约25TB,高峰期,Facebook 每秒处理55万张照片,这些数字让如何管理这些数据成为一个巨大的挑战。本文由 Facebook 工程师撰写,讲述了他们是如何管理这些照片的。

旧的 NFS 照片架构
老的照片系统架构分以下几个层:
# 上传层接收用户上传的照片并保存在 NFS 存储层。
# 照片服务层接收 HTTP 请求并从 NFS 存储层输出照片。
# NFS存储层建立在商业存储系统之上。

因为每张照片都以文件形式单独存储,这样庞大的照片量导致非常庞大的元数据规模,超过了 NFS 存储层的缓存上限,导致每次招聘请求会上传都包含多次I/O操作。庞大的元数据成为整个照片架构的瓶颈。这就是为什么 Facebook 主要依赖 CDN 的原因。为了解决这些问题,他们做了两项优化:
# Cachr: 一个缓存服务器,缓存 Facebook 的小尺寸用户资料照片。
# NFS文件句柄缓存:部署在照片输出层,以降低 NFS 存储层的元数据开销。

新的 Haystack 照片架构
新的照片架构将输出层和存储层合并为一个物理层,建立在一个基于 HTTP 的照片服务器上,照片存储在一个叫做 haystack 的对象库,以消除照片读取操作中不必要的元数据开销。新架构中,I/O 操作只针对真正的照片数据(而不是文件系统元数据)。haystack 可以细分为以下几个功能层:
# HTTP 服务器
# 照片存储
# Haystack 对象存储
# 文件系统
# 存储空间

存储
Haystack 部署在商业存储刀片服务器上,典型配置为一个2U的服务器,包含:
# 两个4核CPU
# 16GB – 32GB 内存
# 硬件 RAID,含256-512M NVRAM 高速缓存
# 超过12个1TB SATA 硬盘

每个刀片服务器提供大约10TB的存储能力,使用了硬件 RAID-6, RAID 6在保持低成本的基础上实现了很好的性能和冗余。不佳的写性能可以通过高速缓存解决,硬盘缓存被禁用以防止断电损失。
文件系统
Haystack 对象库是建立在10TB容量的单一文件系统之上。文件系统中的每个文件都在一张区块表中对应具体的物理位置,目前使用的文件系统为 XFS。
Haystack 对象库
Haystack 是一个简单的日志结构,存储着其内部数据对象的指针。一个 Haystack 包括两个文件,包括指针和索引文件:

大小: 17.5 K
尺寸: 500 x 231
浏览: 3357 次
点击打开新窗口浏览全图

Haystack 对象存储结构

大小: 36.73 K
尺寸: 500 x 232
浏览: 3442 次
点击打开新窗口浏览全图

大小: 11.91 K
尺寸: 432 x 154
浏览: 3743 次
点击打开新窗口浏览全图

指针和索引文件结构

Haystack 写操作
Haystack 写操作同步将指针追加到 haystack 存储文件,当指针积累到一定程度,就会生成索引写到索引文件。为了降低硬件故障带来的损失,索引文件还会定期写道存储空间中。

Haystack 读操作
传到 haystack 读操作的参数包括指针的偏移量,key,代用Key,Cookie 以及数据尺寸。Haystack 于是根据数据尺寸从文件中读取整个指针。

Haystack 删除操作
删除比较简单,只是在 Haystack 存储的指针上设置一个已删除标志。已经删除的指针和索引的空间并不回收。

照片存储服务器
照片存储服务器负责接受 HTTP 请求,并转换成相应的 Haystack 操作。为了降低I/O操作,该服务器维护着全部 Haystack 中文件索引的缓存。服务器启动时,系统就会将这些索引读到缓存中。由于每个节点都有数百万张照片,必须保证索引的容量不会超过服务器的物理内存。

对于用户上传的图片,系统分配一个64位的独立ID,照片接着被缩放成4种不同尺寸,每种尺寸的图拥有相同的随机 Cookie 和 ID,图片尺寸描述(大,中,小,缩略图)被存在代用key 中。接着上传服务器通知照片存储服务器将这些资料联通图片存储到 haystack 中。

每张图片的索引缓存包含以下数据

大小: 15.81 K
尺寸: 500 x 178
浏览: 3648 次
点击打开新窗口浏览全图

Haystack 使用 Google 的开源 sparse hash data 结构以保证内存中的索引缓存尽可能小。
照片存储的写/修改操作
写操作将照片数据写到 Haystack 存储并更新内存中的索引。如果索引中已经包含相同的 Key,说明是修改操作。

照片存储的读操作
传递到 Haystack 的参数包括 Haystack ID,照片的 Key, 尺寸以及 Cookie,服务器从缓存中查找并到 Haystack 中读取真正的数据。

照片存储的删除操作
通知 Haystack 执行删除操作之后,内存中的索引缓存会被更新,将便宜量设置为0,表示照片已被删除。

重新捆扎
重新捆扎会复制并建立新的 Haystack,期间,略过那些已经删除的照片的数据,并重新建立内存中的索引缓存。

HTTP 服务器
Http 框架使用的是简单的 evhttp 服务器。使用多线程,每个线程都可以单独处理一个 HTTP 请求。

结束语
Haystack 是一个基于 HTTP 的对象存储,包含指向实体数据的指针,该架构消除了文件系统元数据的开销,并实现将全部索引直接存储到缓存,以最小的 I/O 操作实现对照片的存储和读取。

本文国际来源:http://www.facebook.com/FacebookEngineering#/note.php?note_id=76191543919&ref=mf

中文翻译来源:COMSHARP CMS 官方网站

我的来源:http://zys.8800.org/index.php/archives/334

Tags: facebook, 架构

思考:内部博客历史上的今天

我这里说的历史上的今天并非网络上那种把几千年几百年的事情显示的那种历史上的今天,我说的是当某一个网站建站时间长后,数据量大的时候,可以开始考虑把前几年同一时刻发表的文章列出来。

我对于这个想法,在考虑用yii重构的时候就想过是否要加这个功能。虽然说这是画蛇添足,但在自己看自己的文章时,看到一年前两年前的文章时,你也可以了解到自己的思想到底有没有进步。去年这个时间你是在写一些垃圾,还是在写一些精华,现在呢?还是垃圾又或者已经进步了?

但,说白了,这个玩意对于其他浏览的用户来说,真的没有什么特别的意义,相反还会有反感,我为什么要看你一年前的东西,我关注是当前的内容,如果对于当前的内容有相关的资料,那还可以值得考虑一下。所以TAG相关文章就很容易被点击。

所以,历史上的今天对于增加内链是有好处的,但不是特别建议推广。我的思考是做类似于widget之类的功能放在内容页【并非一定】。

相反,我对于TAG有新的要求,一个网站,尽量不要超过200个TAG,最好都是一些有效TAG,否则一定会让人迷惑。或者说,其实你的网站也很乱,内容越杂,TAG也才会越多。当你精确于某几件事情,你的TAG应该是相对集中的。

wordpress的TAG表,设计的非常有意思。考虑过使用。crc和crt,如果真重构了,应该会用到。

Tags: history, thinking

新的尝试。

在文章内容里加入了新的尝试,可以把页面分享至google reader;生成pdf;发送至wordpress,发送至live space。

看到很多网站有这个分享功能,我觉得我也是可以尝试一下。不知道是否有什么大用处,但或许能够有不一样的体验?
用官方的话来说,那就是:一个点击, 快速完成分享 常在开心网或人人网看到朋友转贴的精采文章及图片吗? 【分享】就是背后的大功臣,一个强大的网页分享插件,让您将喜欢的博文、新闻等内容快速分享到社群网络上。

但其实,我还是认为这样会反而使得自己的用户在流失,不过,我这也算是一个尝试,而且bshare.cn上面有统计。所以我想试上三个月,看看有没有什么特别的用处。

分享按钮在哪里呢?是在文章的底部啦

大小: 21.24 K
尺寸: 493 x 118
浏览: 1418 次
点击打开新窗口浏览全图

上面的四个按钮的顺序也是我精心挑选的。点击更多则可以分享到其他网站。其中google reader用了你自己的google帐号,如果处于登录状态,可以直接使用。生成pdf则不需要任何帐号【比较适合收藏文章】其他两个也是需要在本站输入帐号,但其实是在bshare.cn的JS代码中输入,所以我不能保证是否会有什么密码XXX的问题。官方和弹出窗的提示窗上也都说了不会收集密码等信息。。。

Tags: bshare, 分享

重拾:自己动手做一个最小的Linux kernel

文章来自至顶网,两年前的内容,只是感觉好象不错,就复制了过来。
原文链接如下:
http://soft.zdnet.com.cn/software_zone/2007/1022/570485.shtml
http://soft.zdnet.com.cn/software_zone/2007/1020/568251.shtml

很难想象,2居然比1先出来。

Linux 能有多小呢 ? 每一个做 embedded 系统的人都把小看成第一要务,其实这是不对的。小当然不会比较坏,但不一定比较好。如果系统使用 4MB 和 5MB 没有价格或性能上的差别,那 4MB 和 5MB 是一样好的。

到底有多小

废话说了一堆,那到底 Linux 有多小呢? 好吧,各位这么有小牛顿的精神。我也只好想办法生一个答案出来了。

首先我必须声明,我的不一定最小。不要说我在欺骗世人,你的核心比我小。我无意比较,我的数据只是给大家一个参考而己。不过我欢迎大家提出自己的心得,告诉大家怎么样做出更小的核心。

我使用的是 Mandrake 内付的 2.2.15,我没有修改任何一行程序码,完全只靠修改组态档得到这些数据。

首先,使用 make xconfig 把所有可以拿掉的选项都拿得。

不要 floppy;

不要 SMP,MTRR;

不要 networking,SCSI;

把所有的 block device 移除,只留下 old IDE device;

把所有的 character device 移除;

把所有的 filesystem 移除,只留下 minix;

不要 sound 支援。

相信我,我己经把所有的选项都移除了。这样做之后,我得到了一个 188K 的核心。 还不够小吗? OK,再加上一招,请把下列二个档案中的 -O3,-O2 用 -Os 取代。

 

./Makefile 
./arch/i386/kernel/Makefile

这样一来,整个核心水小了 9K,成为 179K。不过这个核心恐怕很难发挥 Linux 的功能,因此我决定把网络加回去。把 General 中的 network support 加回去,重新编译,核心变成 189 K。10K 换个 TCP/IP stack,似乎是很上算的生意。不过有 stack 没有 driver 也是惘然,所以我把 embedded board 常用的 RTL8139 的 driver 加回去,195K。

如果你需要 DOS 档案系统,那大小成为 213K。如果 minix 用 ext2 换代,则大小成长至 222K。不过大家要注意,那里的大小指的是核心档的大小。那和所需要的随取记忆体是二回事。这个数字代表的意义是你需要多小的 ROM 来存放你的核心。

Linux 所需的记忆体大约在 600~800 K 之间。1MB 可能可以开机了,但可能不太有用。因为可能连载入 C 程序库都有困难。2MB 应该就可以做点事了,但可能要到 4MB 以上才可以执行一个比较完整的系统。

到底谁占了这些空间

看到这里,是不是觉得 Linux 真的有点大。好吧! 那我们就来看看谁占用了这些空间,下面这个列表是从 222K 这个核心做出来的。

 

# wc  
arch/i386/kernel/kernel.o arch/i386/mm/mm.o kernel/kernel.o mm/mm.o fs/fs.o
ipc/ipc.o
fs/filesystems.a
net/network.a
drivers/block/block.a
drivers/char/char.a
drivers/misc/misc.a
drivers/net/net.a drivers/pnp/pnp.a
/usr/src/smalllinux/arch/i386/lib/lib.a
/usr/src/smalllinux/lib/lib.a
/usr/src/smalllinux/arch/i386/lib/lib.a

结果如下 :

 

243 2250 81946 arch/i386/kernel/kernel.o 
42 316 10569 arch/i386/mm/mm.o
173 1541 74660 kernel/kernel.o
266 2307 68053 mm/mm.o
222 3139 123193 fs/fs.o
49 602 21600 ipc/ipc.o
263 2940 106504 fs/filesystems.a
137 1510 65512 net/network.a
92 719 39178 drivers/block/block.a
230 2308 87556 drivers/char/char.a
1 1 8 drivers/misc/misc.a
83 721 25680 drivers/net/net.a
1 1 8 drivers/pnp/pnp.a
20 187 9526 /usr/src/smalllinux/arch/i386/lib/lib.a
23 150 7714 /usr/src/smalllinux/lib/lib.a
20 187 9526 /usr/src/smalllinux/arch/i386/lib/lib.a
1865 18879 731233 total

先说明一下,这里的大小和最终的大小有点差别,但大致还是可以做个参考。这边显示 730K 实际上大约在 600K 左右。

很显然的,filesystem 相当的大。大约在 230K 左右,占了 1/3 的体积。记忆体管理占了 80K,和核心其它部份的总合差不多。TCP/IP stack 占了 65K,驱动程序占了 120K。SysV IPC 占了 21K,必要的话可以拿掉,核心档应该可以再小个 10K 左右。

所以如果要减核心大小,应该动那里呢? 答案应该很明显,当然是档案系统。Linux 的 VFS 减化了档案系统的设计,buffer cache, directory cache 增加了系统的效率。但这些对整个系统都在 flash 上的 embedded 系统而言根本就用处不大。如果可以把它们对拿掉,核心可以马上缩小 20K 左右。如果跳过整个 VFS,直接将档案系统写成一个 driver 的型式,应该可以将 230K 缩减至 50K左右。整个核心缩到 100K 左右。

从上面的数据来看,ucLinux 所减小的 mm 部份反到省的不多,主要是 mm 除了 virtual memory 之外,也要处理 memory allocation 的部份,这部份是省不得的。如果二者齐做,则 100K 以下的 Linux 核心不是不可能的事。

结语

如果有人有闲的话,不妨拿 2.0 或 1.0 的核心来试试。看能做出多小的核心。看完本文后,143K 的核心不再是技术上的挑战了,是吗? 也许明天就有人宣称做了 120K 的核心了。不过,所为何来,省那几十K。不如好好想想 compressed filesystem 等更有用的技术吧!

Tags: linux, kernel