大型網(wǎng)站技術(shù)架構(gòu)的演進(jìn)之路
作者:翟志軍
原文:https://my.oschina.net/zjzhai/blog/389266
作者:翟志軍
原文:https://my.oschina.net/zjzhai/blog/389266
最近我在閱讀2本關(guān)于大型網(wǎng)站架構(gòu)的書:《大型網(wǎng)站技術(shù)架構(gòu)——核心原理與案例分析》李智慧、《大型網(wǎng)站系統(tǒng)與Java中間件實(shí)踐》曾憲杰。
我期望從這些書中學(xué)習(xí)到大型網(wǎng)站是如何做架構(gòu)的,這個(gè)過(guò)程會(huì)遇到什么問(wèn)題。當(dāng)看完這2本書后,我總結(jié)出兩個(gè)大問(wèn)題:
1. 網(wǎng)站技術(shù)架構(gòu)為什么會(huì)演進(jìn)?換個(gè)說(shuō)法就是為什么網(wǎng)站會(huì)變大?
2. 演進(jìn)的過(guò)程會(huì)遇到什么問(wèn)題?或者說(shuō)為了演進(jìn),會(huì)遇到什么問(wèn)題?
網(wǎng)站技術(shù)架構(gòu)為什么會(huì)演進(jìn)
我個(gè)人總結(jié)出來(lái)我們的技術(shù)架構(gòu)演進(jìn)的兩種驅(qū)動(dòng)力,驅(qū)動(dòng)著我們?yōu)槭裁囱葸M(jìn)網(wǎng)站的技術(shù)架構(gòu):
1. 內(nèi)在驅(qū)動(dòng)力:我們期望把當(dāng)前的業(yè)務(wù)做得更好,開發(fā)更多新業(yè)務(wù)
2. 外在驅(qū)動(dòng)力:用戶量的上升、用戶種類的多樣化
這兩種驅(qū)動(dòng)力不是獨(dú)立的,更多時(shí)候是并行的。我想淘寶就是兩種驅(qū)動(dòng)力并行驅(qū)動(dòng)的結(jié)果。
演進(jìn)的原因很簡(jiǎn)單。但是在什么時(shí)機(jī)我們就應(yīng)該演進(jìn)網(wǎng)站的技術(shù)架構(gòu)了,以及如何演進(jìn)?面對(duì)這些問(wèn)題,說(shuō)實(shí)話,我沒(méi)有任何經(jīng)驗(yàn),再說(shuō)現(xiàn)實(shí)中每家企業(yè)當(dāng)時(shí)都面臨的問(wèn)題都不一樣,所以,我很難從經(jīng)驗(yàn)中總結(jié)出什么是演進(jìn)的時(shí)機(jī)。
但是我可以從另一個(gè)角度切入這個(gè)問(wèn)題:研究網(wǎng)站內(nèi)外結(jié)構(gòu),找到這些結(jié)構(gòu)可能出現(xiàn)的問(wèn)題點(diǎn),知道或者預(yù)見到問(wèn)題點(diǎn)了,你當(dāng)然就知道應(yīng)該怎么演進(jìn)了。類似于你了解了PC機(jī)的結(jié)構(gòu),你也就知道什么時(shí)候要加內(nèi)存了,什么時(shí)候要加硬盤了。
那么我們先看看網(wǎng)站的外部結(jié)構(gòu):

外部結(jié)構(gòu)中,我們可以看由以下幾個(gè)部分構(gòu)成:
U:代表用戶群。當(dāng)用戶群變了,我們的網(wǎng)站如何演進(jìn)?用戶群的分析,我目前能知道的維度有:數(shù)量,種類,地理位置(區(qū)域)。
N:代表網(wǎng)絡(luò)環(huán)境。網(wǎng)絡(luò)環(huán)境在每個(gè)地區(qū)都不同。你可以想像我們?yōu)槭裁葱枰狢DN。當(dāng)我們期望每個(gè)區(qū)域的用戶都能得到好的體驗(yàn),我們的網(wǎng)站如何演進(jìn)?
S:代表安全。就是我們要安全到什么程度?這與網(wǎng)站當(dāng)前所處階段及你網(wǎng)站的性質(zhì)有關(guān)。
C:代表我們的網(wǎng)站。屬于內(nèi)部結(jié)構(gòu)
網(wǎng)站的內(nèi)部結(jié)構(gòu):

