大型網站是指訪問量和數據量都是海量級別的網站系統,大型網站每天的頁面瀏覽量(PV)、訪問量都十分巨大,需要支持高併發;此外,大型網站的數據量也十分巨大,本身的業務也很複雜,需要的技術也最複雜,如:分佈式、緩存、讀寫分離、分庫分表、SOA等等。
但是,萬丈高樓平地起,大型網站也是由簡單的單機系統逐漸構建起來的,所爲本文就介紹一下大型網站的演進過程,以及演進過程中遇到的問題及應對策略。(本文的技術棧爲Java、MySQL)
1 單機應用
在數據量和訪問量都很小的網站初期,一般會把多個軟件都跑在同一個機器上面,即所謂的單機系統。此時,我們可能使用容器tomcat
、jboss
等,然後直接使用JSP
/Servlet
技術,或者開源框架組合SSH
、SSM
,最後再選用數據庫來存儲數據,如:mysql
、sqlserver
、oracle
、db2
等。綜上所述,一個小型的單機系統就可以運行了。
2 應用和數據庫分離
隨着網站的應用逐漸複雜,系統的訪問量增大,服務器的負載壓力變大,就需要升級系統,提高負載能力。有資金實力的,可以增加單機性能,但是在超過一定的限度後,性價比較低。此時,增加機器是一個不錯的解決方法,即有效提升系統負載能力,又有較高的性價比。
在增加機器後,可以把應用和數據庫拆開放到不同的機器上,不僅可以提高單機的負載能力,也可以提高容災能力。
3 應用服務器集羣
隨着訪問量繼續加大,單機應用已經無法滿足負載需求,此時,可以增加應用服務器的數量,從單臺變爲多臺,把用戶的請求分散到不同的服務器中,來提高負載能力。在應用服務器集羣中,不可避免的會遇到服務器出現故障的情況,其中keepalived
是一款故障切換軟件,配合ipvsadm
即可以切換故障,又可以做負載均衡,功能十分強大。
系統演變到這裏會遇到一些問題,即:如何決定某臺服務器來響應當前用戶的請求,以及在應用集羣中會話狀態如何保持或者同步。
下面主要介紹一下會話(Session
)的同步問題。
3.1 Session Sticky
把同一個用戶在一個回話中的請求都分配到固定的服務器中處理,就可以避免跨服務器的Session
問題,常用算法有:sh
(原地址散列)、dh
(目標地址散列)等。
優點:實現簡單
缺點:Session
在應用服務器重啓後消失
3.2 Session Replication
在應用集羣中複製Session
,使得每個服務器都保存有全部用戶的Session
數據。
優點:不需要實現算法來實現請求轉發
缺點:複製Session
時帶寬消耗較大,當訪問量大時,Session
要佔用大量內存
3.3 Session 集中存儲
把Session
集中存儲到一個地方,提供給所有的應用服務器訪問,保證了不同服務器訪問到的Session
數據是一樣的,適用於訪問量比較大的場景中。
優點:解決了Session
複製佔用內存和帶寬的問題,某臺應用服務器的故障不會影響其它服務器正常使用Session
缺點:讀取Session
時引入了網絡操作,增加了延時和不穩定性,如果存儲Session
的機器或者集羣出現問題,將嚴重影響系統使用
3.4 Cookie Based
把Session
存儲在Cookie
中,用戶請求時,服務器根據Cookie
來生成對應的Session
數據。
優點:實現簡單,基本不需要維護
缺點:cookie
長度有限制,安全性較差,消耗額外的帶寬
4 讀寫分離
當網站的訪問量繼續提高,數據庫的讀寫壓力就增大了,但對於數據庫來說,無法簡單的應用集羣來解決壓力問題,因爲數據會不一致,所以常用的解決方案就是讀寫分離。其中,寫庫走主庫,事務中的讀也要走主庫,其它的讀操作可以使用從庫。
數據庫的讀寫分離帶來的問題有主從數據庫的數據同步問題,針對這個問題,可以採用MySQL
自帶的主從模式實現主從複製,也可以使用數據庫中間件MyCAT
。
5 引入搜索引擎
數據庫的模糊查找比較影響性能,即使做了讀寫分離,依然存在這個問題,用戶在查找數據時,常常用到模糊搜索,一般使用like
來實現,但是代價比較大,所有可以使用搜索引擎來實現,來解決模糊查找的讀
問題。
優點:大大提高查詢速度
缺點:增加了維護工作,需要自己實現索引的構建過程,需要維護搜索引擎集羣
6 添加緩存
隨着網站訪問量的進一步加大,數據庫的壓力越來越大,每次訪問都和數據庫交互,會十分影響系統的響應速度,所以可以使用緩存技術。針對熱點數據,直接從內存中取出來返回,加快響應速度。常用的緩存技術方案有:Memcached
、Redis
等。
針對緩存的不同機制,可以分爲數據緩存和頁面緩存
6.1 數據緩存
大型網站添加緩存主要用來分擔數據庫的讀壓力,一般情況下,緩存中存放的是熱數據
,而不是全部數據。緩存的更新方式是在更新數據庫時,同步的更新緩存,保持緩存中的數據和數據庫中的數據是一致的。當緩存容量不夠時,根據LRU
原則清除部分緩存數據。
6.2 頁面緩存
最終展示給用戶的是頁面,對於一些訪問量特別高的動態頁面,也可以採用緩存技術,將頁面緩存起來,利用ESI
規範,加快請求的響應。
優點:減輕數據庫壓力,大幅度提高訪問速度
缺點:需要維護緩存服務器,提高了編碼的複雜性
7 引入分佈式存儲系統
在需要大容量、高併發、容災支持的系統中,常用的關係型數據庫並不是十分合適,所以需要新的存儲系統,即分佈式存儲系統,包括下面3
種:
7.1 分佈式文件系統
在分佈式環境中由多個節點組成的功能與單機系統一樣的文件系統,它是弱格式的,如:MongoDB
、FastDFS
、HDFS
等
7.2 分佈式Key-Value
系統
比分佈式文件系統會更加格式化一些,提供了高性能的半結構化的數據存儲支持
7.3 分佈式數據庫
格式化最規範的存儲方式,支持大容量和高併發
8 數據庫的拆分
在網站的業務越來越複雜,數據量也越來越大時,所有的業務都存儲的單一的數據庫中,但是單一的數據庫或者已經做了讀寫分離但是依然無法滿足系統性能的要求,解決這樣的數據庫瓶頸問題,可以採用數據的垂直拆分和水平拆分。
8.1 水平拆分
數據的水平拆分是把同一張表的數據拆分到多個數據庫中。
優點:解決數據量爆炸性增長,數據庫單表容量有限的問題
缺點:存在SQL
路由的問題,及誇數據庫的事務問題
針對缺點的解決方法可以採用數據庫中間件MyCAT
,也可以不用數據庫的自增主鍵,自定義唯一主鍵的方式
8.2 垂直拆分
數據的垂直拆分是把數據庫中的不同業務拆分到不同的數據庫中
優點:解決了數據庫的壓力,可以更加業務特點做優化
缺點:需要維護多個數據庫,針對複雜業務需求會降低查詢性能,存在跨數據的join
和事務問題
解決方案是儘量避免跨數據庫的事務,或者採用單一查詢,也可以利用MyCat
的跨庫方案來解決
9 拆分應用
當業務越來越多,應用系統會變得十分龐大,這時就需要考慮如何避免系統變臃腫而難以維護,拆分應用是一個不錯的解決方案。根據業務把應用拆開,從一個應用變成多個應用,各個業務不存在直接的調用情況。但是拆分應用,不可避免地存在着冗餘代碼的問題。
10 SOA架構
對於系統中不同的業務,以及一些公共的業務部分,還可以進一步優化,比如採用SOA
架構,把這些業務進一步拆分出來,形成服務化的結構,不僅可以解決冗餘代碼的問題,也可以使不同業務間調用解耦。
11 引入消息中間件
消息中間件提供了消息的異步和解耦的功能,是分佈式系統中完成消息收發的基礎軟件,常用的有:Dubbo
、ActiveMQ
,配合ZooKeeper
使用,可以使系統解耦更徹底,並且也可以做消息的分析、網站的成長預測等。
大型網站的演進基本如上所述,但是也沒有固定的模式,也不會適合所有的網站,具體選擇哪種模式還要根據業務量和遇到的問題做具體的分析。但是,熟悉常見的網站演進模式,在遇到具體的問題時,可以快速找到適合自己網站的架構。(文中的圖片來自互聯網,版權歸原作者所有)
參考資料