查看文章
|
以前谈到过关于高负载、大访问量的门户型web1.0网站的体系结构,提到了许多诸如front-end cache,clustered database,proxy server,cdn等技术,随着web2.0的温度越来越high,web2.0的一些代表性网站的体系结构也被晒了出来,我在这里进行简单的整理,呈现给大家。 案例1:豆瓣 豆瓣是由阿北(杨勃) 花4个多月时间(很神速,关键是胸有成竹),基于linux+lighttpd+fastcgi+python+quixote+mysql架构部署的 web2.0网站,豆瓣的搜索引擎使用twisted,这个是豆瓣的后台,书的价格以及比较信息都是在此之上搜索各大购物网站而来的,mysql用了 innodb和myisam两种引擎,读/写频繁的用innodb,读多写少、写多读少(比如log)或者需要full text index的用myisam,replication/cluster做数据复制和集群,晚上用mysqldump做backup。 案例2:youtube 出于开发效率的考虑,youtube的大部分代码都是python的, web server有两种,一种是apache+fastcgi,另一种是lighttpd(主要做为视频内容服务器),youtube可能是lighttpd 最好的案例。youtube每一个视频都有4个缩略图(Thumbnails),这个缩略图的产生对服务器的负载是个极大的考验,每一秒都给disk的 i/o带来压力,youtube采用了独立的服务器culuster来应对这方面的压力,也对操作系统和缓存做了优化。另外,缩略图的request也导 致了lighttpd性能下降,通过 Hack Lighttpd 增加更多的 worker thread很大程度解决了这个问题,被google收购以后,开始使用google的存储法宝bigtable,一下子提升了在 performance、redundancy、cache等方面的表现。(看来这次收购还是效果颇大)出于redundancy的考虑,每一个 video都放到一组mini cluster上,这组mini cluster上存储了相同内容的视频,the hotest video放在了cdn上,使压力分布到不同的节点上,非热门的,访问量不高的自己进行单独处理。维护的工具也是常见的rsync(同步工具)、ssh (远程登录)等。数据库上,youtube跟很多web2.0的站点一样,偏向使用mysql,主要是存储一些meta data,诸如视频信息、图片信息、用户信息等。youtube通过删除swap交换分区来解决数据库遇到的swap颠簸问题。 youtube最初的 DB 只有 10 块硬盘,后来追加了一组 RAID1。在扩展性方面,采用的是主流的方式,master/slave复制(replication),分散IO。最终的解决之道是是业务层面的分区(在用户名字或者 ID 上做文章,应用程序控制查找机制),而不是物理上的数据库层面的表分区。youtube也用了memcached。 案例3:myspace myspace有6500万的订阅者(还在上升),是因特网上增长最快的网站之一,每天还有260,000新用户注册。它经常因为性能问题而受指责, MySpace不得不处理其他网站很少碰到的或大或小的一些问题。它们是怎么做的呢? 使用的平台是 ASP.NET 2.0 + Windows + IIS + SQL Server ,myspace 每天处理15亿的页面查看,白天处理230万并发的用户,在50万用户的时候,采用简单的磕磕绊绊的体系结构,100万用户时进行了痛苦的垂直分割解决伸 缩性,300万用户时Scale-Out 胜过Scale-Up(按比例增加), 900万用户的时候,站点迁移到ASP.NET,增加了虚拟存储,260万用户的时候myspace采用了64位技术,当小于300万个帐号的时候,他们 使用了一种数据库体系结构,围绕着垂直分割的概念,提供不同服务比如界面登录,用户资料和博客等的网站的各部分都有单独的数据库。 垂直分割方案有助于分开数据库读和写的工作量,并且当用户需要一个新特征时,MySpace 将会加入一个新的在线数据库来支持它。MySpace 从直接使用附着于它的数据库的服务器的存储设备转换到一个存储区域网络(SAN),里面大量的磁盘存储设备由一个高速,专用网络联系到一块,同时数据库连 接到SAN。到SAN的改变提高了性能,正常运行时间和可靠性。 当超过300万个帐号的时候, 垂直分割解决方案就不好使了,因为它们重复了一些水平的信息像跨过所有垂直片的用户帐号。有这么多的重复它会使系统变慢,肯定要失败。个人应用比如Web 站点子部分上的博客将会增长到对于单独一个数据库服务器来说太大的程度,在逻辑上重组所有核心数据到一个数据库里 Myspace的经验告诉我们:你可以使用微软的技术构建大型网站;从一开始就应该使用缓存;高速缓存是一个更好的地方存储临时数据,比如Web站点上跟 踪一个特定用户的会话产生的临时文件,就不再需要记录到数据库里;嵌入OS特征来检测拒绝服务攻击会产生无法解释的错误;把数据分布到地理位置不同的数据 中心,以免发生断电事故。从开始就考虑使用虚拟存储/簇文件系统。它能让你大量并行IO访问,而且不需要任何重组就能够增加所需要的磁盘。 案例4:linkedin 案例5:mixi.jp Mixi目前是日本排名第三的网站,全球排名42,主要提供SNS服务:日记,群组,站内消息,评论,相册等等,是日本最大的SNS网站。Mixi从 2003年12月份开始开发,由现在它的CTO - Batara Kesuma一个人焊,焊了四个月,在2004年2月份开始上线运行。两个月后就注册了1w用户,日访问量60wPV。在随后的一年里,用户增长到了 21w,第二年,增长到了200w。到今年四月份已经增长到370w注册用户,并且还在以每天1.5w人的注册量增长。这些用户中70%是活跃用户(活跃 用户:三天内至少登录一次的用户),平均每个用户每周在线时间为将近3个半小时。 下面我们来看它的技术架构。Mixi采用开源软件作为架构的基础:Linux 2.6,Apache 2.0,MySQL,Perl 5.8,memcached,Squid等等。到目前为止已经有100多台MySQL数据库服务器,并且在以每月10多台的速度增长。Mixi的数据库连 接方式采用的是每次查询都进行连接,而不是持久连接。数据库大多数是以InnoDB方式运行。Mixi解决扩展问题主要依赖于对数据库的切分。 首先进行垂直切分,按照表的内容将不同的表划分到不同的数据库中。然后是水平切分,根据用户的ID将不同用户的内容再划分的不同的数据库中,这是比 较通常的做法,也很管用。划分的关键还是在于应用中的实现,需要将操作封装在在数据层,而尽量不影响业务层。当然完全不改变逻辑层也不可能,这时候最能检 验以前的设计是否到位,如果以前设计的不错,那创建连接的时候传个表名,用户ID进去差不多就解决问题了,而以前如果sql代码到处飞,或者数据层封装的 不太好的话那就累了。 这样做了以后并不能从根本上解决问题,尤其是对于像mixi这种SNS网站,页面上往往需要引用大量的用户信息,好友信息,图片,文章信息,跨表, 跨库操作相当多。这个时候就需要发挥memcached的作用了,用大内存把这些不变的数据全都缓存起来,而当修改时就通知cache过期,这样应用层基 本上就可以解决大部分问题了,只会有很小一部分请求穿透应用层,用到数据库。Mixi的经验是平均每个页面的加载时间在0.02秒左右(当然根据页面大小 情况不尽相似),可以说明这种做法是行之有效的。Mixi一共在32台机器上有缓存服务器,每个Cache Server 2G内存,这些Cache Server与App Server装在一起。因为Cache Server对CPU消耗不大,而有了Cache Server的支援,App Server对内存要求也不是太高,所以可以和平共处,更有效的利用资源。 图片的处理就显得相对简单的多了。对于mixi而言,图像主要有两部分:一部分是经常要使用到的,像用户头像,群组的头像等等,大概有100多 GB,它们被Squid和CDN所缓存,命中率相对比较高;另一部分是用户上传的大量照片,它们的个体访问量相对而言比较小,命中率也比较低,使用 Cache不划算,所以对于这些照片的策略是直接在用户上传的时候分发到到图片存储服务器上,在用户访问的时候直接进行访问,当然图片的位置需要在数据库 中进行记录,不然找不到放在哪台服务器上就郁闷了。 案例6:flickr 我们都看到 Flickr 的成功,而又有多少"精英"们了解过 Flickr 背后的过程是多么充满艰险。 Flickr 是全 CGI 的动态构架,并以一种 .gne 的脚本作为 CGI 程序语言。不管网站制作菜鸟还是高手都会疑惑:gne 是哪种程序语言?答案:gne 不是一种语言,Flickr 是以极为经典的 PHP + MySQL 方式实现的,在被 Yahoo 收购服务器搬入美国之前,使用了 21 台(69.90.111.101-121) Apache/PHP 做 Web、23 台图片服务器、另有 MySQL 服务器组成的数据库集群的服务器数量未知。现在估计使用的是 Yahoo 的负载均衡系统,对外只有一个 Web 的 IP 和图片服务器的 IP 了。 那为何 .php 的文件要改成 .gne 呢?以往有大型网站为向后兼容性考虑,隐藏以程序语言命名的脚本文件扩展名,比如 Baidu 隐藏了 .php(Google 的 http 服务器是自己写的,整合了脚本程序,个别页面是 .py--Python);还有一些网站是改成自己网站名相关的扩展名,如 MSN 的群组则是 .msnw,榕树下是 .rs。 那 Flickr 的 gne 是什么意思?我在维基百科的 Flickr 条目上找到了答案(中文 Flickr 条目上没有写明) 。原来 GNE 是 Game NeverEnding 的缩写,Flickr 的开发者 Ludicorp 在 2002-2004 年一直在开发这套以 Game NerverEnding 为名称的大型多人在线角色扮演游戏--一套基于浏览器的 Web 游戏系统,个人以为应该就是当年九城的虚拟城市。但是开发近 3 年后该计划不得不破产,最终只发布了一个 Beta 版,而 Ludicorp 将这套系统稍加移植,就有了 Flickr。呵呵,原来 gne 是一个项目的名称。关于 GNE 的一些连接:http://del.icio.us/schee/gne。 早期的 Flickr 想做成在类似聊天室的地方让网友分享、交流自己的照片,注重社区形式和保护照片不被外部引用(见徐子涵2004年的文章),可能是看到了 Hello 的模式吧。但是聪明的 Flickr 团队不久就改变了策略,淡化了传统的社区形式--如聊天室、而加强了现在使其功成名就的 Tag 组织形式,一种更自由更随兴更轻松好玩的大社区形式,或者叫它广义社区吧,我随便叫的,可能太学究,看着别太在意就是了。另外,将原来照片只能在 Flash 内浏览的限制区除了,并大力推荐用户将照片引用到自己的 Blog,这无疑对于挑战传统相册系统有决定性意义。减少 Flash 后的网页更多地引进了新兴的 Ajax 技术,使界面操作变得非常 Cool。 这就是 Flickr 的历史,清晰地看到了他们对于优秀产品的执著。有了技术和经验积累,加上不断坚持,总有一天时来运转,你的产品会成为新潮流的里程碑。 还有一句话要告诉 Yupoo 等:把 Flickr 想成一个有 Tag 功能的在线相册就已经错远了;复制粘贴者们想当然将 Flickr 去其糟粕取其精华,结果无关紧要的拿来了,将令人激动的优点都去掉了,结果剩下什么? 案例7:technorati technorati的首席架构师Dorion Carroll在 2006 MySQL 用户会议上介绍了一些关于 Technorati 后台数据库架构的情况。 基本情况 目前处理着大约 10Tb 核心数据, 分布在大约 20 台机器上.通过复制, 多增加了 100Tb 数据, 分布在 200 台机器上。每天增长的数据 1TB. 通过 SOA 的运用, 物理与逻辑的访问相隔离, 似乎消除了数据库的瓶颈. 值得一提的是, 该扩展过程始终是利用普通的硬件与开源软件来完成的。 毕竟 , Web 2.0 站点都不是烧钱的主.。从数据量来看,这绝对是一个相对比较大的 Web 2.0 应用。 Tag 是 Technorati 最为重要的数据元素.。爆炸性的Tag 增长给 Technorati 带来了不小的挑战。 2005 年 1 月的时候, 只有两台数据库服务器, 一主一从。到了06 年一月份, 已经是一主一从, 6 台 MyISAM 从数据库用来对付查询, 3 台 MyISAM 用作异步计算。 一些核心的处理方法: 1) 根据实体(tags/posttags))进行分区 衡量数据访问方法,读和写的平衡.然后通过不同的维度进行分区.( Technorati 数据更新不会很多, 否则会成为数据库灾难) 2) 合理利用 InnoDB 与 MyISAM InnoDB 用于数据完整性/写性能要求比较高的应用. MyISAM 适合进行 OLAP 运算. 物尽其用. 3) MySQL 复制 复制数据到从主数据库到辅数据库上,平衡分布查询与异步计算, 另外一个功能是提供冗余. 如图: 案例8:LiveJournal livejournal是99年始于校园中的项目,几个人出于爱好做了这样一个应用,以实现以下功能:
LiveJournal采用了大量的开源软件,甚至它本身也是一个开源软件。 在上线后,LiveJournal实现了非常快速的增长:
二、LiveJournal架构现状概况 三、从LiveJournal发展中学习 LiveJournal从1台服务器发展到100台服务器,这其中经历了无数的伤痛,但同时也摸索出了解决这些问题的方法,通过对LiveJournal的学习,可以让我们避免LJ曾经犯过的错误,并且从一开始就对系统进行良好的设计,以避免后期的痛苦。 下面我们一步一步看LJ发展的脚步。 1、一台服务器 一台别人捐助的服务器,LJ最初就跑在上面,就像Google开始时候用的破服务器一样,值得我们尊敬。这个阶段,LJ的人以惊人的速度熟悉的 Unix的操作管理,服务器性能出现过问题,不过还好,可以通过一些小修小改应付过去。在这个阶段里LJ把CGI升级到了FastCGI。 最终问题出现了,网站越来越慢,已经无法通过优过化来解决的地步,需要更多的服务器,这时LJ开始提供付费服务,可能是想通过这些钱来购买新的服务器,以解决当时的困境。 毫无疑问,当时LJ存在巨大的单点问题,所有的东西都在那台服务器的铁皮盒子里装着。 2、两台服务器 用付费服务赚来的钱LJ买了两台服务器:一台叫做Kenny的Dell 6U机器用于提供Web服务,一台叫做Cartman的Dell 6U服务器用于提供数据库服务。 LJ有了更大的磁盘,更多的计算资源。但同时网络结构还是非常简单,每台机器两块网卡,Cartman通过内网为Kenny提供MySQL数据库服务。 暂时解决了负载的问题,新的问题又出现了:
3、四台服务器 又买了两台,Kyle和Stan,这次都是1U的,都用于提供Web服务。目前LJ一共有3台Web服务器和一台数据库服务器。这时需要在3台Web服务器上进行负载均横。 LJ把Kenny用于外部的网关,使用mod_backhand进行负载均横。 然后问题又出现了:
4、五台服务器 又买了一台数据库服务器。在两台数据库服务器上使用了数据库同步(Mysql支持的Master-Slave模式),写操作全部针对主数据库(通过Binlog,主服务器上的写操作可以迅速同步到从服务器上),读操作在两个数据库上同时进行(也算是负载均横的一种吧)。 实现同步时要注意几个事项:
5、更多服务器 有钱了,当然要多买些服务器。部署后快了没多久,又开始慢了。这次有更多的Web服务器,更多的数据库服务器,存在 IO与CPU争用。于是采用了BIG-IP作为负载均衡解决方案。 6、现在我们在哪里: 现在服务器基本上够了,但性能还是有问题,原因出在架构上。 数据库的架构是最大的问题。由于增加的数据库都是以Slave模式添加到应用内,这样唯一的好处就是将读操作分布到了多台机器,但这样带来的后果就是写操作被大量分发,每台机器都要执行,服务器越多,浪费就越大,随着写操作的增加,用于服务读操作的资源越来越少。 由一台分布到两台 最终效果 现在我们发现,我们并不需要把这些数据在如此多的服务器上都保留一份。服务器上已经做了RAID,数据库也进行了备份,这么多的备份完全是对资源的浪费,属于冗余极端过度。那为什么不把数据分布存储呢? 问题发现了,开始考虑如何解决。现在要做的就是把不同用户的数据分布到不同的服务器上进行存储,以实现数据的分布式存储,让每台机器只为相对固定的用户服务,以实现平行的架构和良好的可扩展性。 为了实现用户分组,我们需要为每一个用户分配一个组标记,用于标记此用户的数据存放在哪一组数据库服务器中。每组数据库由一个master及几个 slave组成,并且slave的数量在2-3台,以实现系统资源的最合理分配,既保证数据读操作分布,又避免数据过度冗余以及同步操作对系统资源的过度 消耗。 由一台(一组)中心服务器提供用户分组控制。所有用户的分组信息都存储在这台机器上,所有针对用户的操作需要先查询这台机器得到用户的组号,然后再到相应的数据库组中获取数据。 这样的用户架构与目前LJ的架构已经很相像了。 在具体的实现时需要注意几个问题:
7、现在我们在哪里 问题:
对于Master-Slave模式的单点问题,LJ采取了Master-Master模式来解决。所谓Master-Master实际上是人工实现的,并不是由MySQL直接提供的,实际上也就是两台机器同时是Master,也同时是Slave,互相同步。 Master-Master实现时需要注意:
解决方案:
Master-Master模式还有一种用法,这种方法与前一种相比,仍然保持两台机器的同步,但只有一台机器提供服务(读和写),在每天晚上的时候进行轮换,或者出现问题的时候进行切换。 8、现在我们在哪里 现在插播一条广告,MyISAM VS InnoDB。 使用InnoDB:
使用MyISAM:
9、缓存 去年我写过一篇文章介绍memcached,它就是由LJ的团队开发的一款缓存工具,以key-value的方式将数据存储到分布的内存中。LJ缓存的数据:
如何建立缓存策略? 想缓存所有的东西?那是不可能的,我们只需要缓存已经或者可能导致系统瓶颈的地方,最大程度的提交系统运行效率。通过对MySQL的日志的分析我们可以找到缓存的对象。 缓存的缺点?
10、Web访问负载均衡 在数据包级别使用BIG-IP,但BIG-IP并不知道我们内部的处理机制,无法判断由哪台服务器对这些请求进行处理。反向代理并不能很好的起到作用,不是已经够快了,就是达不到我们想要的效果。 所以,LJ又开发了Perlbal。特点:
11、MogileFS LJ使用开源的MogileFS作为分布式文件存储系统。MogileFS使用非常简单,它的主要设计思想是:
到目前为止就这么多了,更多文档可以在http://www.danga.com/words/找到。Danga.com和LiveJournal.com的 同学们拿这个文档参加了两次MySQL Con,两次OS Con,以及众多的其它会议,无私的把他们的经验分享出来,值得我们学习。在web2.0时代快速开发得到大家越来越多的重视,但良好的设计仍是每一个应 用的基础,希望web2.0们在成长为Top500网站的路上,不要因为架构阻碍了网站的发展。 |
'; }else{ _rh1+=' | '; } _rh1+=" |
最近还没有登录用户看过这篇文章…… |
"+cmtname+""; }else{ if(cmtname=="" || cmtname=="匿名网友"){ if(cmturl==""){ html1=" 匿名网友"; }else{ html1=" "+cmtname+""; } }else{ if(cmturl==""){ html1="