背景

對於現在的微服務架構的應用來說,對大量併發的及時響應是一項制勝能力。據使用者行為分析平臺統計,隨行付的某一款APP產品每日請求就達到上千萬次使用者請求、加解密服務3000萬次/日等等。這些微服務每時每刻在處理如此高強度的請求,對資料層的應對能力要求極高。如果我們把對速度的需求放在複雜的分散式資料架構背景下,是很難想象如何讓應用應對如此巨大的資料訪問量的。但很幸運,我們有方法做到。即立方體模型

立方體模型

可擴充套件的分散式系統架構設計有一個樸素的理念,就是:通過加機器就可以解決容量和可用性的問題

對於一個迅速增長的應用而言,容量和效能是首當其衝要面臨的問題。但隨著時間的向前推移、應用規模不斷的快速增長,除了面對效能與容量的問題外,還需要解決功能與模組數量上增長帶來的系統複雜性問題、業務變化帶來的差異化服務問題等。而多數情況下應用設計之初出於諸多因素的考量,並沒有充分考慮或在設計之初就將此類問題提上日程,導致系統的重構成為常態,從而影響業務交付能力。對此,「架構即未來」一書中提出了更加系統的可擴充套件模型,可擴充套件模型是一個富有啟發性的方法,描述了微服務三個維度的擴充套件方法,可以通過它來了解微服務架構的擴充套件維度。

  • X軸:橫向擴充套件模式,關注水平的資料和服務克隆
  • Y軸:功能分解模式,關注應用中的職責的劃分
  • Z軸:資料分割槽模式,關注服務和資料的優先順序劃分

X軸擴充套件

X軸擴充套件是通過絕對平等的複製服務和資料,以解決容量和可用性的問題。以乘坐火車為例,因春運高峰集中,乘客人數也是平時時的幾倍、甚至幾十倍。12306為了提高運力都會採用複製的方法:增加火車數量。增加火車數量有效的提高春運運力、提高乘客出行體驗。

對於軟體工程而言,比如加解密微服務的效能峰值1000TPS,通常我們需要提高TPS,會採取複製加解密服務:增加服務提供者。這就是X軸擴充套件的一個完美示例,說明了X軸擴充套件的思路,把工作無偏向的分配給「複製品」,各個「複製品」之間不共享任何內容、能獨立提供服務。而對於軟體技術來講,X軸擴充套件主要有負載均衡資料複製兩種技術方式。

負載均衡

負載均衡是將使用者的訪問請求通過負載均衡器,均衡分配到由各個「複製品」組成的叢集中去。當某個「複製品」出現故障,也能輕易地將相應「工作」轉移給其它的複製品來「代為完成」。常用的硬體負載有F5、A10,軟體負載Nginx。

這中間涉及到的技術點包括了反向代理、DNS輪詢、雜湊負載均衡演算法(一致性雜湊)、動態節點負載均衡(如按CPU,I/O)等。它的難點在於要求叢集中的「複製品」是不共享任何內容,也就是我們常說的無狀態

資料複製

資料複製是指在資料儲存層進行絕對平等地資料遷移,用於解決儲存層I/O瓶頸以及可用性上的問題。有多個「複製品」儲存,使得每個「複製品」提供無差異的資料服務,我們需要在「複製品」之間同步或非同步的複製資料。

資料複製的方式包括了主從同步(讀寫分離)、雙主同步等。因為資料儲存天生就是有狀態的,資料複製的難點在於如何保證一致性。為保證一致性,衍生了很多複雜的技術和中介軟體,比如Paxos選舉演算法、隨行付Porter資料同步中介軟體等。

識別熱點服務

多數情況下我們的應用中都會存在熱點模組,我們可以理解為越基礎的模組越容易成為熱點模組。熱點模組更加容易成為整個平臺的瓶頸點,所以熱點模組要儘早的採取擴充套件措施,擴充套件措施一般都採用X軸擴充套件方式。

前後端分離

