我先前曾写过三篇有关网站系统、ASP.NET 性能优化的文章,分别从 SQL 语句、数据库设计、ASP.NET 功能、IIS 7 的套件,来探讨此一性能议题。本帖算是系列做的第四篇,整理了一些我看过的书籍和文章,改从「负载均衡、服务器架构、数据库扩展」的角度,提出一些性能优化的建议,以供有建设中大型网站需求的网友们做为参考。php
小弟我先前写过的三篇帖子:html
(一) 30 分钟快快乐乐学 SQL Performance Tuning
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.htmljava
(二) 网站性能愈来愈差怎么办?
http://www.cnblogs.com/WizardWu/archive/2009/01/03/1367527.htmllinux
(三) 用 IIS 七、ARR 與 Velocity 建设高性能的大型网站
http://www.cnblogs.com/WizardWu/archive/2009/05/16/1458108.htmlsql
-----------------------------------------------------数据库
一、Web Server 与 DB Server 分离缓存
小型网站或 B/S 项目,因同时在线人数很少,尚可以让同一台物理主机,既作 Web Server,又作 DB Server。但此两者皆会占用大量的 CPU、内存、磁盘 I/O,最好让两者分别用不一样的服务器主机来提供服务,以分散压力、提升负载承受能力。此外,两者若在同一网段,应尽可能用内网 Private IP 进行访问,而不要用 Public IP 或主机名称。性能优化
基本上跑 Web 上的应用程序,无论用什么软、硬件,同时处理多个用户的 request,一般都比较消耗 CPU;但对数据库而言,CPU 就不见得会大量消耗,而是内存和磁盘 I/O 用得比 Web Server 多。所以通常建议 Web Server 用普通的 PC 便可,但要用好一点的 CPU;而 DB Server 就不能草率,应尽可能买高级的服务器,并要有 RAID 5 或 6 的磁盘阵列 (硬件的 RAID,性能远比操做系统或软件作的 RAID 要好),并有 4 GB 以上的内存。固然若是操做系统、数据库都用 64 位版本的最好,例如升级到 64 位的 SQL Server 和 64 位的 Windows Server,这样内存均可配置到 64 GB;不过要记得,太旧的 PC,一些周边硬件的 driver 可能不支持 64 位的操做系统和软件。服务器
若是在线人数持续增长,则可增长多台 Web Server 和 DB Server,用「服务器集群 (cluster)」、「负载均衡 (Load balancing) 集群」、「高可用性集群 High-availability (HA)」、数据库集群,以实现更大规模的分布式布署。网络
Deployment Plan(部署规划):
http://msdn.microsoft.com/zh-cn/library/ms978676.aspx
Three-Tiered Distribution(三级分布)(硬件、不一样主机的物理级分层):
http://msdn.microsoft.com/zh-cn/library/ms978694.aspx
Three-Layered Services Application(三层服务应用程序)(软件、代码上的分层):
http://msdn.microsoft.com/zh-cn/library/ms978689.aspx
Tiered Distribution(分级分布):
http://msdn.microsoft.com/en-gb/library/ms978701(zh-cn).aspx
Deployment Patterns:
http://msdn.microsoft.com/zh-cn/library/ms998478.aspx
http://msdn.microsoft.com/en-us/library/ms998478.aspx
-----------------------------------------------------
二、负载均衡 (Load Balance)
负载均衡技术发展了多年,有不少专业的服务提供商和产品可选择,基本上又可分为「软件」和「硬件」的解决方案:
(1) 硬件:
硬件的解决方案称做 Layer 4 Switch (第 4 层交换),可将业务流分配到合适的 AP Server 进行处理,知名产品如 Alteon、F5 等。这些硬件产品虽比软件的解决方案要贵得多,可是物有所值,一般能提供远比软件优秀的性能,和方便、易于管理的 UI 界面,供管理人员快速配置。听说 Yahoo 中国当初接近 2000 台服务器时,只用三台 Alteon 就搞定了 [1]。
(2) 软件:
Apache 这一款众所皆知的 HTTP Server,其双向 Proxy / Reverse Proxy 功能,亦可达成 HTTP 负载均衡功能,但其效率算不上特别好。而另外一款 HAProxy 就是纯粹用来处理负载均衡的,且具备简单的缓存功能。
以操做系统内置的负载均衡功能来说,Unix 如 Sun 的 Solaris 有支持,Linux 上则有经常使用的 LVS (Linux Virtual Server),而微软的 Windows Server 2003 / 2008 则有 NLB (Network LoadBalance)。
LVS 是利用 ipvsadm 这一个以 IP 为主的负载均衡程序,来达到让全部 TCP/IP 的通信协议均可以进行负载均衡。因为它是 Linux Kernel 所支持,所以效率至关好,占用的 CPU 资源至关低,但缺点是 ipvsadm 没法针对 Layer 4 以上的网络 packet 数据进行分析。
至于 Windows Server 的 NLB,其原理是不论有多少台服务器,都所有共用一个「集群的 IP」,以下图 1 的 Active Load balancer,和下图 2 的 Virtual Server 1 (Web Server),以及 Virtual DB Server,依照负载均衡的类型来作分配 (Active/Active、Active/Standby、...),而用户在外面只会看到单一个 IP,至于背后有多少台服务器,用户并不须要知道 (如同 Cluster 集群和云计算的概念)。
图 1 分布式用户 vs 服务器农场 (Web Server farm)
图 2 红色箭头为 Failover 架构 (HA),其功能与 Load Balance 不一样
上图 2 中,有四台 Real Server (Web Server),以及三台 Real DB Server,造成 Web 及 DB 的服务器集群 (Cluster)。咱们看到最上方的 Virtual Server 1 自己不具有任何的数据服务 (如:.NET 代码、图片...等),只有一个功能,就是将用户的连线 request 请求,从新导向下方的四台 Real Server。这种利用从新导向 (director) 的方式,将服务负载分布给 Real Server 的方式,就称做 Load Balance。
如今彷佛尚未一种作法,能自动计算主机的「负载」情形,例如计算 CPU 已使用多少百分比,以决定要把 request 丢向哪一台 Real Server;如今通常都仍是按照轮替 (Round-robin) 的方式,或加上一些权重的设置而已。
若咱们在 Server 上设置 Load Balance,且要执行 ASP.NET 程序,就要注意一个问题,就是 Session 的存储位置是在哪一台 Web Server 的内存上,以免发生有用户表单填写得比较久,等到他提交时,已经被 Windows Server 的 NLB 将工做阶段切换到另外一台 Web Server 主机上了。此时就可考虑将 Session State,改存储在 SQL Server 里。
至于用软件作的 Load Balance 其性能如何呢?基本上用软件作的,性能必定不会是 1 + 1 = 2,但一般能提升 Availability,亦即常听到的 HA (高可用性集群 High-availability),即 Failover 方式,如上图 2 的最上方,红色箭头左侧的 Virtual Server 2,是可以侦测 Virtual Server 1 宕机或没法提供服务时,自动将本身的 IP address 取代 Virtual Server1。所以 HA 是指提供「不会中断的服务」,而本帖讨论的 Load Balance 是指提供「能承受高度负载的服务」,二者指的不是同一件事。MIS 人员应视公司的硬件资源、成本和预算,考量是否二者都要作。
Load-Balanced Cluster(负载平衡群集):
http://msdn.microsoft.com/zh-cn/library/ms978730.aspx
http://msdn.microsoft.com/en-us/library/ms978730.aspx
Server Clustering(服务器群集):
http://msdn.microsoft.com/en-gb/library/ms998414(zh-cn).aspx
Installing Network Load Balancing (NLB) on Windows Server 2008:
http://blogs.msdn.com/clustering/archive/2008/01/08/7024154.aspx
Linux load balancing support & consulting:
http://www.netdigix.com/linux-loadbalancing.php
Load Balancing (WCF, 与本文无直接关系):
http://msdn.microsoft.com/zh-cn/library/ms730128.aspx
http://msdn.microsoft.com/en-us/library/ms730128.aspx
-----------------------------------------------------
三、展现和功能的分层
大型网站中,常会为了未来的可扩展性、源代码维护方便,而将前台的展现 (HTML、Script),和后台的商业逻辑、数据库访问 (.NET/C#、SQL),切成多层。
根据 Martin Fowler 在 P of EAA 里的說法:Layer 是指「逻辑」上的分层 (logical separation),Tier 是指「物理」上的分层 (physical separation)。若咱们的 ASP.NET 站台,是用「虚拟」的分层 (N-Layer),来切开 UI - BLL - DAL,一般不会有性能上的问题;但如果用「物理」的分层 (N-Tier),亦即如上图 2 和下图 3,可能每一台 AP Server 都负责不一样的商业逻辑 (销售、库存、物流、制造、会计、...),各自的源代码都存放在不一样的物理主机上,且可各自独立运做,此时就要考虑到每一台 AP Server 在彼此协调合做,以及调用 Web Service (XML 的性能不佳)、执行分布式事务上的性能问题。
图 3 「物理」上的分层,各类商业逻辑可能存在多台物理主机上
谈到「物理」分层上的分布式事务 (Distributed Transaction),微软的 Enterprise Services、COM+、WCF、WF 用到操做系统上的 MS DTC 来协调事务,因为 MS DTC 和这些应用程序各自处于不一样的 Process,在沟通上会遇到序列化、反序列化的动做,还要整合事务中全部的 AppDomain 和不一样主机上的资源,无可避免地必定会拖累性能。
Web Applications: N-Tier vs. N-Layer :
http://codebetter.com/blogs/david.hayden/archive/2005/07/23/129745.aspx
-----------------------------------------------------
四、数据大表拆分
对比较大的数据表,或历史数据比较多的数据表,可根据必定的逻辑进行拆分。若天天的数据量很是大,则可采用按日存放,再用一个「汇总表」来记录当天的一个汇总值;也可先将比较大的表拆分红多个表,再经过「索引表」进行关联处理,以免查询大表形成的性能问题 [1]。
另也可用「表分区」的方式,将数据存储在不一样的文件上,而后再部署到独立的物理服务器,以增长 I/O 吞吐,改善读写的性能。
此外,在本文的系列做「30 分钟快快乐乐学 SQL Performance Tuning」曾提过,若一个数据表的字段过多 (与刚才提的记录量过多不一样),应垂直切割成两个以上的数据表,并可用同名的 Primary Key 一对多连结起来,如:Northwind 的 Orders、Order Details 数据表。以免在访问数据时,以「集簇引 (clustered index)」扫描时会加载过多的数据,或修改数据时形成互相锁定或锁定太久。
-----------------------------------------------------
五、图片服务器分离
对于 Web Server 来讲,用户对图片的请求是最消耗系统资源的,所以可视网站的规模和项目的特性,部署独立的图片服务器,甚至多台图片服务器。
-----------------------------------------------------
六、读写分离
同时对数据库进行「读」和「写」的操做,是很是没效率的一种访问方式。比较好的作法,是根据读、写的压力和需求,分别创建两台结构彻底相同的数据库服务器,将负责「写」的那台服务器的数据,定时复制给负责「读」的服务器。
-----------------------------------------------------
七、扩容性应对突增流量
大型网站在设计架构的时候,必须考虑到之后的容量扩充 [1]。对于活动类的网站来讲,不定时的突增流量是巨大的。在网站主存储服务器上,采用配置文件形式,指定每个存储盘柜上存储的数据文件的 ID 范围。当前台服务器须要读取一个数据的时候,首先经过询问主存储服务器上的接口,得到该数据所在的盘柜及目录地址,而后再去该盘柜读取实际的数据文件。若是须要增长盘柜,则只要修改配置文件便可,前台程序彻底不受影响。
-----------------------------------------------------
八、缓存
缓存 (Cache) 是数据库或对象在内存中的临时容器,使用缓存可大幅减小数据库的读取,改由内存来提供数据。例如咱们能够在 Web Server、DB Server 之间增长一层「数据缓存层」,在内存中创建被频繁请求对象的副本,如此一来,不访问数据库也可供给数据。例如,有 100 个用户请求同一份资料,之前须要查询数据库 100 次,如今则只须要 1 次,其他均可从缓存数据中得到,并且读取速度、网页反应速度会大幅提高。
提供缓存的产品有不少种,还可分为用硬件或软件所作的缓存,如:ASP.NET 内置的缓存功能、第三方厂商的缓存套件、Hibernate 和 NHibernate 里也有 Session 和 SessionFactory 的缓存机制、Oracle 的 cache group 技术,还有我先前在「用 IIS 七、ARR 與 Velocity 建设高性能的大型网站」这篇文章介绍的,微软官方新一代的分布式缓存技术 Velocity,另外像 Proxy Server (代理服务器) 也能够做为网页的缓存:
客户端 <----> 代理服务器 <----> 目的服务器
在 .NET 的类库中,有提供 CacheDependency 和 AggregateCacheDependency 这两个类,可用来将 ASP.NET 中缓存的对象 (如:DataSet),和一或多个物理文件 (如:XML 文件) 或数据库中的表,去创建一种关联。当其中任一个 XML 文件被修改或移除时,与其关联的 DataSet 也会一并从内存里移除;固然,也可透过您程序中设定的时间自动移除。
ASP.NET 2.0 之后的缓存,最大的改变在于 CacheDependency 类已经被微软从新改写过,咱们也可透过自定义类去继承它后再改写,以达成如下功能:
• 从 Active Directory 中的请求,让缓存失效 (缓存被自动移除)
• 从 MSMQ 或 MQSeries 中的请求,让缓存失效
• 从 Web Service 中的请求,让缓存失效
• 建立用于 Oracle 的 CacheDependency
• 其余
此外,SQL Server 中还有一种 SqlCacheDependency (缓存相依性),可监听数据表中的数据是否曾经改变,亦即避免用户在缓存期间查到的数据是旧的,达到若是数据不变化,用户就一直从缓存中取得数据;一旦数据有变化,就自动更新缓存中的数据。启用 SqlCacheDependency 的方式,只要透过 aspnet_regsql.exe 这个工具,搭配参数输入命令,就会在 SQL Server 中产生一个新的 AspNet_SqlCacheTablesForChangeNotification 表,以下图 4 所示,这张表的的每一条记录,都表明您要监听的其中一个表;最右侧的 changeId 字段,其值为供系统判断,用户对 ASP.NET 中的请求,应由内存中的缓存来提供,抑或要至数据库从新作查询。
图 4 启用 SqlCacheDependency 后,自动添加用来监听的表
另外再谈到,我在「网站性能愈来愈差怎么办?」这篇文章,也有提过下面的内容:
(4) 用程序或软件作缓存
用程序作缓存,如 ASP.NET 从 1.x 时代,就已内建的 Cache (缓存) 机制;或用一些第三方的辅助软件、Framework。
(5) 用硬件作快取或缓冲、砸钱加装 AP Server
他还在本来的网页服务器,与数据库服务器的架构中,加入一组应用程序服务器,做为网页服务器 cache 数据的来源。
改版以后的新网站,搜寻速度提高许多,先前每日的统计数据中,处理速度超过 3 秒的数据超过 50 万笔;而改版后,每星期超过 3 秒的查询不到 10 笔。
(6) 用硬件作缓存 (cache)
全盛时期,来自美国 blog 的流量天天达 80 万次。这个数字其实不高,对程序高手来讲是小菜一碟,但笔者是半吊子工程师,知识有限也所以可能程序写得很差,频频被主机供货商发信警告,要求改善网站系统性能。最后,我决定开发 cache system。cache system 缓存系统上线后,将数据库读写,从天天 80 万次下降到天天 16 万次。
回复:
Peter.z.lu
中间件能够有不少选择:
Ncache, Coherence, Velocity, MemCache...
另外,还有像是 Memcached、Cacheman 这种分布式缓存的系统。前者可基于 Linux 和 Win32 平台使用,经过在内存里维护一个巨大的 hash 表,可存储图像、视频、文件及数据库检索的结果,而且支持多服务器,可解决 ASP.NET 内置的缓存机制仅适用于单独的服务器;后者听说是微软旗下 Popfly 项目组成员 Sriram Krishnan 的做品,未来也有可能成为微软的正式产品。
-----------------------------------------------------
九、分布式系统数据结构 - 以 MySpace 为例
在网络上流传一篇很火红的文章「从 MySpace 数据库看分布式系统数据结构变迁」,内容提到 MySpace 这个大型的社区网站,使用微软平台的 Windows Server、SQL Server、ASP.NET 技术,现在每月的用户访问量高达 500 亿,且已有 2 亿个以上的用户注册。如下仅节录该文的重点:
从 MySpace 数据库看分布式系统数据结构变迁:
http://www.cnblogs.com/cxccbv/archive/2009/07/15/1524387.html
http://www.javaeye.com/topic/152766
http://smb.pconline.com.cn/database/0808/1403100.html
http://idai.blogbus.com/logs/14736411.html
-----------------------------------------------------
参考资料:
[1] 亮剑 .NET : .NET 深刻体验与实战精要,第 15 章,做者: 李天平
http://www.fecit.com.cn/
http://www.litianping.com
[2] 走出软件做坊,做者: 阿朱
http://www.china-pub.com/508874
http://blog.csdn.net/david_lv
[3] 多本书籍、网络文件、msdn
-----------------------------------------------------
原文转自:http://www.cnblogs.com/WizardWu/archive/2009/09/22/1571499.html