標籤:
我先前曾寫過三篇有關網站系統、ASP.NET 效能最佳化的文章,分別從 SQL 陳述式、資料庫設計、ASP.NET 功能、IIS 7 的套件,來探討此一效能議題。本帖算是系列作的第四篇,整理了一些我看過的書籍和文章,改從「負載平衡、伺服器架構、資料庫擴充」的角度,提出一些效能最佳化的建議,以供有建設中大型網站需求的網友們作為參考。
小弟我先前寫過的三篇文章:
(一) 30 分鐘快快樂樂學 SQL Performance Tuning
http://www.cnblogs.com/WizardWu/archive/2008/10/27/1320055.html
(二) 網站效能越來越差怎麼辦?
http://www.cnblogs.com/WizardWu/archive/2009/01/03/1367527.html
(三) 用 IIS 7、ARR 與 Velocity 建設高效能的大型網站
http://www.cnblogs.com/WizardWu/archive/2009/05/16/1458108.html
-----------------------------------------------------
1、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
-----------------------------------------------------
2、負載平衡 (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(Server Load Balancer群集):
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
-----------------------------------------------------
3、展示和功能的分層
大型網站中,常會為了將來的可擴充性、原始碼維護方便,而將前台的展示 (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
-----------------------------------------------------
4、資料大表拆分
對比較大的資料表,或曆史資料比較多的資料表,可根據一定的邏輯進行拆分。若每天的資料量非常大,則可採用按日存放,再用一個「匯總表」來記錄當天的一個匯總值;也可先將比較大的表拆分成多個表,再通過「索引表」進行關聯處理,以避免查詢大表造成的效能問題 [1]。
另也可用「表分區」的方式,將資料存放區在不同的檔案上,然後再部署到獨立的物理伺服器,以增加 I/O 吞吐,改善讀寫的效能。
此外,在本文的系列作「30 分鐘快快樂樂學 SQL Performance Tuning」曾提過,若一個資料表的欄位過多 (與剛才提的記錄量過多不同),應垂直切割成兩個以上的資料表,並可用同名的 Primary Key 一對多連結起來,如:Northwind 的 Orders、Order Details 資料表。以避免在訪問資料時,以「集簇引 (clustered index)」掃描時會載入過多的資料,或修改資料時造成互相鎖定或鎖定過久。
-----------------------------------------------------
5、圖片伺服器分離
對於 Web Server 來說,使用者對圖片的請求是最消耗系統資源的,因此可視網站的規模和項目的特性,部署獨立的圖片伺服器,甚至多台圖片伺服器。
-----------------------------------------------------
6、讀寫分離
同時對資料庫進行「讀」和「寫」的操作,是非常沒效率的一種訪問方式。比較好的做法,是根據讀、寫的壓力和需求,分別建立兩台結構完全相同的資料庫伺服器,將負責「寫」的那台伺服器的資料,定時複製給負責「讀」的伺服器。
-----------------------------------------------------
7、擴容性應對突增流量
大型網站在設計架構的時候,必須考慮到以後的容量擴充 [1]。對於活動類的網站來說,不定時的突增流量是巨大的。在網站主儲存伺服器上,採用設定檔形式,指定每一個儲存盤柜上儲存的資料檔案的 ID 範圍。當前台伺服器需要讀取一個資料的時候,首先通過詢問主儲存伺服器上的介面,獲得該資料所在的盤櫃及目錄位址,然後再去該盤櫃讀取實際的資料檔案。如果需要增加盤櫃,則只要修改設定檔即可,前景程式完全不受影響。
-----------------------------------------------------
8、緩衝
緩衝 (Cache) 是資料庫或對象在記憶體中的臨時容器,使用緩衝可大幅減少資料庫的讀取,改由記憶體來提供資料。例如我們可以在 Web Server、DB Server 之間增加一層「資料緩衝層」,在記憶體中建立被頻繁請求對象的副本,如此一來,不訪問資料庫也可供給資料。例如,有 100 個使用者請求同一份資料,以前需要查詢資料庫 100 次,現在則只需要 1 次,其餘都可從快取資料中獲得,而且讀取速度、網頁反應速度會大幅提升。
提供緩衝的產品有很多種,還可分為用硬體或軟體所做的緩衝,如:ASP.NET 內建的緩衝功能、第三方廠商的緩衝套件、Hibernate 和 NHibernate 裡也有 Session 和 SessionFactory 的緩衝機制、Oracle 的 cache group 技術,還有我先前在「用 IIS 7、ARR 與 Velocity 建設高效能的大型網站」這篇文章介紹的,微軟官方新一代的分布式緩衝技術 Velocity,另外像 Proxy Server (Proxy 伺服器) 也可以作為網頁的緩衝:
用戶端 <----> Proxy 伺服器 <----> 目的伺服器
在 .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 的作品,將來也有可能成為微軟的正式產品。
-----------------------------------------------------
9、分布式系統資料結構 - 以 MySpace 為例
在網路上流傳一篇很火紅的文章「從 MySpace 資料庫看分布式系統資料結構變遷」,內容提到 MySpace 這個大型的社區網站,使用微軟平台的 Windows Server、SQL Server、ASP.NET 技術,如今每個月的使用者訪問量高達 500 億,且已有 2 億個以上的使用者註冊。以下僅節錄該文的重點:
- 第一代架構 - 添置更多的 Web 服務器
在 MySpace 有 50 萬個註冊使用者的時候,網站只用了兩台 Dell 雙 CPU、4 GB 記憶體的 Web Server (分散使用者的請求)、一台 DB Server (所有資料都儲存在這)。
- 第二代架構 - 增加資料庫伺服器
運行在三台資料庫伺服器上,一台用於更新資料 (由它複製到其他兩個)、另兩台用於讀取資料,因為看網頁的人多,而需要寫入的人少。等到使用者數和訪問量增加了,就再加裝硬碟。
後來資料庫伺服器的 I/O 成了瓶頸,就按照垂直分割模式設計,把網站裡的不同功能,如:登入、使用者資料和部落格,搬移到不同的資料庫伺服器中,以分擔訪問壓力;若要增加新功能,就再投入新的資料庫伺服器。
當註冊使用者達到 200 萬後,還從存放裝置與資料庫伺服器直接互動的方式,切換到 SAN (存放區域網路),一種高頻寬、專門設計的網路系統,可將大量磁碟存放裝置串連在一起。MySpace 讓資料庫連接到 SAN。但是當使用者增加到 300 萬人後,垂直分割策略也變得難以維持下去,後來架構師後來將主機升級成 34 個 CPU 的昂貴伺服器,卻也無法負荷。
- 第三代架構 - 轉到分散式運算架構
架構師將 MySpace 移到分散式運算架構,它在物理上分布的眾多伺服器,整體必須邏輯上等同於單台機器。拿資料庫來說,就不能再像過去那樣將應用拆分,再以不同資料庫分別支援,而必須將整個網站看作一個應用。這次,不再按網站功能和應用分割資料庫,MySpace 開始將它的使用者按每 100 萬一組分割,然後將各組的全部資料分別存入獨立的 SQL Server 執行個體。後來 MySpace 的每台資料庫伺服器實際運行兩個 SQL Server 執行個體,也就是說每台伺服器會服務大約 200 萬使用者。
- 第四代架構 - 增加資料緩衝層
當使用者達到 900-1000 萬時,MySpace再次遭遇儲存瓶頸問題,後來引用了新的 SAN 產品,但網站目前的要求,已經超越 SAN 的 I/O 磁碟儲存系統、及其讀寫資料的極限速度。
當使用者達到 1700 萬時,增加了一個資料緩衝層,其位於 Web 服務器和資料庫伺服器之間,其唯一職能是在記憶體中建立被頻繁請求資料對象的副本。以前每一位使用者查詢一個資訊,就請求一次資料庫;現在當任一個使用者請求資料庫後,緩衝層就會保留一個副本,當其他使用者再訪問時就不需要再請求資料庫了,如此一來,不訪問資料庫也可以供給資料。
- 第五代架構 - 轉到支援 64 位元處理器的作業系統和資料庫軟體
當使用者數達到 2600 萬時,轉到了還處於 Beta 版、但支援 64 位元處理器的 SQL Server 2005。在升級到 64 位元的 SQL Server 2005 和 Windows Server 2003 後,MySpace 每台伺服器配備了 32 GB 記憶體,後來又提升到了 64 GB。
從 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
網站效能最佳化 - 資料庫及伺服器架構篇