通过接触有关海量资料处理和搜索引擎的诸多技术,常常见识到不少精妙绝伦的架构图。除了每每感叹于每幅图表面上的绘制的精细之外,更为架构图背后所隐藏的设计思想所叹服。个人这两天一直在搜集各大型网站的架构设计图,一为了一饱眼福,领略各类大型网站架构设计的精彩之外,二来也可供闲时反复琢磨体会,何乐而不为呢? 特此,总结整理了诸如国外 wikipedia,Facebook,Yahoo!,YouTube,MySpace,Twitter,国内如优酷网等大型网站的技术架构(本文重点分析优酷网的技术架构),以飨读者。
本文着重凸显每一幅图的精彩之处与其背后含义,而图的说明性文字则从简从略。 ok,好好享受此番架构盛宴吧。当然,若有任何建议或问题,欢迎不吝指正。谢谢。

1 、 WikiPedia 技术架构

WikiPedia 技术架构图 Copy @Mark Bergsma

来自 wikipedia 的资料:峰值每秒钟 3 万个 HTTP 请求 每秒钟 3Gbit 流量, 近乎 375MB 350 台 PC 服务器。

GeoDNSA :40-line patch for BIND to add geographical filters support to the existent views in BIND”, 把多用户带到近的服务器。 GeoDNS 在 WikiPedia 架构中担当重任当然是由 WikiPedia 的内容性质决定的– 面向各个国家,各个地域。

负载均衡:LVS,请看下图:

2 、 Facebook 架构

Facebook 搜索功能的架构示意图

细心的读者一定能发现,上副架构图之前出现在此文之中:从几幅架构图中偷得半点海里资料处理经验。本文与前文大的不同是,前文只有几幅,此文系列将有上百幅架构图,任您尽情观赏。

3 、 Yahoo! Mail 架构

Yahoo! Mail 架构

Yahoo! Mail 架构部署了 Oracle RAC,用来储存 Mail 服务相关的 Meta 资料。

4 、 twitter 技术架构

twitter 的整体架构设计图

twitter 平台大致由 twitter.com 、手机以及第三方应用构成,如下图所示(其中流量主要以手机和第三方为主要来源):

快取在大型 web 专案中起到了举足轻重的作用,毕竟资料越靠近 CPU 存取速度越快。下图是 twitter 的快取架构图:

关于快取系统,还可以看看下幅图:

5 、 Google WordPress APP Engine 技术架构

GAE 的架构图

简单而言,上述 GAE 的架构分为如图所示的三个部分:前端,Datastore 和服务群。

前端包括 4 个模组:Front End,Static Files,WordPress APP Server,WordPress APP Master 。

Datastore 是基于 BigTable 技术的分散式资料库,虽然其也可以被理解成为一个服务,但是由于其是整个 WordPress APP Engine 储存持久化资料的地方,所以其是 WordPress APP Engine 中一个非常核心的模组。其具体细节将在下篇和大家讨论。

整个服务群包括很多服务供 WordPress APP Server 呼叫,比如 Memcache,图形,多用户,URL 抓取和任务伫列等。

6 、 Amazon 技术架构

Amazon 的 Dynamo Key-Value 储存架构图

可能有读者并不熟悉 Amazon,它现在已经是全球商品品种多的网上零售商和全球第 2 大互联网公司。而之前它仅仅是一个小小的网上书店。 ok,下面,咱们来见识下它的架构。
Dynamo 是亚马逊的 key-value 模式的储存平台,可用性和扩充套件性都很好,效能也不错:读写访问中 99.9% 的响应时间都在 300ms 内。按分散式系统常用的杂凑演算法切分资料,分放在不同的 node 上。 Read 操作时,也是根据 key 的杂凑值寻找对应的 node 。 Dynamo 使用了 Consistent Hashing 演算法,node 对应的不再是一个确定的 hash 值,而是一个 hash 值范围,key 的 hash 值落在这个范围内,则顺时针沿 ring 找,碰到的个 node 即为所需。
Dynamo 对 Consistent Hashing 演算法的改进在于:它放在环上作为一个 node 的是一组机器(而不是 memcached 把一台机器作为 node),这一组机器是通过同步机制保证资料一致的。
下图是分散式储存系统的示意图,读者可观摩之:

Amazon 的云架构图如下:

Amazon 的云架构图

7 、优酷网的技术架构

从一开始,优酷网就自建了一套 CMS 来解决前端的页面显示,各个模组之间分离得比较恰当,前端可扩充套件性很好,UI 的分离,让开发与维护变得十分简单和灵活,下图是优酷前端的模组呼叫关系:

这样,就根据 module 、 method 及 params 来确定呼叫相对独立的模组,显得非常简洁。下图是优酷的前端区域性架构图:

优酷的资料库架构也是经历了许多波折,从一开始的单台 MySQL 服务器(Just Running)到简单的 MySQL 主从复制、 SSD 优化、垂直分库、水平 sharding 分库。

简单的 MySQL 主从复制。
MySQL 的主从复制解决了资料库的读写分离,并很好的提升了读的效能,其原来图如下:
其主从复制的过程如下图所示:
但是,主从复制也带来其他一系列效能瓶颈问题:

写入无法扩充套件

写入无法快取

复制延时

锁表率上升

表变大,快取率下降

那问题产生总得解决的,这就产生下面的优化方案。

MySQL 垂直分割槽
如果把业务切割得足够独立,那把不同业务的资料放到不同的资料库服务器将是一个不错的方案,而且万一其中一个业务崩溃了也不会影响其他业务的正常进行,并且也起到了负载分流的作用,大大提升了资料库的吞吐能力。经过垂直分割槽后的资料库架构图如下:
然而,尽管业务之间已经足够独立了,但是有些业务之间或多或少总会有点联络,如多用户,基本上都会和每个业务相关联,况且这种分割槽方式,也不能解决单张表资料量暴涨的问题,因此为何不试试水平 sharding 呢?

MySQL 水平分片(Sharding)
这是一个非常好的思路,将多用户按一定规则(按 id 杂凑)分组,并把该组多用户的资料储存到一个资料库分片中,即一个 sharding,这样随着多用户数量的增加,只要简单地配置一台服务器即可,原理图如下:
如何来确定某个多用户所在的 shard 呢,可以建一张多用户和 shard 对应的资料表,每次请求先从这张表找多用户的 shard id,再从对应 shard 中查询相关资料,如下图所示: 但是,优酷是如何解决跨 shard 的查询呢,这个是个难点,据介绍优酷是尽量不跨 shard 查询,实在不行通过多维分片索引、分散式搜索引擎,下策是分散式资料库查询(这个非常麻烦而且耗效能)。

快取策略
貌似大的系统都对 “快取” 情有独钟,从 http 快取到 memcached 记忆体资料快取,但优酷表示没有用记忆体快取,理由如下:

避免记忆体拷贝,避免记忆体锁

如接到老大哥通知要把某个视讯撤下来,如果在快取里是比较麻烦的

而且 Squid 的 write() 多用户程序空间有消耗,Lighttpd 1.5 的 AIO(非同步 I/O) 读取档案到多用户记忆体导致效率也比较低下。
但为何我们访问优酷会如此流畅,与土豆相比优酷的视讯载入速度略胜一筹?这个要归功于优酷建立的比较完善的内容分发网络(CDN),它通过多种方式保证分布在全国各地的多用户进行就近访问——多用户点选视讯请求后,优酷网将根据多用户所处地区位置,将离多用户近、服务状况知名的视讯服务器地址传送给多用户,从而保证多用户可以得到快速的视讯体验。这就是 CDN 带来的优势,就近访问。