【轉】分佈式架構概述及設計

 

轉,原文: https://blog.csdn.net/l6108003/article/details/94835586

----------------------------------------

引言
隨着越來越多的人蔘與到互聯網的浪潮來,曾經的單體應用架構越來越無法滿足需求,所以,分佈式集羣架構出現,也因此,分佈式搭建開發成爲了Web開發者必掌握的技能之一。那什麼是分佈式呢?怎麼實現分佈式以及怎麼處理分佈式帶來的問題呢?本系列文章就來源於對分佈式各組件系統的學習總結,包含但不限於Zookeeper、Dubbo、消息隊列(ActiveMQ、Kafka、RabbitMQ)、Nosql(Redis、MongoDB)、Niginx、分庫分表MyCat、Netty等內容。作爲跟大多數人一樣的學習使用者,而非佈道者,個人理解難免會有偏差或是其它錯誤,希望各位讀者不吝指教。

正文
一、什麼是分佈式
簡單的說,“分工協作,專人做專事”就是分佈式的概念。就好比你是你們公司唯一的碼農,那麼前後端都需要你自己來開發(單體架構),但隨着業務的增長,你確實忙不過來了,老闆給你招來了一個前端,那麼你就只需要專注後端開發就行了(分佈式)。但是軟件的分佈式搭建遠遠不像現實例子中這麼簡單,需要考慮和處理很多方面的問題,我們先了解以下幾個常見的概念:

集羣:你們公司業務增長的非常快,老闆發現你一個後端忙不過來了,就又招了幾個後端開發來協助你,這就是後端集羣;再往後,發現前端也忙不過來了,又配備幾個前端,就是前端集羣。所以也不難看出,將應用拆分後,你可以有針對性地擴展單個服務,做成集羣,這就是分佈式的好處之一。
節點:這個也非常好理解,一個服務就是一個節點,比如你就是後端集羣中的一個節點,而集羣本身也可以看成是整個應用的一個集羣節點。
副本:副本就是爲服務和數據提供的冗餘,保證高可用。
中間件:爲開發者提供便利,屏蔽複雜的底層的一類框架組件。如服務管理通信、序列化、負載均衡等組件。

上圖就是一個簡單的分佈式架構,但並不是所有的應用一開始就要設計爲分佈式架構,因爲一開始業務量並不大,沒有必要耗費大量的時間和成本去完成一個分佈式架構,甚至有可能到最後都用不上,因此在設計時我們應該遵循演進原則,由簡入深。下面就來簡單分析一下分佈式架構的演進過程。
二、分佈式架構的演化過程
單機版
以商城爲例,爲了簡單說明,這裏就只列出用戶、訂單、配送服務。

如圖,大部分應用最開始都是將應用和數據庫放到一臺物理機上提供服務,但隨着訪問量的提升,服務器負載越來越高,我們首先會優化代碼、對機器做垂直擴容(內存、容量)等,但單臺機器的性能是存在上限的,且對單機擴容的性價比會隨着性能的提升越來越低,那我們就會想到增加服務器。

將應用服務器和數據庫服務器分離
在一開始,我們可能只會增加一臺服務器,並將應用和數據庫分離:


搭建應用服務器集羣
隨着訪問量的繼續增加,單臺應用服務器也無法滿足需求了,我們就需要搭建應用服務器集羣來對外提供服務了

但是,在搭建應用服務器集羣之後,問題就出現了,用戶在訪問時,應該到哪個服務器上去?如何平均服務器壓力?以及用戶的session如何維護(A首先訪問了1號應用服務器並登陸,但下次請求可能是去到2號服務器,但這臺服務器上並沒有用戶的session信息)?
我們可以在用戶層和應用層之間加上一個負載均衡器來平衡服務器的負載,session可以採取同步的方式,或者增加單獨的session共享服務器。

數據庫讀寫分離
應用層的問題暫時解決了,但是此時數據庫又頂不住了。那該如何做呢?只是簡單的增加數據庫的服務器拉提供存儲和訪問能力麼?那肯定不行,這樣數據就不一致了。所以我們需要將數據庫分爲讀庫和寫庫。查詢請求都到讀庫去,而寫入請求都到寫庫去。

