一個成熟的大型分布式系統(tǒng)醇王,并不是在其開始時呢燥,就設(shè)計為這樣,而是在之后的不斷優(yōu)化寓娩,迭代而不斷的進化成熟的叛氨。
在一個系統(tǒng)剛開始運行時,可能用戶數(shù)棘伴,業(yè)務(wù)處理等都還比較簡單寞埠,因此由一臺服務(wù)器就能支撐起其正常的業(yè)務(wù)處理。其系統(tǒng)架構(gòu)模型可能如下所示:
- 單應(yīng)用架構(gòu)
其應(yīng)用服務(wù)和數(shù)據(jù)庫服務(wù)焊夸,都部署在同一臺服務(wù)器上仁连。此時應(yīng)用的實現(xiàn)簡單,能夠快速上線阱穗,為用戶提供服務(wù)饭冬。比如很簡單的可以使用Tomcat+Mysql部署在同一臺機器上使鹅,提供服務(wù)。
但是隨著用戶數(shù)量的增加昌抠,業(yè)務(wù)內(nèi)容的不斷增加患朱。其應(yīng)用服務(wù)器的響應(yīng)可能會慢慢變得遲緩,此時需要提升應(yīng)用服務(wù)器的負載能力扰魂,保證用戶的使用體驗麦乞。因此需要采用更好的系統(tǒng)架構(gòu)
- 應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器分離:
應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器的分離,使得應(yīng)用能夠獲得整個服務(wù)器的CPU資源來響應(yīng)用戶請求劝评。應(yīng)用服務(wù)器和數(shù)據(jù)庫服務(wù)器的分離姐直,也大大減少了應(yīng)用的宕機風(fēng)險。此時我們開始關(guān)注服務(wù)器的管理了蒋畜。
- 應(yīng)用服務(wù)器集群:
隨著用戶量的繼續(xù)增加声畏,一臺應(yīng)用服務(wù)器可能不能滿足系統(tǒng)的需求,因此我們需要采用應(yīng)用服務(wù)器的集群架構(gòu)姻成。
通過將用戶的請求分流到不同的應(yīng)用服務(wù)器插龄,從而提高整個系統(tǒng)的負載能力,保證用戶的使用體驗科展。
但是當應(yīng)用服務(wù)器采用集群結(jié)構(gòu)后均牢,遇到了之前不存在的新問題,比如:
(1):用戶的請求由誰來決定才睹,分發(fā)給哪個服務(wù)器來處理(負載均衡問題)徘跪。
(2):用戶在使用網(wǎng)站的過程中,如何維護用戶session琅攘,保證不同的服務(wù)器響應(yīng)請求時垮庐,能保證用戶Session數(shù)據(jù)共享。
因此這個應(yīng)用集群架構(gòu)中坞琴,需要在應(yīng)用服務(wù)器之上哨查,新增一層進行負載均衡。
負載均衡器剧辐,可以分為軟負載和硬負載寒亥。
軟負載: Nginx或Apache等。
硬負載:F5等.
Session共享荧关,可通過配置Tomcat的session共享來解決护盈。但是由于Session在服務(wù)器間的復(fù)制,占用浪費帶寬比較嚴重羞酗,此時建議Tomcat的實例不能過多。
- 數(shù)據(jù)庫服務(wù)器讀寫分離:
在完成了應(yīng)用服務(wù)器的集群分布后紊服,此時的系統(tǒng)瓶頸就卡在數(shù)據(jù)庫服務(wù)這塊了檀轨。在對數(shù)據(jù)庫服務(wù)器進行分布式集群時胸竞,很容易碰到多個數(shù)據(jù)庫實例上的數(shù)據(jù)不一致的問題,因此一般我們會根據(jù)提供的應(yīng)用服務(wù)具體類型参萄,綜合考慮應(yīng)用提供的讀寫服務(wù)頻率等特點卫枝。可以考慮先把數(shù)據(jù)庫服務(wù)的讀寫進行分離讹挎。
此時校赤,系統(tǒng)遇到的問題是:
(1):主從服務(wù)器上的數(shù)據(jù)同步⊥怖#可以使用Mysql自帶的主從復(fù)制马篮。
(2):可以根據(jù)業(yè)務(wù)選擇對應(yīng)的數(shù)據(jù)庫中間件,屏蔽具體的數(shù)據(jù)庫訪問細節(jié)怜奖,如mycat等浑测。
-
使用搜索引擎,緩解數(shù)據(jù)庫讀庫壓力
根據(jù)具體的業(yè)務(wù)類型歪玲,如果設(shè)計到很多模糊查詢迁央,而且數(shù)據(jù)量比較大,此時可以引入搜索引擎滥崩,如Elasticsearch岖圈。
引入了搜索引擎,則需要額外的工作钙皮,如維護索引的構(gòu)建蜂科,數(shù)據(jù)同步到搜索引擎等。
-
引入緩存機制
隨著用戶請求數(shù)量的增加株灸,有一些熱點數(shù)據(jù)崇摄,可能會不斷的被用戶訪問,此時慌烧,可以把這些數(shù)據(jù)放進內(nèi)存中逐抑,既避免訪問數(shù)據(jù)庫,又能加速響應(yīng)用戶請求屹蚊。此時可以開始使用緩存技術(shù)厕氨,比如Redis,Memcache等。
使用緩存機制汹粤,能夠緩存讀庫壓力命斧,提升應(yīng)用性能,與讀庫相比嘱兼,從緩存中讀取數(shù)據(jù)国葬,也能夠更快的響應(yīng)用戶請求。
在有些使用場景中,可能需要使用一些數(shù)據(jù)汇四,這些數(shù)據(jù)放在內(nèi)存中不太合適接奈,而放到數(shù)據(jù)庫中又太麻煩,此時可以考慮使用NoSql產(chǎn)品通孽,來代替?zhèn)鹘y(tǒng)的關(guān)系型數(shù)據(jù)庫序宦,保持這些數(shù)據(jù)。
在分布式系統(tǒng)中背苦,使用NoSql時互捌,也需要考慮緩存是否支持分布式集群。
-
數(shù)據(jù)庫的水平/垂直拆分
隨著業(yè)務(wù)量和數(shù)據(jù)量的持續(xù)增加行剂,由于所有的數(shù)據(jù)都在同一個數(shù)據(jù)庫中秕噪,數(shù)據(jù)庫表非常多且雜,有些一個表中的數(shù)據(jù)記錄已經(jīng)達到了很大的數(shù)量硼讽。盡管采取了讀寫分離巢价,緩存機制等,但是單個數(shù)據(jù)庫中的并發(fā)連接數(shù)有一個上限固阁,因此對數(shù)據(jù)庫的訪問依然會成為一個瓶頸壤躲。
因此需要考慮對數(shù)據(jù)庫進行拆分。
垂直拆分:把不同的業(yè)務(wù)數(shù)據(jù)拆分到不同的數(shù)據(jù)庫中备燃。
水平拆分:把同一張表中的數(shù)據(jù)碉克,拆分到不同的數(shù)據(jù)庫中,水平拆分的原因是某些表中的數(shù)據(jù)量記錄太大并齐,達到了單個數(shù)據(jù)庫的瓶頸漏麦。
- 應(yīng)用的拆分
隨著業(yè)務(wù)越來越多,整個應(yīng)用越來越復(fù)雜况褪,工程規(guī)模也越來越大撕贞。此時的管理維護工作量會越來越復(fù)雜〔舛猓可以考慮根據(jù)領(lǐng)域模型捏膨,對系統(tǒng)進行拆分
對應(yīng)用進行拆分后,可能有一些基本的操作食侮,在每個子系統(tǒng)中号涯,都會使用到,比如訪問用戶數(shù)據(jù)等锯七,此時可以把這些相同的操作链快,抽象出來,通過提供服務(wù)的方式眉尸,提供給各個子系統(tǒng)使用域蜗。
因此此時遇到的一些新問題是巨双,多個子系統(tǒng)之間如何進行遠程通信。比如通過RPC技術(shù)(dubbo,webservice,hession,heep,RMI等)地消,解決遠程通信問題炉峰。
在系統(tǒng)不斷進化時,整個系統(tǒng)也變得越來越復(fù)雜脉执,管理難度越來越大,同時也會不斷的出現(xiàn)新的技術(shù)戒劫,來解決不斷出現(xiàn)的新問題半夷,如微服務(wù),Docker容器技術(shù)迅细,容器編排等巫橄。
最重要的是,根據(jù)應(yīng)用的實際情況茵典,如用戶量湘换,并發(fā)數(shù),數(shù)據(jù)量等采用最合適的架構(gòu)统阿。
Memo
本文轉(zhuǎn)載于互聯(lián)網(wǎng)彩倚,出處不明,如有侵權(quán)扶平,請聯(lián)系刪除