大型網(wǎng)站是指訪問量和數(shù)據(jù)量都是海量級別的網(wǎng)站系統(tǒng)蝶棋,大型網(wǎng)站每天的頁面瀏覽量(PV)、訪問量都十分巨大忽妒,需要支持高并發(fā)玩裙;此外,大型網(wǎng)站的數(shù)據(jù)量也十分巨大段直,本身的業(yè)務(wù)也很復(fù)雜吃溅,需要的技術(shù)也最復(fù)雜,如:分布式鸯檬、緩存决侈、讀寫分離、分庫分表喧务、SOA等等赖歌。
但是枉圃,萬丈高樓平地起,大型網(wǎng)站也是由簡單的單機(jī)系統(tǒng)逐漸構(gòu)建起來的庐冯,所為本文就介紹一下大型網(wǎng)站的演進(jìn)過程孽亲,以及演進(jìn)過程中遇到的問題及應(yīng)對策略。(本文的技術(shù)棧為Java展父、MySQL)
1 單機(jī)應(yīng)用
在數(shù)據(jù)量和訪問量都很小的網(wǎng)站初期返劲,一般會把多個軟件都跑在同一個機(jī)器上面,即所謂的單機(jī)系統(tǒng)栖茉。此時篮绿,我們可能使用容器tomcat
、jboss
等吕漂,然后直接使用JSP
/Servlet
技術(shù)搔耕,或者開源框架組合SSH
、SSM
痰娱,最后再選用數(shù)據(jù)庫來存儲數(shù)據(jù)弃榨,如:mysql
、sqlserver
梨睁、oracle
鲸睛、db2
等。綜上所述坡贺,一個小型的單機(jī)系統(tǒng)就可以運行了官辈。
2 應(yīng)用和數(shù)據(jù)庫分離
隨著網(wǎng)站的應(yīng)用逐漸復(fù)雜,系統(tǒng)的訪問量增大遍坟,服務(wù)器的負(fù)載壓力變大拳亿,就需要升級系統(tǒng),提高負(fù)載能力愿伴。有資金實力的肺魁,可以增加單機(jī)性能,但是在超過一定的限度后隔节,性價比較低鹅经。此時,增加機(jī)器是一個不錯的解決方法怎诫,即有效提升系統(tǒng)負(fù)載能力瘾晃,又有較高的性價比。
在增加機(jī)器后幻妓,可以把應(yīng)用和數(shù)據(jù)庫拆開放到不同的機(jī)器上蹦误,不僅可以提高單機(jī)的負(fù)載能力,也可以提高容災(zāi)能力。
3 應(yīng)用服務(wù)器集群
隨著訪問量繼續(xù)加大强胰,單機(jī)應(yīng)用已經(jīng)無法滿足負(fù)載需求尚镰,此時,可以增加應(yīng)用服務(wù)器的數(shù)量哪廓,從單臺變?yōu)槎嗯_狗唉,把用戶的請求分散到不同的服務(wù)器中,來提高負(fù)載能力涡真。在應(yīng)用服務(wù)器集群中分俯,不可避免的會遇到服務(wù)器出現(xiàn)故障的情況,其中keepalived
是一款故障切換軟件哆料,配合ipvsadm
即可以切換故障缸剪,又可以做負(fù)載均衡,功能十分強(qiáng)大东亦。
系統(tǒng)演變到這里會遇到一些問題杏节,即:如何決定某臺服務(wù)器來響應(yīng)當(dāng)前用戶的請求,以及在應(yīng)用集群中會話狀態(tài)如何保持或者同步典阵。
下面主要介紹一下會話(Session
)的同步問題奋渔。
3.1 Session Sticky
把同一個用戶在一個回話中的請求都分配到固定的服務(wù)器中處理,就可以避免跨服務(wù)器的Session
問題壮啊,常用算法有:sh
(原地址散列)嫉鲸、dh
(目標(biāo)地址散列)等。
優(yōu)點:實現(xiàn)簡單
缺點:Session
在應(yīng)用服務(wù)器重啟后消失
3.2 Session Replication
在應(yīng)用集群中復(fù)制Session
歹啼,使得每個服務(wù)器都保存有全部用戶的Session
數(shù)據(jù)玄渗。
優(yōu)點:不需要實現(xiàn)算法來實現(xiàn)請求轉(zhuǎn)發(fā)
缺點:復(fù)制Session
時帶寬消耗較大,當(dāng)訪問量大時狸眼,Session
要占用大量內(nèi)存
3.3 Session 集中存儲
把Session
集中存儲到一個地方藤树,提供給所有的應(yīng)用服務(wù)器訪問,保證了不同服務(wù)器訪問到的Session
數(shù)據(jù)是一樣的拓萌,適用于訪問量比較大的場景中岁钓。
優(yōu)點:解決了Session
復(fù)制占用內(nèi)存和帶寬的問題,某臺應(yīng)用服務(wù)器的故障不會影響其它服務(wù)器正常使用Session
缺點:讀取Session
時引入了網(wǎng)絡(luò)操作司志,增加了延時和不穩(wěn)定性甜紫,如果存儲Session
的機(jī)器或者集群出現(xiàn)問題降宅,將嚴(yán)重影響系統(tǒng)使用
3.4 Cookie Based
把Session
存儲在Cookie
中骂远,用戶請求時,服務(wù)器根據(jù)Cookie
來生成對應(yīng)的Session
數(shù)據(jù)腰根。
優(yōu)點:實現(xiàn)簡單激才,基本不需要維護(hù)
缺點:cookie
長度有限制,安全性較差,消耗額外的帶寬
4 讀寫分離
當(dāng)網(wǎng)站的訪問量繼續(xù)提高瘸恼,數(shù)據(jù)庫的讀寫壓力就增大了劣挫,但對于數(shù)據(jù)庫來說,無法簡單的應(yīng)用集群來解決壓力問題东帅,因為數(shù)據(jù)會不一致压固,所以常用的解決方案就是讀寫分離。其中靠闭,寫庫走主庫帐我,事務(wù)中的讀也要走主庫,其它的讀操作可以使用從庫愧膀。
數(shù)據(jù)庫的讀寫分離帶來的問題有主從數(shù)據(jù)庫的數(shù)據(jù)同步問題拦键,針對這個問題,可以采用MySQL
自帶的主從模式實現(xiàn)主從復(fù)制檩淋,也可以使用數(shù)據(jù)庫中間件MyCAT
芬为。
5 引入搜索引擎
數(shù)據(jù)庫的模糊查找比較影響性能,即使做了讀寫分離蟀悦,依然存在這個問題媚朦,用戶在查找數(shù)據(jù)時,常常用到模糊搜索日戈,一般使用like
來實現(xiàn)莲镣,但是代價比較大,所有可以使用搜索引擎來實現(xiàn)涎拉,來解決模糊查找的讀
問題瑞侮。
優(yōu)點:大大提高查詢速度
缺點:增加了維護(hù)工作,需要自己實現(xiàn)索引的構(gòu)建過程鼓拧,需要維護(hù)搜索引擎集群
6 添加緩存
隨著網(wǎng)站訪問量的進(jìn)一步加大半火,數(shù)據(jù)庫的壓力越來越大,每次訪問都和數(shù)據(jù)庫交互季俩,會十分影響系統(tǒng)的響應(yīng)速度钮糖,所以可以使用緩存技術(shù)。針對熱點數(shù)據(jù)酌住,直接從內(nèi)存中取出來返回店归,加快響應(yīng)速度。常用的緩存技術(shù)方案有:Memcached
酪我、Redis
等消痛。
針對緩存的不同機(jī)制,可以分為數(shù)據(jù)緩存和頁面緩存
6.1 數(shù)據(jù)緩存
大型網(wǎng)站添加緩存主要用來分擔(dān)數(shù)據(jù)庫的讀壓力都哭,一般情況下秩伞,緩存中存放的是熱數(shù)據(jù)
逞带,而不是全部數(shù)據(jù)。緩存的更新方式是在更新數(shù)據(jù)庫時纱新,同步的更新緩存展氓,保持緩存中的數(shù)據(jù)和數(shù)據(jù)庫中的數(shù)據(jù)是一致的。當(dāng)緩存容量不夠時脸爱,根據(jù)LRU
原則清除部分緩存數(shù)據(jù)遇汞。
6.2 頁面緩存
最終展示給用戶的是頁面,對于一些訪問量特別高的動態(tài)頁面簿废,也可以采用緩存技術(shù)勺疼,將頁面緩存起來,利用ESI
規(guī)范捏鱼,加快請求的響應(yīng)执庐。
優(yōu)點:減輕數(shù)據(jù)庫壓力,大幅度提高訪問速度
缺點:需要維護(hù)緩存服務(wù)器导梆,提高了編碼的復(fù)雜性
7 引入分布式存儲系統(tǒng)
在需要大容量轨淌、高并發(fā)、容災(zāi)支持的系統(tǒng)中看尼,常用的關(guān)系型數(shù)據(jù)庫并不是十分合適递鹉,所以需要新的存儲系統(tǒng),即分布式存儲系統(tǒng)藏斩,包括下面3
種:
7.1 分布式文件系統(tǒng)
在分布式環(huán)境中由多個節(jié)點組成的功能與單機(jī)系統(tǒng)一樣的文件系統(tǒng)躏结,它是弱格式的,如:MongoDB
狰域、FastDFS
媳拴、HDFS
等
7.2 分布式Key-Value
系統(tǒng)
比分布式文件系統(tǒng)會更加格式化一些,提供了高性能的半結(jié)構(gòu)化的數(shù)據(jù)存儲支持
7.3 分布式數(shù)據(jù)庫
格式化最規(guī)范的存儲方式兆览,支持大容量和高并發(fā)
8 數(shù)據(jù)庫的拆分
在網(wǎng)站的業(yè)務(wù)越來越復(fù)雜屈溉,數(shù)據(jù)量也越來越大時,所有的業(yè)務(wù)都存儲的單一的數(shù)據(jù)庫中抬探,但是單一的數(shù)據(jù)庫或者已經(jīng)做了讀寫分離但是依然無法滿足系統(tǒng)性能的要求子巾,解決這樣的數(shù)據(jù)庫瓶頸問題,可以采用數(shù)據(jù)的垂直拆分和水平拆分小压。
8.1 水平拆分
數(shù)據(jù)的水平拆分是把同一張表的數(shù)據(jù)拆分到多個數(shù)據(jù)庫中线梗。
優(yōu)點:解決數(shù)據(jù)量爆炸性增長,數(shù)據(jù)庫單表容量有限的問題
缺點:存在SQL
路由的問題怠益,及夸數(shù)據(jù)庫的事務(wù)問題
針對缺點的解決方法可以采用數(shù)據(jù)庫中間件MyCAT
仪搔,也可以不用數(shù)據(jù)庫的自增主鍵,自定義唯一主鍵的方式
8.2 垂直拆分
數(shù)據(jù)的垂直拆分是把數(shù)據(jù)庫中的不同業(yè)務(wù)拆分到不同的數(shù)據(jù)庫中
優(yōu)點:解決了數(shù)據(jù)庫的壓力溉痢,可以更加業(yè)務(wù)特點做優(yōu)化
缺點:需要維護(hù)多個數(shù)據(jù)庫僻造,針對復(fù)雜業(yè)務(wù)需求會降低查詢性能憋他,存在跨數(shù)據(jù)的join
和事務(wù)問題
解決方案是盡量避免跨數(shù)據(jù)庫的事務(wù)孩饼,或者采用單一查詢髓削,也可以利用MyCat
的跨庫方案來解決
9 拆分應(yīng)用
當(dāng)業(yè)務(wù)越來越多,應(yīng)用系統(tǒng)會變得十分龐大镀娶,這時就需要考慮如何避免系統(tǒng)變臃腫而難以維護(hù)立膛,拆分應(yīng)用是一個不錯的解決方案。根據(jù)業(yè)務(wù)把應(yīng)用拆開梯码,從一個應(yīng)用變成多個應(yīng)用宝泵,各個業(yè)務(wù)不存在直接的調(diào)用情況。但是拆分應(yīng)用轩娶,不可避免地存在著冗余代碼的問題儿奶。
10 SOA架構(gòu)
對于系統(tǒng)中不同的業(yè)務(wù),以及一些公共的業(yè)務(wù)部分鳄抒,還可以進(jìn)一步優(yōu)化闯捎,比如采用SOA
架構(gòu),把這些業(yè)務(wù)進(jìn)一步拆分出來许溅,形成服務(wù)化的結(jié)構(gòu)瓤鼻,不僅可以解決冗余代碼的問題,也可以使不同業(yè)務(wù)間調(diào)用解耦贤重。
11 引入消息中間件
消息中間件提供了消息的異步和解耦的功能茬祷,是分布式系統(tǒng)中完成消息收發(fā)的基礎(chǔ)軟件,常用的有:Dubbo
并蝗、ActiveMQ
祭犯,配合ZooKeeper
使用,可以使系統(tǒng)解耦更徹底滚停,并且也可以做消息的分析盹憎、網(wǎng)站的成長預(yù)測等。
大型網(wǎng)站的演進(jìn)基本如上所述铐刘,但是也沒有固定的模式陪每,也不會適合所有的網(wǎng)站,具體選擇哪種模式還要根據(jù)業(yè)務(wù)量和遇到的問題做具體的分析镰吵。但是檩禾,熟悉常見的網(wǎng)站演進(jìn)模式,在遇到具體的問題時疤祭,可以快速找到適合自己網(wǎng)站的架構(gòu)盼产。(文中的圖片來自互聯(lián)網(wǎng),版權(quán)歸原作者所有)
參考資料
《大型網(wǎng)站系統(tǒng)與Java中間件實踐》
阿里P9架構(gòu)師簡述從單機(jī)至億級流量大型網(wǎng)站系統(tǒng)架構(gòu)的演進(jìn)過程