但這樣也存在幾個問題:

數據如何同步以及同步延遲如何處理?
應用層數據源的選擇
大數據查詢搜索,可以引入搜索引擎
避免每次訪問直接到達數據庫,可以引入redis等緩存數據庫緩存熱點數據
問題看似都解決了,但是每個數據庫都存儲的是同樣的數據,隨着業務繼續擴大, 我們就不得不考慮對數據庫做水平或垂直拆分:

水平拆分:將同一個表中的數據拆分至多個數據庫中
垂直拆分:將不同業務的數據放到不同的數據庫中

應用拆分
業務繼續增長,數據庫達到瓶頸時可以繼續增加服務器解決,但是應用層呢?也只是單純的增加服務器麼?基於二八原則,其實大部分訪問量是集中在20%的功能上的,如果我們只是單純的增加服務器,那麼無疑會浪費掉許多的資源,所以我麼會想到能不能針對這20%的應用做擴展呢?當然是可以的,只不過我們需要先將應用拆分爲多個子系統(一般是根據業務):

隨着應用拆分隨之而來的問題是,公用的代碼如何處理?各服務之間如何通信?公用代碼我們不可能放到每個服務中去,而是應該提出來對外提供服務,同時服務之間的調用可以通過RPC或者HTTP方式來實現。

演化至此,這樣的架構就是一個成熟的分佈式架構了,但是,架構還是會隨着業務和技術的提升不停地演化;而此時你有沒有發現這樣的一個架構和馮諾伊曼結構很像呢!輸入輸出設備對應用戶和服務之間的輸入輸出,數據庫服務器就像是存儲設備,而整個應用層就像是一個CPU(控制器、運算器)。所以,分佈式架構可以簡單的理解爲將多臺計算機組成的一臺超級計算機。

三、分佈式架構的設計
在設計分佈式架構時,我們需要了解幾個基本的概念。

主流架構模型-SOA和微服務
CAP和BASE理論
DDD(領域驅動設計)
這些理論限於篇幅原因,這裏就不展開詳述,讀者可自行查閱。下面主要來談談分佈式架構的高可用設計。

分佈式架構的高可用設計
在分佈式架構中,常常面臨的兩個矛盾的問題是一致性和高可用,這兩個是無法同時滿足的,那我們舍誰取誰呢?從用戶的角度分析,我們寧可獲取到舊數據,也不願意等半天都打不開應用,所以常常是保證高可用,讓數據達到最終一致性,那麼如何設計高可用的分佈式架構呢?主要從以下幾個方面:

搭建服務集羣,提高負載,避免單點故障。尤其是特別重要的服務,如訪問量較高的服務和核心服務(一旦掛掉就會導致整個應用不可用的服務)。
應對災難,搭建異地災備,預防地區因發生地震、颱風等自然災害導致地區的集羣服務器都不可用。
接口限流以及服務降級。爲防止過高的併發量造成服務器負載過高而出現故障,應對接口限流,同時,當某個或多個服務出現故障時,應當服務降級,避免拖累整個應用。比如支付時因網絡故障等導致無法支付,但搜索商品和下單仍然可用。
故障監控報警。
服務的可伸縮性,易於水平擴張服務器數量。
使用緩存降低數據庫壓力。
使用CDN等加速靜態資源的訪問。
高可用的分佈式架構需要考慮非常多的方面,針對不同的場景有不同的解決方案,而對於不同的公司而言也不需要一應俱全,需要在實踐中多思考總結,根據自己的業務情況來設計。

總結
本文從理論層面講述了分佈式的基本概念、演化過程,以及設計,從宏觀角度搞清楚分佈式的起源以及分佈式帶來的一系列問題,也就能明白各項技術出現的原因以及應用的場景。
————————————————
版權聲明:本文爲CSDN博主「夜勿語」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/l6108003/article/details/94835586

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章