存爱好,做为收藏,原地址:http://www.blogjava.net/BlueDavy/archive/2008/09/03/226749.html ,同时向原创致敬html
以前也有一些介绍大型网站架构演变的文章,例如LiveJournal的、ebay的,都是很是值得参考的,不过感受他们讲的更多的是每次演变的结果,而没有很详细的讲为何须要作这样的演变,再加上近来感受有很多同窗都很难明白为何一个网站须要那么复杂的技术,因而有了写这篇文章的想法,在这篇文章中 将阐述一个普通的网站发展成大型网站过程当中的一种较为典型的架构演变历程和所需掌握的知识体系,但愿能给想从事互联网行业的同窗一点初步的概念,:),文中的不对之处也请各位多给点建议,让本文真正起到抛砖引玉的效果。前端
架构演变第一步:物理分离webserver和数据库java
最开始,因为某些想法,因而在互联网上搭建了一个网站,这个时候甚至有可能主机都是租借的,但因为这篇文章咱们只关注架构的演变历程,所以就假设这个时候 已是托管了一台主机,而且有必定的带宽了,这个时候因为网站具有了必定的特点,吸引了部分人访问,逐渐你发现系统的压力愈来愈高,响应速度愈来愈慢,而这个时候比较明显的是数据库和应用互相影响,应用出问题了,数据库也很容易出现问题,而数据库出问题的时候,应用也容易出问题,因而进入了第一步演变阶段:将应用和数据库从物理上分离,变成了两台机器,这个时候技术上没有什么新的要求,但你发现确实起到效果了,系统又恢复到之前的响应速度了,而且支撑住了更高的流量,而且不会由于数据库和应用造成互相的影响。linux
看看这一步完成后系统的图示:nginx
这一步涉及到了这些知识体系:web
这一步架构演变对技术上的知识体系基本没有要求。算法
架构演变第二步:增长页面缓存数据库
好景不长,随着访问的人愈来愈多,你发现响应速度又开始变慢了,查找缘由,发现是访问数据库的操做太多,致使数据链接竞争激烈,因此响应变慢,但数据库连 接又不能开太多,不然数据库机器压力会很高,所以考虑采用缓存机制来减小数据库链接资源的竞争和对数据库读的压力,这个时候首先也许会选择采用squid 等相似的机制来将系统中相对静态的页面(例如一两天才会有更新的页面)进行缓存(固然,也能够采用将页面静态化的方案),这样程序上能够不作修改,就可以 很好的减小对webserver的压力以及减小数据库链接资源的竞争,OK,因而开始采用squid来作相对静态的页面的缓存。apache
看看这一步完成后系统的图示:编程
这一步涉及到了这些知识体系:
前端页面缓存技术,例如squid,如想用好的话还得深刻掌握下squid的实现方式以及缓存的失效算法等。
架构演变第三步:增长页面片断缓存
增长了squid作缓存后,总体系统的速度确实是提高了,webserver的压力也开始降低了,但随着访问量的增长,发现系统又开始变的有些慢了,在尝 到了squid之类的动态缓存带来的好处后,开始想能不能让如今那些动态页面里相对静态的部分也缓存起来呢,所以考虑采用相似ESI之类的页面片断缓存策略,OK,因而开始采用ESI来作动态页面中相对静态的片断部分的缓存。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
页面片断缓存技术,例如ESI等,想用好的话一样须要掌握ESI的实现方式等;
架构演变第四步:数据缓存
在采用ESI之类的技术再次提升了系统的缓存效果后,系统的压力确实进一步下降了,但一样,随着访问量的增长,系统仍是开始变慢,通过查找,可能会发现系 统中存在一些重复获取数据信息的地方,像获取用户信息等,这个时候开始考虑是否是能够将这些数据信息也缓存起来呢,因而将这些数据缓存到本地内存,改变完毕后,彻底符合预期,系统的响应速度又恢复了,数据库的压力也再度下降了很多。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
缓存技术,包括像Map数据结构、缓存算法、所选用的框架自己的实现机制等。
架构演变第五步: 增长webserver
好景不长,发现随着系统访问量的再度增长,webserver机器的压力在高峰期会上升到比较高,这个时候开始考虑增长一台webserver,这也是为了同时解决可用性的问题,避免单台的webserver down机的话就无法使用了,在作了这些考虑后,决定增长一台webserver,增长一台webserver时,会碰到一些问题,典型的有:
一、如何让访问分配到这两台机器上,这个时候一般会考虑的方案是Apache自带的负载均衡方案,或LVS这类的软件负载均衡方案;
二、如何保持状态信息的同步,例如用户session等,这个时候会考虑的方案有写入数据库、写入存储、cookie或同步session信息等机制等;
三、如何保持数据缓存信息的同步,例如以前缓存的用户数据等,这个时候一般会考虑的机制有缓存同步或分布式缓存;
四、如何让上传文件这些相似的功能继续正常,这个时候一般会考虑的机制是使用共享文件系统或存储等;
在解决了这些问题后,终因而把webserver增长为了两台,系统终因而又恢复到了以往的速度。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
负载均衡技术(包括但不限于硬件负载均衡、软件负载均衡、负载算法、linux转发协议、所选用的技术的实现细节等)、主备技术(包括但不限于ARP欺骗、linux heart-beat等)、状态信息或缓存同步技术(包括但不限于Cookie技术、UDP协议、状态信息广播、所选用的缓存同步技术的实现细节等)、共享文件技术(包括但不限于NFS等)、存储技术(包括但不限于存储设备等)。
架构演变第六步:分库
享受了一段时间的系统访问量高速增加的幸福后,发现系统又开始变慢了,此次又是什么情况呢,通过查找,发现数据库写入、更新的这些操做的部分数据库链接的 资源竞争很是激烈,致使了系统变慢,这下怎么办呢,此时可选的方案有数据库集群和分库策略,集群方面像有些数据库支持的并非很好,所以分库会成为比较广泛的策略,分库也就意味着要对原有程序进行修改,一通修改实现分库后,不错,目标达到了,系统恢复甚至速度比之前还快了。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
这一步更多的是须要从业务上作合理的划分,以实现分库,具体技术细节上没有其余的要求;
但同时随着数据量的增大和分库的进行,在数据库的设计、调优以及维护上须要作的更好,所以对这些方面的技术仍是提出了很高的要求的。
架构演变第七步:分表、DAL和分布式缓存
随着系统的不断运行,数据量开始大幅度增加,这个时候发现分库后查询仍然会有些慢,因而按照分库的思想开始作分表的工做,固然,这不可避免的会须要对程序 进行一些修改,也许在这个时候就会发现应用本身要关心分库分表的规则等,仍是有些复杂的,因而萌生可否增长一个通用的框架来实现分库分表的数据访问,这个在ebay的架构中对应的就是DAL,这个演变的过程相对而言须要花费较长的时间,固然,也有可能这个通用的框架会等到分表作完后才开始作,同时,在这个阶段可 能会发现以前的缓存同步方案出现问题,由于数据量太大,致使如今不太可能将缓存存在本地,而后同步的方式,须要采用分布式缓存方案了,因而,又是一通考察和折磨,终因而将大量的数据缓存转移到分布式缓存上了。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
分表更多的一样是业务上的划分,技术上涉及到的会有动态hash算法、consistent hash算法等;
DAL涉及到比较多的复杂技术,例如数据库链接的管理(超时、异常)、数据库操做的控制(超时、异常)、分库分表规则的封装等;
架构演变第八步:增长更多的webserver
在作完分库分表这些工做后,数据库上的压力已经降到比较低了,又开始过着天天看着访问量暴增的幸福生活了,忽然有一天,发现系统的访问又开始有变慢的趋势 了,这个时候首先查看数据库,压力一切正常,以后查看webserver,发现apache阻塞了不少的请求,而应用服务器对每一个请求也是比较快的,看来 是请求数过高致使须要排队等待,响应速度变慢,这还好办,通常来讲,这个时候也会有些钱了,因而添加一些webserver服务器,在这个添加 webserver服务器的过程,有可能会出现几种挑战:
一、Apache的软负载或LVS软负载等没法承担巨大的web访问量(请求链接数、网络流量等)的调度了,这个时候若是经费容许的话,会采起的方案是购 买硬件负载,例如F五、Netsclar、Athelon之类的,如经费不容许的话,会采起的方案是将应用从逻辑上作必定的分类,而后分散到不一样的软负载集群中;
二、原有的一些状态信息同步、文件共享等方案可能会出现瓶颈,须要进行改进,也许这个时候会根据状况编写符合网站业务需求的分布式文件系统等;
在作完这些工做后,开始进入一个看似完美的无限伸缩的时代,当网站流量增长时,应对的解决方案就是不断的添加webserver。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
到了这一步,随着机器数的不断增加、数据量的不断增加和对系统可用性的要求愈来愈高,这个时候要求对所采用的技术都要有更为深刻的理解,并须要根据网站的需求来作更加定制性质的产品。
架构演变第九步:数据读写分离和廉价存储方案
忽然有一天,发现这个完美的时代也要结束了,数据库的噩梦又一次出如今眼前了,因为添加的webserver太多了,致使数据库链接的资源仍是不够用,而这个时候又已经分库分表了,开始分析数据库的压力情况,可能会发现数据库的读写比很高,这个时候一般会想到数据读写分离的方案,固然,这个方案要实现并不 容易,另外,可能会发现一些数据存储在数据库上有些浪费,或者说过于占用数据库资源,所以在这个阶段可能会造成的架构演变是实现数据读写分离,同时编写一些更为廉价的存储方案,例如BigTable这种。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
数据读写分离要求对数据库的复制、standby等策略有深刻的掌握和理解,同时会要求具有自行实现的技术;
廉价存储方案要求对OS的文件存储有深刻的掌握和理解,同时要求对采用的语言在文件这块的实现有深刻的掌握。
架构演变第十步:进入大型分布式应用时代和廉价服务器群梦想时代
通过上面这个漫长而痛苦的过程,终因而再度迎来了完美的时代,不断的增长webserver就能够支撑愈来愈高的访问量了,对于大型网站而言,人气的重要毋 庸置疑,随着人气的愈来愈高,各类各样的功能需求也开始爆发性的增加,这个时候忽然发现,原来部署在webserver上的那个web应用已经很是庞大 了,当多个团队都开始对其进行改动时,可真是至关的不方便,复用性也至关糟糕,基本是每一个团队都作了或多或少重复的事情,并且部署和维护也是至关的麻烦, 由于庞大的应用包在N台机器上复制、启动都须要耗费很多的时间,出问题的时候也不是很好查,另一个更糟糕的情况是颇有可能会出现某个应用上的bug就导 致了全站都不可用,还有其余的像调优很差操做(由于机器上部署的应用什么都要作,根本就没法进行针对性的调优)等因素,根据这样的分析,开始痛下决心,将 系统根据职责进行拆分,因而一个大型的分布式应用就诞生了,一般,这个步骤须要耗费至关长的时间,由于会碰到不少的挑战:
一、拆成分布式后须要提供一个高性能、稳定的通讯框架,而且须要支持多种不一样的通讯和远程调用方式;
二、将一个庞大的应用拆分须要耗费很长的时间,须要进行业务的整理和系统依赖关系的控制等;
三、如何运维(依赖管理、运行情况管理、错误追踪、调优、监控和报警等)好这个庞大的分布式应用。
通过这一步,差很少系统的架构进入相对稳定的阶段,同时也能开始采用大量的廉价机器来支撑着巨大的访问量和数据量,结合这套架构以及这么屡次演变过程吸收的经验来采用其余各类各样的方法来支撑着愈来愈高的访问量。
看看这一步完成后系统的图示:
这一步涉及到了这些知识体系:
这一步涉及的知识体系很是的多,要求对通讯、远程调用、消息机制等有深刻的理解和掌握,要求的都是从理论、硬件级、操做系统级以及所采用的语言的实现都有清楚的理解。
运维这块涉及的知识体系也很是的多,多数状况下须要掌握分布式并行计算、报表、监控技术以及规则策略等等。
提及来确实不怎么费力,整个网站架构的经典演变过程都和上面比较的相似,固然,每步采起的方案,演变的步骤有可能有不一样,另外,因为网站的业务不一样,会有不一样的专业技术的需求,这篇blog更多的是从架构的角度来说解演变的过程,固然,其中还有不少的技术也未在此说起,像数据库集群、数据挖掘、搜索等,但在真实的演变过程当中还会借助像提高硬件配置、网络环境、改造操做系统、CDN镜像等来支撑更大的流量,所以在真实的发展过程当中还会有不少的不一样,另一个大型网站要作到的远远不只仅上面这些,还有像安全、运维、运营、服务、存储等,要作好一个大型的网站真的很不容易,写这篇文章更多的是但愿可以引出更多大型网站架构演变的介绍,:)。
ps:最后附上几篇LiveJournal架构演变的文章:
从LiveJournal后台发展看大规模网站性能优化方法
http://blog.zhangjianfeng.com/article/743
另外从这里:http://www.danga.com/words/你们能够找到更多关于如今LiveJournal网站架构的介绍。
Jack.Wang
全部软件开发方法都要解决从需求到实现之间的转换问题。基于体系结构的软件开发包含如下几个主要阶段:
1)经过对特定领域应用软件进行分析,提炼出其中的稳定需求和易变需求,创建可重用的领域模型。依据领域模型和用户需求,产生应用系统的需求规格说明。
2)在领域模型的基础上,根据需求规格说明提炼出特定领域的软件体系结构。这是系统的高层设计,其目标是经过重用领域体系结构库中已有的高质量的体系结构,或生成最适合该用户需求的体系结构,并加以提炼入库,以备未来的重用,并在此体系结构的指导下,把系统逐步分解成相应的组件和链接件,直至组件
和链接件能够被设计模式和面向对象方法处理为止。
3)这个阶段主要解决具体组件和链接件的设计问题。经过重用可重用组件库中模式、对象和其它可重用的设计件,或从新设计的组件,并提炼入库;而后经过具体的编程实现,就可获得可运行的程序
lingxiao
写得不错。 我最近也在做相关方面的研究,不清楚对应到你上面阶段的那个部分,可是个人实现可能别有洞天。 我作web已经7年多了,最不能忍受的就是重复重复再重复,用了.net java以后我总于返回到了c时代,归结web应用其实就是数据+格式化,而xml+xslt偏偏就是这个模型,因此个人应用就是基于xml+xslt,而且作了一整套的技术论证,从SEO到换肤、多语言等高级特性都有了合理的解决方法,而且能够模块重用,作到数据跟界面的完全分离,这样更有利于静态化,数据重用。 固然,实现的过程有阻碍,我已经作这套系统作了3年,废弃了一套java作得半成品的东西(我重写了jsp,还作了一个webserver和解释器,可是发现静态处理性能不行),如今总于有点眉目了,个人web server静态处理性能能大到nginx的120%,apache的200%(均是在300用户负载的测试下),数据库应用服务能达到 15000RPS/S(静态文件23000左右,测试是在单机状况下,cpu Q6600 4核,2G内存,1个主线程,4个应用线程测试),代理性能是静态性能的接近50%,这几乎成为极限了,这为个人模型奠基了基础。 完成后系统自己就自带分布式文件系统、负载均衡、缓存系统,应用是基于配置的数据管理器,能够将数据库、静态文件、prama、服务器变量等等经过数据管理器按照用户权限发送给可解析xml的客户端,对于SEO、非xslt解析支持的浏览器等等所有采用在服务器端合成输出。界面则所有由xslt完成。 这样就能保证90%的请求能到到亚静态文件的处理速度,系统还在完善中,采用c在linux下编写的,但愿有空共同探讨。