我先前曾寫過三篇有關網站系統、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