一个小型的网站,好比我的网站,可使用最简单的html静态页面就实现了,配合一些图片达到美化效果,全部的页面均存放在一个目录下,这样的网站对系统架构、性能的要求都很简单,随着互联网业务的不断丰富,网站相关的技术通过这些年的发展,已经细分到很细的方方面面,尤为对于大型网站来讲,所采用的术更是涉及面很是广,从硬件到软件、编程语言、数据库、WebServer、防火墙等各个领域都有了很高的要求,已经不是原来简单的html静态网站所能比拟的。html
大型网站,好比门户网站。在面对大量用户访问、高并发请求方面,基本的解决方案集中在这样几个环节:使用高性能的服务器、高性能的数据库、高效率的编程语言、还有高性能的Web容器。可是除了这几个方面,还无法根本解决大型网站面临的高负载和高并发问题。前端
上面提供的几个解决思路在必定程度上也意味着更大的投入,而且这样的解决思路具有瓶颈,没有很好的扩展性,下面我从低成本、高性能和高扩张性的角度来讲说个人一些经验。web
1、HTML静态化
其实你们都知道,效率最高、消耗最小的就是纯静态化的html页面,因此咱们尽量使咱们的网站上的页面采用静态页面来实现,这个最简单的方法其实也是最有效的方法。可是对于大量内容而且频繁更新的网站,咱们没法所有手动去挨个实现,因而出现了咱们常见的信息发布系统CMS,像咱们常访问的各个门户站点的新闻频道,甚至他们的其余频道,都是经过信息发布系统来管理和实现的,信息发布系统能够实现最简单的信息录入自动生成静态页面,还能具有频道管理、权限管理、自动抓取等功能,对于一个大型网站来讲,拥有一套高效、可管理的CMS是必不可少的。算法
除了门户和信息发布类型的网站,对于交互性要求很高的社区类型网站来讲,尽量的静态化也是提升性能的必要手段,将社区内的帖子、文章进行实时的静态化,有更新的时候再从新静态化也是大量使用的策略,像Mop的大杂烩就是使用了这样的策略,网易社区等也是如此。目前不少博客也都实现了静态化
同时,html静态化也是某些缓存策略使用的手段,对于系统中频繁使用数据库查询可是内容更新很小的应用,能够考虑使用html静态化来实现,好比论坛中论坛的公用设置信息,这些信息目前的主流论坛均可以进行后台管理而且存储再数据库中,这些信息其实大量被前台程序调用,可是更新频率很小,能够考虑将这部份内容进行后台更新的时候进行静态化,这样避免了大量的数据库访问请求。数据库
在进行html静态化的时候可使用一种折中的方法,就是前端使用动态实现,在必定的策略下进行定时静态化和定时判断调用,这个能实现不少灵活性的操做,apache
2、图片服务器分离
你们知道,对于Web服务器来讲,无论是Apache、IIS仍是其余容器,图片是最消耗资源的,因而咱们有必要将图片与页面进行分离,这是基本上大型网站都会采用的策略,他们都有独立的图片服务器,甚至不少台图片服务器。这样的架构能够下降提供页面访问请求的服务器系统压力,而且能够保证系统不会由于图片问题而崩溃。编程
在应用服务器和图片服务器上,能够进行不一样的配置优化,好比Apache在配置ContentType的时候能够尽可能少支持,尽量少的LoadModule,保证更高的系统消耗和执行效率。缓存
另外,在处理静态页面或者图片、js等访问方面,能够考虑使用lighttpd代替Apache,它提供了更轻量级和更高效的处理能力。安全
3、数据库集群和库表散列
大型网站都有复杂的应用,这些应用必须使用数据库,那么在面对大量访问的时候,数据库的瓶颈很快就能显现出来,这时一台数据库将很快没法知足应用,因而咱们须要使用数据库集群或者库表散列。性能优化
在数据库集群方面,不少数据库都有本身的解决方案,Oracle、Sybase等都有很好的方案,经常使用的MySQL提供的Master/Slave也是相似的方案,您使用了什么样的DB,就参考相应的解决方案来实施便可。
上面提到的数据库集群因为在架构、成本、扩张性方面都会受到所采用DB类型的限制,因而咱们须要从应用程序的角度来考虑改善系统架构,库表散列是经常使用而且最有效的解决方案。咱们在应用程序中安装业务和应用或者功能模块将数据库进行分离,不一样的模块对应不一样的数据库或者表,再按照必定的策略对某个页面或者功能进行更小的数据库散列,好比用户表,按照用户ID进行表散列,这样就可以低成本的提高系统的性能而且有很好的扩展性。sohu的论坛就是采用了这样的架构,将论坛的用户、设置、帖子等信息进行数据库分离,而后对帖子、用户按照板块和ID进行散列数据库和表,最终能够在配置文件中进行简单的配置便能让系统随时增长一台低成本的数据库进来补充系统性能。
4、缓存
缓存一词搞技术的都接触过,不少地方用到缓存。网站架构和网站开发中的缓存也是很是重要。这里先讲述最基本的两种缓存。高级和分布式的缓存在后面讲述。
架构方面的缓存,对Apache比较熟悉的人都能知道Apache提供了本身的mod_proxy缓存模块,也可使用外加的Squid进行缓存,这两种方式都可以有效的提升Apache的访问响应能力。
5、镜像
镜像是大型网站常采用的提升性能和数据安全性的方式,镜像的技术能够解决不一样网络接入商和地域带来的用户访问速度差别,好比ChinaNet和EduNet之间的差别就促使了不少网站在教育网内搭建镜像站点,数据进行定时更新或者实时更新。在镜像的细节技术方面,这里不阐述太深,有不少专业的现成的解决架构和产品可选。也有廉价的经过软件实现的思路,好比Linux上的rsync等工具。
6、负载均衡
负载均衡将是大型网站解决高负荷访问和大量并发请求采用的终极解决办法。
负载均衡技术发展了多年,有不少专业的服务提供商和产品能够选择,我我的接触过一些解决方法,其中有两个架构能够给你们作参考。另外有关初级的负载均衡DNS轮循和较专业的CDN架构就很少说了。
6.1 硬件四层交换
第四层交换使用第三层和第四层信息包的报头信息,根据应用区间识别业务流,将整个区间段的业务流分配到合适的应用服务器进行处理。 第四层交换功能就象是虚IP,指向物理服务器。它传输的业务服从的协议多种多样,有HTTP、FTP、NFS、Telnet或其余协议。这些业务在物理服务器基础上,须要复杂的载量平衡算法。在IP世界,业务类型由终端TCP或UDP端口地址来决定,在第四层交换中的应用区间则由源端和终端IP地址、TCP和UDP端口共同决定。
在硬件四层交换产品领域,有一些知名的产品能够选择,好比Alteon、F5等,这些产品很昂贵,可是物有所值,可以提供很是优秀的性能和很灵活的管理能力。Yahoo中国当初接近2000台服务器使用了三四台Alteon就搞定了。
6.2 软件四层交换
你们知道了硬件四层交换机的原理后,基于OSI模型来实现的软件四层交换也就应运而生,这样的解决方案实现的原理一致,不过性能稍差。可是知足必定量的压力仍是游刃有余的,有人说软件实现方式其实更灵活,处理能力彻底看你配置的熟悉能力。
软件四层交换咱们可使用Linux上经常使用的LVS来解决,LVS就是Linux Virtual Server,他提供了基于心跳线heartbeat的实时灾难应对解决方案,提升系统的鲁棒性,同时可供了灵活的虚拟VIP配置和管理功能,能够同时知足多种应用需求,这对于分布式的系统来讲必不可少。
一个典型的使用负载均衡的策略就是,在软件或者硬件四层交换的基础上搭建squid集群,这种思路在不少大型网站包括搜索引擎上被采用,这样的架构低成本、高性能还有很强的扩张性,随时往架构里面增减节点都很是容易。这样的架构我准备空了专门详细整理一下和你们探讨。
6.3 七层交换
你们都知道TCP/IP的七层协议,四层交换是基于传输层的,在这一层只能处理链接的管理,可是没法和业务关联起来,一般只能针对tcp、udp的链接来进行处理,而真正的业务逻辑须要后面的服务器群本身来处理,随着技术的发展,今天,咱们在不少高级的应用中出现了七层交换。
七层交换是基于TCP/IP的第七层应用层来实现的,在这一层上,首先咱们能够区分出具体的应用,好比HTTP、TELNET、FTP、DNS等等,还能根据应用中传送的内容来进行策略的管理,好比咱们有这么两个网站的路径 a.com/music/… 和a.com/photo/… 原来基于四层交换只能把这两个url的请求都分发到后面一组服务器上,可是七层交换能够判断访问的是music/仍是photo/路径,而后分别分发到不通的服务器群上,从而实现更灵活的系统架构设计。
固然,七层交换也分硬件和软件的实现方式,在这里我不细说了,硬件有著名的F5、Nortel等,软件有Haproxy等,固然,七层交换的软件目前仍是在性能上要远远差异于硬件实现的,要知道,这些硬件都价格不菲
总结:
对于大型网站来讲,前面提到的每一个方法可能都会被同时使用到,这里介绍得比较浅显,具体实现过程当中不少细节还须要你们慢慢熟悉和体会,有时一个很小的squid参数或者apache参数设置,对于系统性能的影响就会很大,但愿你们一块儿讨论,达到抛砖引玉之效。
咱们说到有关图片影响性能的问题,通常来讲都是出自于咱们的大部分访问页面中图片每每比html代码占用的流量大,在同等网络带宽的状况下,图片传输须要的时间更长,因为传输须要花很大开销在创建链接上,这会延长用户client端与server端的http链接时长,这对于apache来讲,并发性能确定会降低,除非你的返回所有是静态的,那就能够把 httpd.conf 中的 KeepAlives 为 off ,这样能够减少链接处理时间,可是若是图片过多会致使创建的链接次数增多,一样消耗性能。
另外咱们提到的理论更多的是针对大型集群的案例,在这样的环境下,图片的分离能有效的改进架构,进而影响到性能的提高,要知道咱们为何要谈架构?架构可能为了安全、为了资源分配、也为了更科学的开发和管理,可是终极目都是为了性能。
另外在RFC1945的HTTP协议文档中很容易找到有关Mime Type和Content length部分的说明,这样对于理解图片对性能影响是很容易的。
对于大型的站点来讲,他的数据库和 Web Server 通常都是分布式的,在多个区域都有部署,当某个地区的用户访问时会对应到一个节点上,若是是对社区内的帖子实时静态化,有更新时再从新静态化,那么在节点之间如何马上同步呢?数据库端如何实现呢?若是用户看不到的话会觉得发帖失败?形成重复发了,那么如何将用户锁定在一个节点上呢?
对于将一个用户锁定在某个节点上是经过四层交换来实现的,通常状况下是这样,若是应用比较小的能够经过程序代码来实现。大型的应用通常经过相似LVS和硬件四层交换来管理用户链接,能够制定策略来使用户的链接在生命期内保持在某个节点上。
静态化和同步的策略比较多,通常采用的方法是集中或者分布存储,可是静态化倒是经过集中存储来实现的,而后使用前端的proxy群来实现缓存和分担压力。
通常对于一个中型网站来讲,交互操做很是多,日PV百万左右,如何作合理的负载?
交互若是很是多,能够考虑使用集群加Memory Cache的方式,把不断变化并且须要同步的数据放入Memory Cache里面进行读取,具体的方案还得须要结合具体的状况来分析。
若是一个网站处于技术发展期,那么这些优化手段应该先实施哪些后实施哪些呢?
或者说从成本(技术、人力和财力成本)方面,哪些先实施可以取得最大效果呢?
先从服务器性能优化、代码性能优化方面入手,包括webserver、dbserver的优化配置、html静态化等容易入手的开始,这些环节争取先榨取到最大化的利用率,而后再考虑从架构上增长投入,好比集群、负载均衡等方面,这些都须要在有必定的发展积累以后再作考虑比较恰当。
这个img.9tmd.com是虚拟主机吧,也就是说是一个apache提供的服务吧,这样的话对于性能的提升也颇有意义吗?仍是只是铺垫,为了方便之后的物理分离呢?
由于目前只有一台服务器,因此从物理上没法实现真正的分离,暂时使用虚拟主机来实现,是为了程序设计和网站架构上的灵活,若是有了一台新的服务器,我只须要把图片镜像过去或者同步过去,而后把img.9tmd.com的dns解析到新的服务器上就天然实现了分离,若是如今不从架构和程序上实现,从此这样的分离就会比较痛苦:)
关于如何在网站的前期尽量低成本的投入,作到性能最大化利用,同时作好后期系统架构的规划,这个问题能够说已经放大到超出技术范畴,不过和技术相关的部分仍是有很多须要考虑的。
一个网站的规划关键的就是对阶段性目标的规划,好比预测几个月后达到什么用户级别、存储级别、并发请求数,而后再过几个月又将什么状况,这些预测必须根据具体业务和市场状况来进行预估和不断调整的,有了这些预测数据做为参考,就能进行技术架构的规划,不然技术上是没法合理进行架构设计的。
在网站发展规划基础上,考虑从此要提供什么样的应用?有些什么样的域名关系?各个应用之间的业务逻辑和关联是什么?面对什么地域分布的用户提供服务?等等。。。
上面这些问题有助于规划网站服务器和设备投入,同时从技术上能够及早预测到将来将会是一个什么架构,在知足这个架构下的每一个节点将须要知足什么条件,就是初期架构的要求。
总的来讲,不结合具体业务的技术规划是没有意义的,因此首先是业务规划,也就是产品设计,而后才是技术规划。
图片服务器与主数据分离的问题。
图片是存储在硬盘里好仍是存储在数据库里好?
请您分硬盘和数据库两种状况解释下面的疑问。
当存放图片的服务器容量不能知足要求时如何办?
当存放图片的服务器负载不能知足要求时如何办?
确定是存储在硬盘里面,出现存储在数据库里面的说法其实是出自一些虚拟主机或者租用空间的我的网站和企业网站,由于网站数据量小,也为了备份方便,从大型商业网站来讲,没有图片存储在数据库里面的大型应用。数据库容量和效率都会是极大的瓶颈。
你提到的后面两个问题。容量和负载基本上是同时要考虑的问题,容量方面,大部分的解决方案都是使用海量存储,好比专业的盘阵,入门级的磁盘柜或者高级的光纤盘阵、局域网盘阵等,这些都是主要的解决方案。记得我原来讲过,若是是考虑低成本,必定要本身使用便宜单台服务器来存储,那就须要从程序逻辑上去控制,好比你能够多台一样的服务器来存储,分别提供NFS的分区给前端应用使用,在前端应用的程序逻辑中本身去控制存储在哪一台服务器的NFS分区上,好比根据Userid或者图片id、或者别的逻辑去进行散列,这个和咱们规划大型数据库存储散列分表或者分库存储的逻辑相似。
基本上图片负载高的解决办法有两种,前端squid缓存和镜像,经过对存储设备(服务器或者盘阵)使用镜像,能够分布到多台服务器上对外提供图片服务,而后再配合squid缓存实现负载的下降和提升用户访问速度。
1、图片服务器分离
这个观点是我一直以来都很是支持的。特别是若是程序与图片都放在同一个 APAHCE 的服务器下,每个图片的请求都有可能致使一个 HTTPD 进程的调用,而 HTTPD 若是包含有 PHP 模块的的时候,就会占用过多的内存,而这个是没有任何须要的。
使用独立的图片服务器不但能够避免以上这个状况,更能够对不一样的使用性质的图片设置不一样的过时时间,以便同一个用户在不一样页面访问相同图片时不会再次从服务器(基因而缓存服务器)取数据,不但止快速,并且还省了带宽。还有就是,对于缓存的时间上,亦能够作调立的调节。
在我过往所管理的图片服务器中,不但止是将图片与应用及页面中分离出来,仍是为不一样性质的图片启用不一样的域名。以缓解不一样性质图片带来的压力。例如 photo.img.domain.com 这个域名是为了摄影服务的,平时使用 5 台 CACHE,但到了 5.1 长假期后,就有可能须要独立为他增长至 10 台。而增长的这 5 台能够从其余负载较低的图片服务器中调动过来临时使用。
2、数据库集群
一套 ORACLE RAC 的集群布置大概在 40W 左右,这个价格对于通常公司来讲,是没有必要的。由于 WEB 的应用逻辑相对较简单,而 ORACLE 这些大型数据库的价值在于数据挖掘,而不在于简单的存储。因此选择 MySQL 或 PostgreSQL 会实际一些。
简单的 MySQL 复制就能够实现较好的效果。读的时候从 SLAVE 读,写的时候才到 MASTER 上更新。实际的状况下,MySQL 的复制性能很是好,基本上不会带来过高的更新延时。使用 balance (http://www.inlab.de/balance.html)这个软件,在本地(127.0.0.1)监听 3306 端口,再映射多个 SLAVE 数据库,能够实现读取的负载均衡。
3、图片保存于磁盘仍是数据库?
对于这个问题,我亦有认真地考虑过。若是是在 ext3 的文件系统下,建 3W 个目录就到极限了,而使用 xfs 的话就没有这个限制。图片的存储,若是须要是大量的保存,必需要分隔成不少个小目录,不然就会有 ext3 只能建 3W 目录的限制,并且文件数及目录数太多会影响磁盘性能。尚未算上空间占用浪费等问题。
更更重要的是,对于一个大量小文件的数据备份,要占用极大的资源和很是长的时间。在这些问题前面,可能将图片保存在数据库是个另外的选择。
能够尝试将图片保存到数据库,前端用 PHP 程序返回实际的图片,再在前端放置一个 SQUID 的服务器,能够避免性能问题。那么图片的备份问题,亦能够利用 MySQL 的数据复制机制来实现。这个问题就能够获得较好的解决了。
4、页面的静态化我就不说了,我本身作的 wordpress 就彻底实现了静态化,同时能很好地兼顾动态数据的生成。
5、缓存
我本身以前也提出过使用 memcached,但实际使用中不是很是特别的理想。固然,各个应用环境不一致会有不一致的使用结果,这个并不重要。只要本身以为好用就用。
6、软件四层交换
LVS 的性能很是好,我有朋友的网站使用了 LVS 来作负责均衡的调度器,数据量很是大均可以轻松支撑。固然是使用了 DR 的方式。
其实我本身还想过能够用 LVS 来作 CDN 的调度。例如北京的 BGP 机房接受用户的请求,而后经过 LVS 的 TUN 方式,将请求调度到电信或网通机房的实际物理服务器上,直接向用户返回数据。
这种是 WAN 的调度,F5 这些硬件设备也应用这样的技术。不过使用 LVS 来实现费用就大大下降