內(nèi)部結(jié)構(gòu)的組成:
A:應(yīng)用服務(wù)。
D:數(shù)據(jù)服務(wù)
總結(jié)下來(lái)就是我們?cè)诳紤]網(wǎng)站是否應(yīng)該演進(jìn)了或者如何演進(jìn)時(shí),這些組成部分為我們提供了考慮問(wèn)題的基準(zhǔn)。
那么我們?yōu)槭裁床灰婚_始就把網(wǎng)站設(shè)計(jì)成“大型”的。李智慧在后記里寫到:“不要企圖去設(shè)計(jì)一個(gè)大型網(wǎng)站”,“原因是互聯(lián)網(wǎng)發(fā)展運(yùn)行有其自己的規(guī)律,短暫的互聯(lián)網(wǎng)歷史已經(jīng)一再證明這種企圖行不通”。還說(shuō)了:“大型網(wǎng)站不是設(shè)計(jì)出來(lái)的,而是逐步演化出來(lái)的”。對(duì)于最后這句話,我需要提醒下:“不是設(shè)計(jì)出來(lái)的”并不代表“隨意設(shè)計(jì)”。
對(duì)于“大型網(wǎng)站的設(shè)計(jì)”,我個(gè)人的看法是現(xiàn)在我們的有“云”了,計(jì)算是可以買的,只要我們的設(shè)計(jì)能適應(yīng)“云”,我是不是就可以一開始就設(shè)計(jì)大型網(wǎng)站了?
演進(jìn)的過(guò)程會(huì)遇到什么問(wèn)題
-?最初
從一個(gè)小網(wǎng)站說(shuō)起。一臺(tái)服務(wù)器也就足夠了。

-?數(shù)據(jù)服務(wù)與應(yīng)用服務(wù)分離
越來(lái)越多的用戶代表著越來(lái)越多的數(shù)據(jù),一臺(tái)服務(wù)器已經(jīng)滿足不了。我們將數(shù)據(jù)服務(wù)和應(yīng)用服務(wù)分離,給應(yīng)用服務(wù)器配置更好的CPU,內(nèi)存。而給數(shù)據(jù)服務(wù)器配置更好更大的硬盤。

- 使用緩存
因?yàn)?0%的業(yè)務(wù)訪問(wèn)都集中在20%的數(shù)據(jù)上,如果我們能將這部分?jǐn)?shù)據(jù)緩存下來(lái),性能一下子就上來(lái)了。而緩存又分為兩種:本地緩存和遠(yuǎn)程分布式緩存。具體使用哪種?還是兩種都用,我目前不知道。

這里有一個(gè)問(wèn)題,書沒(méi)有提到:應(yīng)該緩存哪些數(shù)據(jù)?應(yīng)該有一些原則的吧。
- 使用服務(wù)器集群
當(dāng)這臺(tái)服務(wù)器的處理能力達(dá)到上限時(shí),它就會(huì)成為瓶頸。雖然你是可以通過(guò)購(gòu)買更強(qiáng)大的硬件,但總會(huì)有上限。這時(shí),我們就需要服務(wù)器的集群。這時(shí),就必須加個(gè)新東西:負(fù)載均衡調(diào)度服務(wù)器。

但是,使用服務(wù)器集群時(shí),需要考慮一個(gè)問(wèn)題:Session的管理問(wèn)題。Session的管理有以下幾種方式:
* Session Sticky:打個(gè)比方就是如果我們每次吃飯都要保證我們用的是自己的碗筷,而只要我們?cè)谝患绎埖昀锎嬷覀兊耐肟辏灰覀兠看稳ミ@家飯店吃飯就好了。
? ? ?
? ? ?這種方式的問(wèn)題:
? ? ?1. 一臺(tái)服務(wù)器重啟,上面的session都沒(méi)了
? ? ?2. 負(fù)載均衡器成了有狀態(tài)的機(jī)器,要實(shí)現(xiàn)容災(zāi)會(huì)有麻煩
* Session復(fù)制:就像我們?cè)谒械娘埖昀锒即嬉环葑约旱耐肟辍2贿m合做大規(guī)模集群,適合機(jī)器不多的情況

? ? ?這種方案的問(wèn)題:
? ? ?1. 應(yīng)用服務(wù)器間帶寬問(wèn)題
? ? ?2. 大量用戶在線時(shí),占用內(nèi)存過(guò)多
* 基于Cookie:類似于每次吃飯都把自己的碗筷帶上
? ? ?
? ? ?這種方案的問(wèn)題:
? ? ?1. Cookie的長(zhǎng)度限制
? ? ?2. 安全性
? ? ?3. 數(shù)據(jù)中心外部帶寬的消耗
? ? ?4. 性能影響,服務(wù)器處理每次的請(qǐng)求的內(nèi)容又多了
* Session服務(wù)器:同樣可以是集群的。這種方式適用于session數(shù)量及web服務(wù)器數(shù)量大的情況

