無論是國外的Google、Facebook、Amazon,還是國內的Baidu、Taobao等,這些高性能的服務器在處理高并發的請求時,都能快速、準確的給予應答。通過查閱資料,了解現有大型網站的技術架構,發現目前常用的技術有分層、緩存、負載均衡、數據庫性能優化,分布式系統等等。接下類分別對這些技術進行簡單介紹。
1 分層與服務分離
無論OSI的7層網絡結構,還是計算機底層硬件與上層軟件之間的分層,甚至于Web領域大家非常熟悉的MVC開發模式,分層在計算機領域無處不在。分層可以將不同的功能部件獨立起來,下層為上層提供訪問接口,支撐上層的功能;上層調用下層接口來完成服務。
分層也是服務器端采用的一種方法,通過將數據庫、文件資源等與應用服務器分開,可以緩解服務器壓力。
另外,根據業務需求的不同,將明顯沒有交集的業務分開,獨立成不同的模塊單獨進行管理,也可以在很大程度上提升服務器性能。
2 緩存
緩存在計算機很多地方都有涉及,比如在內存與硬盤之間增加Cache、增加IO緩沖區來緩解速度之間的不匹配。緩存的出現主要是依據計算機中著名的二八定律。緩存的技術主要包括本地緩存、分布式緩存、CDN和反向代理。
根據二八定律,80%的操作集中在20%的數據上。網站將常用的數據緩存在本地應用服務器中,以后直接通過緩存中的數據來響應用戶的請求,而不用再去計算。這樣就可以減少響應時間。
分布式緩存相比本地緩存速度要慢,因為應用服務器要訪問專門的緩存服務器來獲取數據,但是應用服務器主要用于處理請求,其自身內存有限,如果緩存大量數據,應用程序的運行速度將受到明顯影響。因此很多大型網站都使用遠程分布式緩存,部署大內存的服務器作為專門的緩存服務器。
緩存的另外兩種表現形式是CDN和反向代理。不同的地方在于,CDN部署在網絡提供商(比如電信、移動、聯通等)的機房,用戶在請求網站服務時,可以直接從網絡提供商機房獲取數據;而反向代理則部署在網站的中心機房,當用戶的請求到中心機房后,首先訪問的服務器是反向代理服務器,如果反向代理服務器中有相應資源的緩存,就將其直接返回給用戶,而不用再去請求應用服務器。
3 負載均衡
負載均衡的原理就是去中心化。當用戶并發請求量巨大時,如果將所有的請求都交給一個服務器去處理,很可能造成服務器宕機,即使能夠正確響應,響應時間也可能會比較長,給用戶造成不好的體驗。
大型網站都是將一個域名綁定不同的服務器IP,這樣表面上好像只有一臺服務器在提供服務,實際則是一個服務器集群在提供相同的服務。負載均衡器接收所有用戶的請求,再根據每臺應用服務器正在處理的請求數量來對請求進行分配。這樣就能在很大程度上提高系統的性能,同時擴展性也得到很大提升——當某臺服務器宕機時,直接替換就可以,其它服務器繼續相應用戶請求;當用戶請求量超過預定峰值時,也可以通過實時增加服務器來緩解壓力。
4 數據庫性能優化
使用緩存后,大部分的數據操作不需要通過數據庫即可完成。但是仍有一部分讀操作(緩存訪問不命中,緩存過期)和全部的寫操作需要訪問數據庫,在網站的用戶達到一定規模時,數據庫因為負載壓力過高而成為網站的瓶頸。因而需要對數據庫進行優化,常用的技術主要包括讀寫分離、結合非關系型數據庫使用、分布式數據庫等。
一般情況下,數據庫讀操作所需要的時間比寫操作的要少很多,通過將數據庫的讀寫操作分離可以明顯改善數據庫性能。目前很多大型網站都配置數據庫主從關系,主數據庫用于寫操作并將數據同步更新到從數據庫上,從數據庫只負責讀操作。例如,新浪云計算平臺(SAE)給用戶的數據庫就進行了主從配置。
同時,可以利用非關系型數據庫和搜索引擎對數據檢索的優勢,來減輕應用服務器直接訪問關系型數據庫的壓力。
當對業務進行分離后,可以根據業務所涉及的數據,將數據庫進行分庫部署在不同的服務器上。
5 冗余
網站需要7x24小時連續運行,但是服務器隨時可能出現故障,特別是服務器規模比較大時,出現某臺服務器宕機是必然事件。要想保證在服務器宕機的情況下網站依然可以繼續服務,不丟失數據,就需要一定程度的服務器冗余運行,數據冗余備份,這樣當某臺服務器宕機時,可以將其上的服務和數據轉移到其它機器上繼續運行。
接下來,我們主要針對緩存中的Memcached技術進行介紹。
1 Memcached
1.1 Memcached簡介
Memcached是一個高性能的分布式對象緩存系統,用于動態Web應用,以減輕數據庫負載[1]。它通過在內存中緩存數據和對象來減少應用程序讀取數據庫的次數,從而提高網站的性能。如圖1是Memcached在網站中的位置示意圖。
圖1 Memcached位置示意圖
Memcached以鍵值對的形式將數據(或對象)緩存在內存中,雖然使用到了多個服務節點,但是和一般分布式緩存系統不同的是,每一份數據在Memcached中只存在一份,每個Memcached服務節點之間相互不可見。因此,Memcached中每份數據的鍵值是唯一的。
簡而言之,Memcached類似于一個典型的非關系型存儲系統,可以歸入基于內容的鍵值對存儲類型[2]。
1.2 Memcached工作原理
當高并發的外部請求訪問服務器時,負載均衡服務器會根據各應用服務器的使用情況進行分配轉發,如果需要對數據進行讀取,應用服務器會按照一定的Hash算法計算鍵值的結果,并根據計算結果訪問Memcached的某一個服務節點,服務節點再次計算鍵值的第二次Hash值,再根據計算結果對數據進行讀取,如果緩存中有數據則直接返回給應用,否則需要從數據庫獲取數據,同時將獲取到的數據寫入到Memcached中[3]。
圖2 Memcached工作原理
2 性能分析
在本機上安裝Memcached,客戶端使用Memcached提供的接口進行數據的存儲與訪問,并與直接通過MySQL獲取數據的方式進行對比。
2.1 Memcached安裝
由于Memcached主要用于服務器端,而服務器端操作系統大多用Linux,因此網上多數教程是關于在Linux上安裝使用Memcached的。在Windows上安裝更加簡單,只需找到對應操作系統的版本即可[4]。
安裝Memcached后,打開服務即可使用相應功能,Memcached默認監聽11211端口,如果是在本機上,直接使用127.0.0.1:11211就可以訪問了,這點和MySQL非常類似。
Memcached提供了很多高級語言的接口,可以根據這些接口來完成對數據的存儲與訪問。
2.2 Memcached和MySQL性能比較
為了比較使用Memcached前后訪問數據性能的情況,進行以下模擬實驗。
硬件條件:
CPU:Intel Core 2.60GHz;
內存:2GB;
軟件條件:
操作系統:Window 64;
Memcached最大內存:64MB;
Memcached最大連接數:1024。
MySQL中共有29120條記錄,使用多線程模擬用戶的并發訪問,每個用戶請求100次數據讀取。表1是在用戶數量為N的條件下,測試所有請求都處理完所用時間T的結果。
表1 測試結果
三種方法說明:MySQL表示所有的數據請求直接通過訪問數據庫返回;隨機Mem表示在增加了Memcached緩存后,對于每個用戶的100次請求,數據之間沒有任何關系,完全隨機;二八定律Mem表示用戶的請求遵循二八定律,就是說平均100次請求中,有比較多的次數訪問的是相同數據,這個可以通過程序模擬,在訪問時控制相應次數訪問相同的數據。
圖3、圖4分別對應表1的兩種數據表示。
圖3 柱狀圖顯示結果
圖4 折線顯示結果
由于在完全隨機訪問的條件下,數據的命中率非常低(幾乎為0),每次請求都需要從數據庫中獲取,同時還要將請求到的數據保存在緩存中,因此效率比直接從數據庫中獲取還要低。但是當用戶多次請求相同的數據是,使用Memcached 明顯比直接從MySQL中獲取效率要高很多。
整個測試過程還存在著一些不足之處:
受實際條件限制,Memcached服務節點數只有1個;
另外,數據庫中數據量級也不是非常大;
沒有測試數據寫入的情況
無論是國外的Google、Facebook、Amazon,還是國內的Baidu、Taobao等,這些高性能的服務器在處理高并發的請求時,都能快速、準確的給予應答。通過查閱資料,了解現有大型網站的技術架構,發現目前常用的技術有分層、緩存、負載均衡、數據庫性能優化,分布式系統等等。接下類分別對這些技術進行簡單介紹。
3 關鍵問題
通過上述分析可知,Memcached在一些條件下對提升數據訪問效率有很大作用。對于那些不常變動訪問頻率又非常高的數據,將其放在緩存中,可以很好的緩解數據庫的壓力,進而提升系統性能。但同時,Memcached自身也還存在著一些不足之處:
由于Memcached是將數據緩存在內存中,當出現斷電情況時,數據將立即消失;
所有數據在Memcached中只保存一份,因此可靠性不是很高,一旦某臺服務節點出現故障,相應的數據將丟失;
Memcached在設計之初每個key的value最大是1MB,隨著目前數據量的快速增長,緩存數據量大的文件,比如音頻、視頻等有很大不足。