文 / 林昊
互联网已经发展多年,其中不乏脱颖而出者,这些网站多数都已存在了接近10年或10年以上,在如此长时间的发展过程中,除了业务上面临的挑战,在技术上也面临了很多的挑战。我挑选了一些Alexa排名较前的网站(排名截止到2012年4月21日),看看它们在技术上是如何应对业务发展过程中的挑战的。
Google
目前
Alexa
排名第
1
。它诞生于
1997
年,当时是一个研究性项目,每个月
build
一次索引,
build
出来的索引通过
sharding
(
shard by doc
)的方式分散到多台服务器(
Index Server
)上,具体的网页数据同样通过
sharding
的方式分散到多台服务器(
Doc Server
)上,当用户提交请求时,通过前端的一台服务器将请求提交给
Index Server
获得打了分的倒排索引,然后从
Doc Server
提取具体的网页信息(例如网页标题、搜索关键词匹配的片段信息等),最终展现给用户。 随着索引的网页增加,这个结构可通过增加
Index Server
以及
Doc Server
来存储索引以及网页的数据,但仍然会面临其他很多方面的问题,于是在这之后的十多年的时间里,
Google
做了很多事情来改进上面的结构。 1999
年,
Google
增加了一个
Cache Cluster
,用来
Cache
查询的索引结果和文档片段信息,同时将
Index Server
和
Doc Server
通过
Replicate
的方式变成了
Cluster
。这两个改造带来的好处是网站的响应速度、可支撑的访问量以及可用性(
Availability
)得到了提升。这个变化造成了成本的增加,
Google
在硬件方面的风格始终是不用昂贵的高端硬件,而是在软件层面来保证系统的可靠性及高性能,于是同年,
Google
开始采用自行设计的服务器来降低成本。2000
年,
Google
开始自行设计
DataCenter
,采用了各种方法(例如采用其他的制冷方法来替代空调)来优化
PUE
(能源利用率),同时对自行设计的服务器也做了很多化。2001
年,
Google
对
Index
的格式进行了修改,将所有的
Index
放入内存, 这次改造带来的好处是网站的响应速度以及可支撑的访问量得到了极大的提升。2003
年,
Google
发表了文章
Google Cluster Architecture
,其
Cluster
结构组成为硬件
LB+Index Cluster+Doc Cluster+
大量廉价服务器(例如
IDE
硬盘、性价比高的
CPU
等),通过并行处理
+sharding
来保证在降低对硬件要求的同时,响应速度仍然很快。同年
Google
发表了关于
Google
文件系统的论文(
GFS
在
2000
年就已经上线),这篇论文很大程度也体现了
Google
不用昂贵硬件的风格,通过
GFS+
大量廉价的服务器即可存储大量的数据。2004
年,
Google
再次对
Index
的格式进行了修改,使得网站的响应速度继续提升。同年
Google
发表关于
MapReduce
的论文,通过
MapReduce+
大量廉价的服务器即可快速完成以前要使用昂贵小型机、中型机甚至是大型机才能完成的计算任务,而这显然对于
Google
快速地构建索引提供了很大的帮助。2006
年,
Google
发表了关于
BigTable
的论文(
2003
年开始上线),使得海量数据的分析能够达到在线系统的要求了,这对于
Google
提升网站的响应速度起到了很大的帮助。 以上
3
篇论文彻底改变了业界对于海量数据的存储、分析和检索的方法(小道消息:
Google
内部已完成了
GFS
、
MapReduce
、
BigTable
的替换),也奠定了
Google
在业界的技术领导地位。 在一些场景中,
Google
也采用
MySQL
来存储数据。同样,
Google
对
MySQL
也做了很多修改,它使用的
MySQL
信息可以从
https://code.google.com/p/google-mysql/
了解。 2007
年,
Google
将
build
索引的时间缩短到分钟级,当新网页出现后,几分钟后即可在
Google
搜索到,同时将
Index Cluster
通过
Protocol Buffers
对外提供
Service
,以供
Google
各种搜索(例如网页、图片、新闻、书籍等)使用,除了
Index Cluster
提供的
Service
外,还有很多其他的
Service
,例如广告、词法检查等。
Google
的一次搜索大概需要调用内部
50
个以上的
Service
,
Service
主要用
C++
或
Java
来编写。2009
年,
Google
的一篇《
How Google uses Linux
》文章,揭示了
Google
在提升机器利用率方面也做了很多的努力,例如将不同资源消耗类型的应用部署在同一台机器上。 在之后,
Google
又研发了
Colossus
(下一代类
GFS
文件系统)、
Spanner
(下一代类
BigTable
海量存储和计算架构)、实时搜索(基于
Colossus
实现),主要都是为了提升搜索的实时性以及存储更多数据。除了在海量数据相关技术上的革新外,
Google
也不断对业界的传统技术进行创新,例如提高
TCP
的初始拥塞窗口值、改进
HTTP
的
SPDY
协议、新的图片格式
WebP
等。 在
Google
的发展过程中,其技术的改造主要围绕在可伸缩性、性能、成本和可用性
4
个方面,
Google
不采用昂贵硬件的风格以及领先其他网站的数据量决定了其技术改造基本都是对传统的软硬件技术的革新。
Facebook
目前
Alexa
排名第
2
。它采用
LAMP
构建,随着业务的发展,它也在技术上做了很多改造。 作为改造的第一步,
Facebook
首先在
LAMP
结构中增加了
Memcached
,用来缓存各种数据,从而大幅度提升系统的响应时间以及可支撑的访问量,之后又增加了
Services
层,将
News Feed
、
Search
等较通用的功能作为
Service
提供给前端的
PHP
系统使用,前端的系统通过
Thrift
访问这些
Service
。
Facebook
采用了多种语言来编写各种不同的
Service
,主要是针对不同的场景选择合适的语言,例如
C++
、
Java
、
Erlang
。 大量使用
Memcached
以及访问量的不断上涨,导致访问
Memcached
的网络流量太大,交换机无法支撑,
Facebook
通过改造采用
UDP
的方式来访问
Memcached
,以降低单连接上的网络流量。除此之外,还有其他一些改造,具体信息可以查看
http://on.fb.me/8R0C
。 PHP
作为脚本语言,优势是开发简单、易上手,劣势是需要消耗较多的
CPU
和内存。当
Facebook
的访问量增长到了一定规模后,这个劣势就比较突出了,于是从
2007
年起,
Facebook
就尝试多种方法来解决这个问题,最后诞生于
Facebook Hackathon
的
HipHop
产品成功地脱颖而出。
HipHop
可以自动将
PHP
转化为
C++
代码,
Facebook
在使用
HipHop
后,同等配置的机器,可支撑的请求量是之前的
6
倍,
CPU
的使用率平均下降了
50%
,从而为
Facebook
节省了大量主机。将来
Facebook
还会对
HipHop
进行再次改进,通过
HipHop
将
PHP
编译为
bytecode
,放入
HipHop VM
中执行,再由
HipHop VM
来编译为机器代码,方式与
JIT
类似。 2009
年,
Facebook
研发了
BigPipe
,借助此系统,
Facebook
成功让网站的速度提升了两倍。随着
Facebook
访问量的上涨,收集众多服务器上的执行日志也开始面临挑战,于是
Facebook
研发了
Scribe
来解决此问题。对于存储在
MySQL
中的数据,
Facebook
采用垂直拆分库和水平拆分表的方式来支撑不断增长的数据量。作为
Facebook
技术体系中重要的一环,
Facebook
也对
MySQL
进行了很多优化和改进,例如
Online Schema Change
等,更多信息可见
http://www.facebook.com/MySQLAtFacebook
。 发展之初的
Facebook
采用了高端的存储设备(例如
NetApp
、
Akamai
)来存图片,随着图片不断增加,成本也大幅提高,于是
2009
年
Facebook
开发了
Haystack
来存储图片。
Haystack
可采用廉价的
PC Server
进行存储,大幅度降低了成本。 Facebook
除了使用
MySQL
存储数据外,近几年也开始摸索采用新的方式。在
2008
年
Facebook
开发了
Cassandra
,在
Message Inbox Search
中作为新的存储方式。不过在
2010
年,
Facebook
又放弃了
Cassandra
,转为采用
HBase
作为其
Messages
的存储,并在
2011
年将
HBase
应用在了
Facebook
更多的项目上(例如
Puma
、
ODS
)。据说,现在
Facebook
更是在尝试将其用户以及关系数据从
MySQL
迁移到
HBase
。 从
2009
年开始,
Facebook
尝试自行设计
DataCenter
以及服务器,以降低其运行成本,并对外开放了其构建的
PUE
仅
1.07
的
DataCenter
的相关技术。Facebook
在技术方面的基本原则是:“在能用开源产品的情况下就用开源,根据情况对其进行优化并反馈给社区”。从
Facebook
的技术发展历程上可以看到这个原则贯彻始终,
Facebook
的技术改造也主要是围绕在可伸缩、性能、成本和可用性
4
个方面。
Twitter目前
Alexa
排名第
8
。在
2006
年诞生之时是采用
Ruby On Rails+ MySQL
构建的,
2007
年增加了
Memcached
作为
Cache
层,以提升响应速度。基于
Ruby on Rails
让
Twitter
享受到了快速的开发能力,但随着访问量的增长,其对
CPU
和内存的消耗也让
Twitter
痛苦不堪,于是
Twitter
做了不少改造和努力,例如编写了一个优化版的
Ruby GC
。 2008
年
Twitter
决定逐步往
Java
迁移,选择了
Scala
作为主力的开发语言(理由是“难以向一屋子的
Ruby
程序员推销
Java
”),采用
Thrift
作为其主要的通信框架,开发了
Finagle
作为其
Service Framework
,可将后端各种功能暴露为
Service
提供给前端系统使用,使得前端系统无需关心各种不同的通信协议(例如对于使用者可以用同样的调用服务的方式去访问
Memcache
、
Redis
、
Thrift
服务端),开发了
Kestrel
作为其消息中间件(替代之前用
Ruby
写的
Starling
)。 Twitter
的数据存储一直采用
MySQL
,发展过程中出现的小插曲是,当
Facebook
开源了
Cassandra
时,
Twitter
本计划使用,但最终还是放弃,仍然保持了使用
MySQL
,
Twitter
的
MySQL
版本已开源(
https://github.com/twitter/mysql
)。
Twitter
也是采用分库分表的方式来支撑大数据量,使用
Memcached
来
Cache tweet
,
timeline
的信息则迁移为用
Redis
来
Cache
。 2010
年,
Twitter
在盐湖城拥有了第一个自建的
DataCenter
,主要是为了增加可控性。从
Twitter
的发展过程看,
6
年来它的技术改造主要围绕可伸缩以及可用性。
作为一家电子商务网站的员工,请允许我在此介绍这个
Alexa
排名
21
的著名电子商务网站的技术演变。 1995
年,
eBay
诞生,当时采用
CGI
编写,数据库采用的是
GDBM
,最多只能支撑
5
万件在线商品。1997
年,
eBay
将操作系统从
FreeBSD
迁移到
Windows NT
,另外将数据库从
GDBM
迁移为
Oracle
。1999
年,
eBay
将前端系统改造为
Cluster
(之前只有一台主机),采用
Resonate
作为负载均衡,后端的
Oracle
机器升级为
Sun E1000
小型机,同年给数据库增加了一台机器作为备库,提升可用性。前端机器随着访问量不断增加还可以应付,但数据库机器在
1999
年
11
月时已经达到了瓶颈(已经不能再加
CPU
和内存了),于是在
11
月开始将数据库按业务拆分为多个库。2001-2002
年,
eBay
将数据表进行了水平拆分,例如按类目存储商品,同时部署
Oracle
的小型机换为
Sun A3500
。2002
年,将整个网站迁移为用
Java
构建,在这个阶段,做了
DAL
框架来屏蔽数据库分库分表带来的影响,同时还设计了一个开发框架以供开发人员更好地上手进行功能开发。从
eBay
的整个发展过程来看,技术改造主要围绕在可伸缩性和可用性两点。
腾讯目前Alexa
排名第
9
。最初
QQ IM
采用的是单台接入服务器来处理用户的登录和状态保持,但在发展到一百万用户同时在线时,这台服务器已经无法支撑。于是
QQ IM
将所有单台服务器改造为了集群,并增加了状态同步服务器,由其完成集群内状态的同步,用户的信息存储在
MySQL
中,做了分库分表,好友关系存储在自行实现的文件存储中。为了提升进程间通信的效率,腾讯自行实现了用户态
IPC
。之后腾讯将状态同步服务器也改造为同步集群,以支撑越来越多的在线用户。在经历了前面几次改造后,已基本能支撑千万级别的用户同时在线,但可用性比较差,于是腾讯对
QQ IM
再次进行改造,实现了同城跨<