? ? ?這種方案需要考慮的是:
? ? ?1. 保證session服務(wù)器的可用性
? ? ?2. 我們?cè)趯憫?yīng)用時(shí)需要做調(diào)整,我目前不知道應(yīng)用服務(wù)器能否將這部分邏輯透明化
- 數(shù)據(jù)庫(kù)讀寫分離
數(shù)據(jù)庫(kù)的一部分讀(未緩存、緩存過(guò)期)及所有的寫操作都還需要經(jīng)過(guò)數(shù)據(jù)庫(kù)。當(dāng)用戶量達(dá)到一定量,數(shù)據(jù)庫(kù)將會(huì)成為瓶頸。這邊我們使用數(shù)據(jù)庫(kù)提供的熱備功能,將所有的讀操作引入slave服務(wù)器。注意:讀寫分離解決的是讀壓力大的問(wèn)題。

因?yàn)閿?shù)據(jù)庫(kù)的讀寫分離了,所以,我們的應(yīng)用程序也得做相應(yīng)的變化。我們實(shí)現(xiàn)一個(gè)數(shù)據(jù)訪問(wèn)模塊使上層寫代碼的人不知道讀寫分離的存在。這里,我很想知道如果我使用ORM模型時(shí),如何實(shí)現(xiàn)讀寫的分離?
數(shù)據(jù)庫(kù)讀寫分離會(huì)遇到如下問(wèn)題:
* 數(shù)據(jù)復(fù)制問(wèn)題:考慮時(shí)延、數(shù)據(jù)庫(kù)的支持、復(fù)制條件支持。不要忘了,分機(jī)房后,這個(gè)更是問(wèn)題。
* 應(yīng)用對(duì)于數(shù)據(jù)源的路由問(wèn)題
- 使用反向代理和CDN加速網(wǎng)站響應(yīng)
使用CDN可以很好的解決不同的地區(qū)的訪問(wèn)速度問(wèn)題,反向代理則在服務(wù)器機(jī)房中緩存用戶資源:

- 使用分布式文件系統(tǒng)

- 數(shù)據(jù)庫(kù)專庫(kù)專用:數(shù)據(jù)垂直拆分。這樣可以解決部分?jǐn)?shù)據(jù)寫的問(wèn)題

垂直拆分?jǐn)?shù)據(jù)庫(kù)時(shí),會(huì)遇到的問(wèn)題:
* 跨業(yè)務(wù)的事務(wù)
* 應(yīng)用的配置項(xiàng)多了
關(guān)于事務(wù)的問(wèn)題,有兩種辦法:
* 使用分布式事務(wù)
* 去掉事務(wù)或不追求強(qiáng)事務(wù)
-?某個(gè)業(yè)務(wù)的數(shù)據(jù)表的數(shù)據(jù)量或者更新量達(dá)到了單個(gè)數(shù)據(jù)庫(kù)的瓶頸:數(shù)據(jù)水平拆分
將同一個(gè)表的數(shù)據(jù)拆分到兩個(gè)數(shù)據(jù)庫(kù)中

數(shù)據(jù)水平拆分會(huì)遇到的問(wèn)題:
* SQL的路由問(wèn)題,需要知道某個(gè)User在哪個(gè)數(shù)據(jù)庫(kù)上。
* 主鍵的策略會(huì)有不同。
* 查詢時(shí)的性能問(wèn)題,如分頁(yè)問(wèn)題
- 使用搜索引擎:解決數(shù)據(jù)查詢問(wèn)題
- 部分場(chǎng)景可使用NoSQL提高性能
- 開發(fā)數(shù)據(jù)統(tǒng)一訪問(wèn)模塊:解決上層應(yīng)用開發(fā)的數(shù)據(jù)源問(wèn)題

- 業(yè)務(wù)拆分及應(yīng)用拆分
網(wǎng)站的業(yè)務(wù)日益復(fù)雜,建立一個(gè)獨(dú)立的大型應(yīng)用來(lái)完成這所有的業(yè)務(wù)變得不實(shí)際。從管理角度來(lái),也不方便管理。然而,業(yè)務(wù)的拆分很難找到一種通用的模式,這是一個(gè)企業(yè)管理問(wèn)題和技術(shù)問(wèn)題的混合問(wèn)題。同時(shí)和每個(gè)企業(yè)的具體情況有關(guān)。
但是從這兩本書來(lái)看,最終架構(gòu)都走向服務(wù)化,也就是SOA。而如何實(shí)現(xiàn)SOA,是另一個(gè)很大的話題,不是本篇文章的范疇。
我從程立08年的演講中截個(gè)圖來(lái)說(shuō)明SOA后的架構(gòu)大概是怎樣的:

