業界對於可擴展的系統架構設計有一個樸素的理念,就是:算法
經過加機器就能夠解決容量和可用性問題安全
這一理念在「雲計算」概念瘋狂流行的今天,獲得了普遍的承認!對於一個規模迅速增加的系統而言,容量和性能問題固然是首當其衝的。可是隨着時間的向前,系統規模的增加,除了面對性能與容量的問題外,還須要面對功能與模塊數量上的增加帶來的系統複雜性問題以及業務的變化帶來的提供差別化服務問題。而許多系統,在架構設計時並未充分考慮到這些問題,致使系統的重構成爲常態,從而影響業務交付能力,還浪費人力財力!性能優化
對此,《可擴展的藝術》一書提出了一個更加系統的可擴展模型—— AKF可擴展立方 (Scalability Cube)。這個立方體中沿着三個座標軸設置分別爲:X、Y、Z。架構
X軸擴展 —— 關注水平的數據和服務克隆,也就是前文提到的「加機器解決問題」 Y軸擴展 —— 關注應用中職責的劃分,好比數據類型,交易執行類型的劃分 Z軸擴展 —— 關注服務和數據的優先級劃分,如分地域劃分
整個擴展模型,用下圖來表示,其中原點表明徹底無擴展的狀態。負載均衡
一.X軸擴展運維
X軸擴展與咱們前面樸素理念是一致的,經過絕對平等地複製服務與數據,以解決容量和可用性的問題。咱們以生產汽車的工廠來舉例:假設一個車間能完整的生產一輛汽車,爲了短期內生產更多的汽車,咱們能夠建設更多的車間,任何新增車間除了工做的效率可能不一樣以外,都是一個新的複製品,也能提供與原來車間相同的工做,生產出完整的汽車。給複製品分配工做就是一個X軸擴展的一個完美示例,說明了X軸擴展的思路,即把工做無偏向的分配給複製品,每一個複製品在不考慮生產效率的狀況下,誰來作這項工做是無偏向的, 各個複製品之間不共享任何內容 。異步
而在工程技術上來說,X軸擴展主要有如下兩種技術方案:分佈式
1.負載均衡性能
故名思議,負載均衡就是將用戶的訪問請求經過負載均衡器,均衡分配到由各個「複製品」組成的集羣中去。當某個複製品出現故障,也能輕易地將相應「工做」轉移給其它的複製品來「代爲完成」。這中間涉及到的工程技術點包括了反向代理,DNS輪詢,哈希負載均衡算法(一致性哈希),動態節點負載均衡(如按CPU,I/O)等。它的難點在於要求集羣中的「複製品」是不共享任何內容,也就是咱們常說的 無狀態 。優化
2.數據複製
數據複製是指在數據存儲層進行絕對平等地數據遷移,用於解決存儲層I/O瓶頸以及可用性上的問題。因爲存在多個複製品存儲,爲了使得每一個複製品提供無差別的數據服務,咱們須要在複製品之間同步或異步地複製數據。數據複製的方式包括了主從同步(常見的讀/寫分離),雙主同步等。由於數據存儲天生就是有狀態的,數據複製的難點在於 一致性 的保證上,爲了一致性的保證,從而也衍生了不少複雜的技術,好比Paxos選舉算法等。
二.Y軸擴展
Y軸擴展表示的是根據數據的類型或者交易執行的類型(或者二者都有)來劃分工做職責。通常稱爲面向服務或面向資源的擴展。咱們再以生產汽車的工廠來舉例:如亨利.福特所作的同樣,將汽車製造的工序按專業性分紅不一樣車間和流水線,再也不是一個車間負責完成100%的任務,製造一輛完整的汽車,而是讓這每一個車間都執行一些子任務,如安裝發動機,噴漆,安裝玻璃等等。這樣的分工,益處是明顯的,每一個車間負責的 任務更簡單 ,從而能更專業更高效的完成生產。
與汽車工廠的分工相似,爲了下降系統複雜度,Y軸擴展會將龐大的總體應用拆分爲一組服務。每一個服務實現一組相關的功能,如訂單管理、客戶管理等。在工程上常見的方案是 服務化架構(SOA) 。好比對於一個電子商務平臺,咱們能夠拆分紅不一樣的服務,組成下面這樣的架構:
但經過觀察上圖容易發現,當服務數量增多時,服務調用關係變得複雜。爲系統添加一個新功能,要調用的服務數也變得不可控,由此引起了服務管理上的混亂。因此,通常狀況下,須要採用服務註冊的機制造成服務網關來進行服務治理。系統的架構將變成下圖所示:
同時,爲了提高單個服務的可用性和容量, 對每個服務進行X軸擴展劃分 。
三.Z軸擴展
Z軸擴展一般是指基於請求者或用戶獨特的需求,進行系統劃分,並使得劃分出來的子系統是相互隔離但又是完整的。繼續以生產汽車的工廠來舉例:福特公司爲了發展在中國的業務,或者利用中國的廉價勞動力,在中國創建一個完整的子工廠,與美國工廠同樣,負責完整的汽車生產。這就是一種Z軸擴展。
對於系統而言,Z軸擴展通常是爲了知足差別性的需求或者是爲了安全隔離而採起的擴展措施。好比爲了提供VIP用戶服務,能夠將系統完整地複製一份出來,與普通用戶所使用的系統徹底隔離開來;再如,針對不一樣的地域用戶,系統自動切換到對應地域的子系統,爲用戶提供服務,均可以認爲是Z軸擴展。同時,在系統的灰度部署上,咱們也一般使用Z軸擴展來完成。
工程領域常見的Z軸擴展有如下兩種方案:
1.單元化架構
在分佈式服務設計領域,一個單元(Cell)就是知足某個分區全部業務操做的自包含閉環。如上面咱們說到的Y軸擴展的SOA架構,客戶端對服務端節點的選擇通常是隨機的,可是,若是在此加上Z軸擴展,那服務節點的選擇將再也不是隨機的了,而是每一個單元自成一體。以下圖:
2.數據分區
爲了性能數據安全上的考慮,咱們將一個完整的數據集按必定的維度劃分出不一樣的子集。 一個分區(Shard),就是是總體數據集的一個子集。好比用尾號來劃分用戶,那一樣尾號的那部分用戶就能夠認爲是一個分區。數據分區爲通常包括如下幾種數據劃分的方式:
數據類型(如:業務類型) 數據範圍(如:時間段,用戶ID) 數據熱度(如:用戶活躍度,商品熱度) 按讀寫分(如:商品描述,商品庫存)
固然,數據分區也是有代價的,它將增長數據運維的難度,關聯搜索的複雜度增長等。
總結:
一個在可擴展性上設計良好的系統,會充分考慮三個維度上的可擴展性。X軸上擴展處理的是平臺或系統執行的交易量或工做量增加,雖然X軸擴展可以很好處理交易量的增加,但當系統複雜度的大幅度增長,或用戶數量增長以及差別化服務需求出現,X軸擴展就難以應付了,如是咱們能夠經過Y軸擴展來處理系統複雜度增加的問題以及Z軸擴展來處理差別性化需求的問題。而當採用的擴展座標軸不止一條時,那麼 X軸擴展老是其它擴展方法的次級劃分 。同時,這三個維度擴展性,使得系統性能上改善有了更多的方向,對於系統性能優化,也是相當重要。