一個成熟的大型分散式系統,並不是在其開始時,就設計為這樣,而是在之後的不斷優化,迭代而不斷的進化成熟的。 在一個系統剛開始運行時,可能用戶數,業務處理等都還比較簡單,因此由一臺伺服器就能支撐起其正常的業務處理。其系統架構模型可能如下所示: 1,單應用架構 其應用服務和資料庫服務,都部署在同一臺伺服器 ...
一個成熟的大型分散式系統,並不是在其開始時,就設計為這樣,而是在之後的不斷優化,迭代而不斷的進化成熟的。
在一個系統剛開始運行時,可能用戶數,業務處理等都還比較簡單,因此由一臺伺服器就能支撐起其正常的業務處理。其系統架構模型可能如下所示:
1,單應用架構
其應用服務和資料庫服務,都部署在同一臺伺服器上。此時應用的實現簡單,能夠快速上線,為用戶提供服務。比如很簡單的可以使用Tomcat+Mysql部署在同一臺機器上,提供服務。
但是隨著用戶數量的增加,業務內容的不斷增加。其應用伺服器的響應可能會慢慢變得遲緩,此時需要提升應用伺服器的負載能力,保證用戶的使用體驗。因此需要採用更好的系統架構:
2,應用伺服器和資料庫伺服器分離:
應用伺服器和資料庫伺服器的分離,使得應用能夠獲得整個伺服器的CPU資源來響應用戶請求。應用伺服器和資料庫伺服器的分離,也大大減少了應用的宕機風險。此時我們開始關註伺服器的管理了。
3,應用伺服器集群:
隨著用戶量的繼續增加,一臺應用伺服器可能不能滿足系統的需求,因此我們需要採用應用伺服器的集群架構。
通過將用戶的請求分流到不同的應用伺服器,從而提高整個系統的負載能力,保證用戶的使用體驗。
但是當應用伺服器採用集群結構後,遇到了之前不存在的新問題,比如:
(1):用戶的請求由誰來決定,分發給哪個伺服器來處理(負載均衡問題)。
(2):用戶在使用網站的過程中,如何維護用戶session,保證不同的伺服器響應請求時,能保證用戶Session數據共用。
因此這個應用集群架構中,需要在應用伺服器之上,新增一層進行負載均衡。
負載均衡器,可以分為軟負載和硬負載。
軟負載: Nginx或Apache等。
硬負載:F5等.
Session共用,可通過配置Tomcat的session共用來解決。但是由於Session在伺服器間的複製,占用浪費帶寬比較嚴重,此時建議Tomcat的實例不能過多。
4,資料庫伺服器讀寫分離:
在完成了應用伺服器的集群分佈後,此時的系統瓶頸就卡在資料庫服務這塊了。在對資料庫伺服器進行分散式集群時,很容易碰到多個資料庫實例上的數據不一致的問題,因此一般我們會根據提供的應用服務具體類型,綜合考慮應用提供的讀寫服務頻率等特點。可以考慮先把資料庫服務的讀寫進行分離。
此時,系統遇到的問題是:
(1):主從伺服器上的數據同步。可以使用Mysql自帶的主從複製。
(2):可以根據業務選擇對應的資料庫中間件,屏蔽具體的資料庫訪問細節,如mycat等。
5,使用搜索引擎,緩解資料庫讀庫壓力
根據具體的業務類型,如果設計到很多模糊查詢,而且數據量比較大,此時可以引入搜索引擎,如Elasticsearch。
引入了搜索引擎,則需要額外的工作,如維護索引的構建,數據同步到搜索引擎等。
6,引入緩存機制
隨著用戶請求數量的增加,有一些熱點數據,可能會不斷的被用戶訪問,此時,可以把這些數據放進記憶體中,既避免訪問資料庫,又能加速響應用戶請求。此時可以開始使用緩存技術,比如Redis,Memcache等。
使用緩存機制,能夠緩存讀庫壓力,提升應用性能,與讀庫相比,從緩存中讀取數據,也能夠更快的響應用戶請求。
在有些使用場景中,可能需要使用一些數據,這些數據放在記憶體中不太合適,而放到資料庫中又太麻煩,此時可以考慮使用NoSql產品,來代替傳統的關係型資料庫,保持這些數據。
在分散式系統中,使用NoSql時,也需要考慮緩存是否支持分散式集群。
7,資料庫的水平/垂直拆分
隨著業務量和數據量的持續增加,由於所有的數據都在同一個資料庫中,資料庫表非常多且雜,有些一個表中的數據記錄已經達到了很大的數量。儘管採取了讀寫分離,緩存機制等,但是單個資料庫中的併發連接數有一個上限,因此對資料庫的訪問依然會成為一個瓶頸。
因此需要考慮對資料庫進行拆分。
垂直拆分:把不同的業務數據拆分到不同的資料庫中。
水平拆分:把同一張表中的數據,拆分到不同的資料庫中,水平拆分的原因是某些表中的數據量記錄太大,達到了單個資料庫的瓶頸。
8,應用的拆分
隨著業務越來越多,整個應用越來越複雜,工程規模也越來越大。此時的管理維護工作量會越來越複雜。可以考慮根據領域模型,對系統進行拆分
對應用進行拆分後,可能有一些基本的操作,在每個子系統中,都會使用到,比如訪問用戶數據等,此時可以把這些相同的操作,抽象出來,通過提供服務的方式,提供給各個子系統使用。
因此此時遇到的一些新問題是,多個子系統之間如何進行遠程通信。比如通過RPC技術(dubbo,webservice,hession,heep,RMI等),解決遠程通信問題。
在系統不斷進化時,整個系統也變得越來越複雜,管理難度越來越大,同時也會不斷的出現新的技術,來解決不斷出現的新問題,如微服務,Docker容器技術,容器編排等。
最重要的是,根據應用的實際情況,如用戶量,併發數,數據量等採用最合適的架構。