- 非功能性問(wèn)題
? ? ?- 安全性問(wèn)題、監(jiān)控問(wèn)題
?????- 發(fā)布問(wèn)題:新的架構(gòu)意味著新的發(fā)布方式
?????- 分機(jī)房
? ?? ?????這兩本書都沒(méi)有說(shuō)分機(jī)房的問(wèn)題。我沒(méi)有經(jīng)驗(yàn),可是也可以猜到如果要分機(jī)房了,所有上面的問(wèn)題都可能要重新考慮。
?????- 組織架構(gòu)的變化?
? ?? ?????我們的技術(shù)架構(gòu)的變化,勢(shì)必會(huì)引起我們的組織架構(gòu)的變化,反之亦然。
? ?? ?????這部分看似不應(yīng)該由我們來(lái)管,但是,我覺(jué)得,我們技術(shù)人員也要參與一部分的組織架構(gòu)的設(shè)計(jì)。舉個(gè)例子,組織架構(gòu)的設(shè)計(jì)會(huì)涉及績(jī)效,而績(jī)效有時(shí)很像一個(gè)國(guó)家的法律。如果一個(gè)國(guó)家的法律不健全,會(huì)發(fā)生什么?你懂的。
? ?? ?????同時(shí),我們還必須考慮人員對(duì)新架構(gòu)的學(xué)習(xí)成本。
? ?? ?????這部分我目前在看相關(guān)的書籍,還沒(méi)有一個(gè)系統(tǒng)的認(rèn)識(shí)。
總結(jié):
- 關(guān)于演進(jìn)的順序
在現(xiàn)實(shí)中,技術(shù)架構(gòu)的演進(jìn)不一定就是按文章從頭到尾這樣列下來(lái)的,所以,要視具體情況來(lái)下決定。
- 關(guān)于傳統(tǒng)演進(jìn)與現(xiàn)代有“云”環(huán)境下的演進(jìn)
很可惜,只有李智慧談到云,而且只點(diǎn)了一下——“現(xiàn)在越來(lái)越多人的網(wǎng)站從建立之初就是搭建在大型網(wǎng)站提供的云計(jì)算服務(wù)基礎(chǔ)之上,所需的一切資源:計(jì)算、存儲(chǔ)、網(wǎng)絡(luò)都可以按需購(gòu)買線性伸縮,不需要自己一點(diǎn)一點(diǎn)地拼湊各種資源,綜合使用各種技術(shù)方案逐步去完善自己的網(wǎng)站架構(gòu)”。
因?yàn)槲矣谩霸啤钡臅r(shí)間也不長(zhǎng),還不能總結(jié)出有云架構(gòu)與傳統(tǒng)的無(wú)云架構(gòu)在演進(jìn)的時(shí)候有什么不同。
說(shuō)回傳統(tǒng)的架構(gòu)演進(jìn),我自己總結(jié)和思考的結(jié)果是:
在對(duì)網(wǎng)站進(jìn)行架構(gòu)調(diào)整時(shí),可以從兩大的維度考慮:數(shù)據(jù)服務(wù)和應(yīng)用服務(wù)。而這個(gè)調(diào)整的過(guò)程中,需要分清當(dāng)前哪個(gè)點(diǎn)是瓶頸,需要知道哪個(gè)點(diǎn)優(yōu)化的優(yōu)先級(jí)最高。同時(shí),最重要的一點(diǎn):我們雖然作為技術(shù)人員,也應(yīng)該去學(xué)習(xí)業(yè)務(wù)知識(shí),這樣我們?cè)诳紤]問(wèn)題時(shí)分清哪些是業(yè)務(wù)問(wèn)題,哪些是技術(shù)問(wèn)題,分清后才能對(duì)癥下藥。你要知道有些問(wèn)題用技術(shù)手段并不比用業(yè)務(wù)手段更有效。12306的分時(shí)賣票就是一個(gè)典型例子。
- END -
?推薦閱讀? 30個(gè)Python極簡(jiǎn)代碼,10分鐘get常用技巧!
Java 應(yīng)用最常見的3個(gè)問(wèn)題排查思路
記一次線上商城系統(tǒng)高并發(fā)的優(yōu)化
點(diǎn)亮,服務(wù)器三年不宕機(jī)