其實在我們開發過程中,經常會給pc端、mobile、app端各自研發一套前端。其實對於這三端來說,大部分端業務邏輯是一樣的。唯一區別就是互動展現邏輯不同。如果controller層在後端手裡,後端為了這些不同端頁面展示邏輯,分別維護這些controller,徒增和前端溝通端成本、在擴充套件性上面也不能達到很方便的擴充套件。前後端分離的好處在於:

  • 提升適配性
  • 提升響應速度
  • 提升效能(分後端可分別優化)

Y軸擴充套件

Y軸擴充套件是根據資料的型別或者交易執行的型別(或者兩者都有)來劃分工作職責。一般稱為面向服務或面向資源的擴充套件。

我們再以火車來舉例,12306根據起點和終點的不同,劃分了多條火車線路。每條火車線路的週期歸屬運輸,交付著乘客的出行服務。這樣做的好處是明顯的,每條火車線路的任務更簡單,從而能更高效的提供出行服務。

與火車分工類似,為了降低系統複雜度,Y軸擴充套件會將龐大的整體應用拆分為一組服務。每個服務實現一組相關的功能,如核心交易、風險控制等。而在軟體上常見的方案是服務化架構(SOA)、微服務化架構(Micro Service)。

Z軸擴充套件

Z軸擴充套件是指基於請求者或使用者獨特的需求,進行系統劃分,並使得劃分出來的子系統是相互隔離但又是完整的。繼續以火車舉例,12306為了更好發展業務,交付出行體驗。在中國建立N多個鐵路局,各個鐵路局個行其責,分別提供出行服務。這就是一種Z軸擴充套件。

對於軟體而言,Z軸擴充套件一般是為了滿足差異性的需求、安全隔離而採取的擴充套件措施。比如,為了提供VIP使用者服務,可以將系統完整地複製一份出來,與普通使用者所使用的系統完全隔離;針對不同的地域使用者,系統自動切換到對應地域的子系統,為使用者提供服務,都是Z軸擴充套件。另外,在系統的灰度部署上,我們也通常使用Z軸擴充套件來完成。

軟體領域常見的Z軸擴充套件有以下兩種方案:分離化部署和資料分割槽

分離化部署

在分散式服務設計領域,一個煙筒狀就是滿足某個分割槽所有業務操作的自包含閉環。如上面我們說到的Y軸擴充套件的微服務架構,客戶端對服務端節點的選擇一般是隨機的,但是,如果在此加上Z軸擴充套件,那服務節點的選擇將不再是隨機的了,而是每個煙筒狀自成一體。

資料分割槽

為了效能及資料安全考慮,我們將一個完整的資料集按一定的維度劃分出不同的子集。 一個分割槽(Sharding),就是是整體資料集的一個子集。比如用尾號來劃分使用者,那同樣尾號的那部分使用者就可以認為是一個分割槽。資料分割槽為一般包括以下幾種資料劃分的方式:

  • 資料型別(如,業務型別)
  • 資料範圍(如,時間段、使用者)
  • 資料熱度(如,使用者活躍度)
  • 按讀寫分(如,描述,庫存)

當然,資料分割槽也是有代價的,它將增加資料運維的難度,關聯搜尋的複雜度增加等。

總結

X軸上擴充套件是平臺或系統的交易量或工作量增長,雖然X軸擴充套件能夠很好處理交易量的增長,但當系統複雜度的大幅度增加,或使用者數量增加以及差異化服務需求出現,X軸擴充套件就難以應付了。但我們可以通過Y軸擴充套件來處理系統複雜度增長、Z軸擴充套件來處理差異性化需求。XYZ三個軸可以根據實際情況酌情使用其中一個、兩個或三個,三個軸既可以無限向下擴充套件也可以無限向上擴充套件。我們在設計系統架構時可將擴充套件立方體模型作為理論指導,設計完之後回過頭來驗證是否可以做相應的擴充套件。

一個擴充套件性良好的系統,會充分考慮三個維度上的可擴充套件性,熟練運用三個維度的擴充套件性,使得系統性能改善上有更多的方向,但在系統性能優化上,程式碼層面、框架層面、設計層面也是更加的至關重要。

作者簡介

馬鐵利,TGO鯤鵬會北京分會會員,10年全棧工程師,擅長微服務分散式架構設計。主要負責架構部日常管理,參與構建微服務平臺周邊基礎設施及中介軟體。負責隨行付對外開源等事宜。