從零開始學架構V2-架構設計基礎知識-3

說明

在瞭解完軟件架構的基本設計原則、涉及流程,還需要補充一下架構設計中一些常見的基礎知識,分爲基礎的技術知識、常見的軟件架構都有哪些,本章節介紹的是基礎知識。

一、數據庫

單機的性能總是有限的,當業務發展到一定規模後,單機性能瓶頸問題就會日益凸顯;當單機出現性能瓶頸時,常見應對方案就是更換配置更高的機器、增加機器、優化性能三種方式;

增加機器:我們常說的橫向擴展。數據庫與應用服務不同,應用服務一般不存儲數據,僅做邏輯計算,複雜點在於服務註冊、發現、負載均衡,解決這些之後只需要增加機器部署服務就可以了。數據庫的橫向擴展則需要對整體數據做拆分,然後將數據分散到多個機器上;當業務再次增長,原來多臺機器性能不足以支持時,可能還需要對數據再次拆分。

優化性能:當單臺機器的性能不夠時,將一部分工作交給其他機器來處理;與增加不同,該方式是複用已有集羣的能力,常見的實現就是讀寫分離。

接下來我們一起看看數據庫的讀寫分離。

1.1 讀寫分離

定義: 讀寫分離,顧名思義將數據庫的讀、寫操作分開,交給不同的機器來處理,處理結果與單臺機器相同,那該如何實現呢?

當多臺機器存儲的數據完全相同,用戶的請求直接交由任意一臺機器處理都與原單機處理結果一致了;想要多臺機器數據完全一致常見的方式就是一個寫請求等所有機器都修改完畢再返回,這種方案性能未免有點差;簡單優化一下:一臺機器寫操作完成就認爲成功,由該機器異步同步其他到其他機器

此種方式也會引出新的問題:同步延遲,此問題下文會再次介紹;爲了減少剛剛寫機器的壓力,一般會把讀請求交給非寫操作的機器。整理一下:我們將處理寫操作的機器叫做主服務器,處理讀操作的機器叫做從服務器,於是就可以得到下圖:

在此架構中,數據庫主機通過複製將數據同步到從機,每臺數據庫服務器都存儲了所有的業務數據;主從架構使用一主一從、一主多從都是可以的,從機越多集羣的讀性能就越高,當然從機越多主機壓力也會越大,數據延遲也會越明顯;當主機掛掉後,可以在從機中選擇一臺機器頂替實現高可用。

任何架構都不會是十分完美的,讀寫分離亦是如此,主機同步從機是一個異步過程,存在一定的時間差,這樣就會導致“主從延遲”問題,常見的解決方案是一致性要求較高的業務,讀寫請求都走主機,否則讀請求還是走從機。

引入該架構還會帶來複雜度問題:如何識別是讀、寫請求?如何將讀請求轉發給從機?主從故障節點發生變化後如何保障讀寫請求還是分配給主、從機器?公司有X個應用,如何降低改造成本?

數據庫的操作都是通過SQL進行,只需要解析SQL很容易知道該操作是讀還是寫;

對於請求的轉發,常見的實現有兩種:

圖一增加數據庫代理,包裝已有有的數據庫集羣,對外提供數據庫的鏈接、請求處理、讀寫分離、分庫分表、故障處理等。優點是改造成本較小,方便維護升級;缺點是所有請求都需要走代理,很容易成爲系統瓶頸,本身也需要做高可用保障。

圖二增加統一數據解析層,原系統應用訪問數據庫都需要經過該層,該層做SQL解析,對於讀寫分離架構、分庫分表架構等,根據策略請請求發送到具體的機器上。優點是額外的機器成本較少,SQL解析、選庫選表都在系統應用服務器上完成。缺點:改造成本大。所有應用都需要改造;功能迭代時,需要所有應用都一起升級。

對比主備架構

主從架構中“從機”的“從”可以理解爲“僕從”,僕從是要幫主人幹活的,“從機”是需要提供讀數據的功能的;而主備架構中“備機”一般被認爲僅僅提供備份功能,不提供訪問功能。所以使用“主從”還是“主備”,是要看場景的,這兩個詞並不是完全等同的。

1.2 分庫分表

“單機優化”介紹完畢後再開看看橫向擴展:分庫分表。

背景: 單個數據庫服務器存儲的數據量不能太大,需要控制在一定的範圍內。爲了滿足業務數據存儲的需求,就需要將存儲分散到多臺數據庫服務器上。

1.2.1 分庫

介紹: 分庫指的是按照業務模塊將數據分散到不同的數據庫服務器

日常在電商平臺購買商品時,大多都會進行搜索、瀏覽商品、下單、物流派送流程,其中涉及了商品、訂單、履歷等系統,按照業務模塊可拆分成商品數據庫、訂單數據庫、履約數據庫等,不同的數據庫分散到不同的數據庫服務器上。

當數據庫分散到不同服務上後,可能會對已有邏輯產生影響:如跨庫的統計SQL;

1.2.2 分表

介紹: 分表是按照業務需求將大表拆分成多個小表,減少每次SQL檢索數據塊的大小、多少,從而提高整體性能。

垂直拆分: 按照業務需求將使用頻率較低的字段拆分多個單獨的表。

主要應用於寬表中,將一些不常用字段單獨拆分出去。

橫向拆分: 按照一定的算法將數據量特別大的表拆分成多個小表。

常見拆分方式:

  1. 範圍拆分:選取有序的數據列(整型、時間戳等)作爲路由的條件,不同分段分散到不同的數據庫表中。以最常見的用戶ID爲例,路由算法可以按照100w的範圍大小進行分段,(1,100w]放到表1中,(100w,200w]放到數據庫2的表中,以此類推。
  2. Hash拆分:選取某個列(或者某幾個列組合也可以)的值進行Hash運算,然後根據Hash結果分散到不同的數據庫表中。同樣以用戶ID爲例,假如我們一開始就規劃了10個數據庫表,路由算法可以簡單地用user_id % 10的值來表示數據所屬的數據庫表編號,ID爲985的用戶放到編號爲5的子表中,ID爲10086的用戶放到編號爲6的字表中。
  3. 配置拆分:配置路由就是路由表,用一張獨立的表來記錄路由信息。同樣以用戶ID爲例,我們新增一張user_router表,這個表包含user_id和table_id兩列,根據user_id就可以查詢對應的table_id。

當時數據拆分到多個表後,可能會對已有的邏輯產生問題:

  1. 使用聚合函數(count、sum、avg)等會導致數據統計不正確;
  2. 如果有排序,也會導致排序錯誤。
  3. 無法使用join

垂直拆分、橫向拆分圖例:

1.3 其他存儲

K-V存儲: 解決關係數據庫無法存儲數據結構的問題,以Redis爲代表。 文檔數據庫: 解決關係數據庫強schema約束的問題,以MongoDB爲代表。 列式數據庫: 解決關係數據庫大數據場景下的I/O問題,以HBase爲代表。 全文搜索引擎: 解決關係數據庫的全文搜索性能問題,以Elasticsearch爲代表。

二、負載均衡

定義: 負載均衡,英文名稱爲Load Balance,其含義就是指將負載(工作任務或者網絡請求)分攤到多個操作單元(服務器或者組件)上進行運行。目的是儘量將網絡流量 平均 發送到多個服務器上,以保證整個業務系統的高可用。 作用:

  1. 高併發。通過採取一定的算法策略,將流量儘可能的均勻發送給後端的實例,以此提高集羣的併發處理能力。
  2. 伸縮性。根據網絡流量的大小,增加或者減少後端服務器實例,由負載均衡設備進行控制,這樣使得集羣具有伸縮性。
  3. 高可用。負載均衡器通過算法或者其他性能數據來監控候選實例,當實例負載過高或者異常時,減少其流量請求或者直接跳過該實例,將請求發送個其他可用實例,這使得集羣具有高可用的特性。
  4. 安全防護。有些負載均衡器提供了安全防護功能。如:黑白名單處理、防火牆等。

2.1 分類

按照負載均衡的載體來分類可分爲硬件、軟件負載均衡。對軟件負載細分,按照OSI網絡分層模型來劃分可以分爲二層、三層、四層、七層負載均衡等。

2.1.1 硬件負載均衡

定義:通過單獨的硬件設備來實現負載均衡功能。

優點:

  1. 功能強大:支持全局負載均衡並提供較全面的、複雜的負載均衡算法。
  2. 性能強悍:硬件負載均衡由於是在專用處理器上運行,因此吞吐量大,可支持單機百萬以上的併發。
  3. 安全性高:往往具備防火牆,防 DDos 攻擊等安全功能。

缺點:

  1. 貴。市面上常見的硬件負載均衡服務器有F5、A10,F5價格在15w~55w不等,A10價格在55w-100w不等,因此在大公司纔會負擔的起。
  2. 擴展性差:當訪問量突增時,超過限度不能動態擴容。

2.1.2 軟件負載均衡

軟件負載均衡指的是在服務器的操作系統上安裝負載均衡軟件,從此服務器發出的請求經軟件負載均衡算法路由到後端集羣的某一臺機器上。

常見負載均衡軟件有:LVS、Nginx、Haproxy。

優點

  1. 擴展性好:適應動態變化,可以通過添加軟件負載均衡實例,動態擴展到超出初始容量的能力。
  2. 成本低廉:軟件負載均衡可以在任何標準物理設備上運行,降低了購買和運維的成本。 缺點
  3. 性能略差:相比於硬件負載均衡,軟件負載均衡的性能要略低一些。

2.1.3 網絡分層負載均衡

基於OSI網絡分層模型,根據每層的特點進行負載均衡。

二層:數據鏈路層,該層在數據傳輸時根據MAC地址定位到唯一的設備,因此該層負載均衡的原理就是通過在通信協議的數據鏈路層修改mac地址。具體流程是讓負載均衡服務器和業務服務器綁定同一個虛擬IP(即VIP),客戶端直接通過這個VIP進行請求集羣。集羣中不同的機器採用相同IP地址,但是機器的MAC地址不一樣。當負載均衡服務器接受到請求之後,通過改寫報文的目標MAC地址的方式將請求轉發到目標機器實現負載均衡。

三層:網絡層,該層在數據傳輸時根據IP地址定位到唯一的機器,在該層中負載均衡服務器依舊對外提供一個VIP(虛IP),但是集羣中不同的機器採用不同的IP地址。當負載均衡服務器接受到請求之後,根據不同的負載均衡算法,通過IP將請求轉發至不同的真實服務器。

四層:傳輸層,該層通過IP+端口定位到唯一應用,通過修改數據報文中的IP,將請求轉發給被負載均衡的服務器。主要是基於tcp協議報文,可以做任何基於tcp/ip協議的軟件的負載均衡,比如Haproxy、LVS等。

七層:應用層,七層負載均衡基本都是基於http協議的,適用於web服務器的負載均衡,比如Nginx等。

2.1.4 DNS負載均衡

DNS,域名系統,處於第七層的最簡單也是最常見的負載均衡方式,一般用來實現地理級別的均衡。例如北京、天津都訪問北京的機房;上海、蘇州都訪問上海機房; 優點

  1. 簡單、成本低:負載均衡工作交給DNS服務器處理,無須自己開發或者維護負載均衡設備。
  2. 就近訪問,提升訪問速度:DNS解析時可以根據請求來源IP,解析成距離用戶最近的服務器地址,可以加快訪問速度,改善性能。

缺點

  1. 更新不及時:DNS緩存的時間比較長,修改DNS配置後,由於緩存的原因,還是有很多用戶會繼續訪問修改前的IP,這樣的訪問會失敗,達不到負載均衡的目的,並且也影響用戶正常使用業務。
  2. 擴展性差:DNS負載均衡的控制權在域名商那裏,無法根據業務特點針對其做更多的定製化功能和擴展特性。
  3. 分配策略比較簡單:DNS負載均衡支持的算法少;不能區分服務器的差異(不能根據系統與服務的狀態來判斷負載);也無法感知後端服務器的狀態。

2.2 典型架構

瞭解完一些常見的負載均衡架構後,接下來看下負載均衡的典型實際應用。 當用戶訪問某個網站時,通過域名請求後端服務,經過DNS解析返回距離當前位置最近的服務器IP地址;

當用戶訪問服務器IP地址時,該請求會經過硬件負載均衡集羣,由該集羣將請求轉發到四層負載均衡的LVS集羣上;

LVS接收到請求後在根據已有的配置將請求轉發到具體的七層負載均衡NGINX集羣上;

最後由NGINX集羣將請求轉發到具體得應用集羣,應用集羣處理完畢後響應該客戶端。

2.3 常用算法

負載均衡的算法有很多,如果按照算法被負載均衡機器的實時情況是否影響負載均衡來劃分可以劃分爲靜態負載均衡算法和動態負載均衡算法;

常見的靜態均衡算法:輪詢法、隨機法、源地址哈希法、一致性哈希法、加權輪詢法、加權隨機法。

常見的動態負載均衡算法:最少連接數法、最快響應速度法。

  1. 輪詢法 每一次來自網絡的請求輪流分配給內部中的服務器,從1至N然後重新開始。此種均衡算法適合於服務器組中的所有服務器都有相同的軟硬件配置並且平均服務請求相對均衡的情況。
  2. 隨機法 將請求隨機分配到各個節點。
  3. 源地址哈希法 根據請求源 IP,通過哈希計算得到一個數值,用該數值在候選服務器列表的進行取模運算,得到的結果便是選中的服務器。
  4. 一致性哈希法 一些場景希望同樣的請求儘量落到一臺機器上,比如訪問緩存集羣時,我們往往希望同一種請求能落到同一個後端上,以充分利用其上已有的緩存,不同的機器承載不同的穩定請求量(也可以理解爲固定批用戶的請求)。而不是隨機地散落到所有機器上,那樣的話會迫使所有機器緩存所有的內容,最終由於存不下形成顛簸而表現糟糕。 我們都知道hash能滿足這個要求,比如當有n臺服務器時,輸入x總是會發送到第hash(x) % n臺服務器上。但當服務器變爲m臺時,hash(x) % n和hash(x) % m很可能都不相等,這會使得幾乎所有請求的發送目的地都發生變化,如果目的地是緩存服務,所有緩存將失效,繼而對原本被緩存遮擋的數據庫或計算服務造成請求風暴,觸發雪崩。一致性哈希是一種特殊的哈希算法,在增加服務器時,發向每個老節點的請求中只會有一部分轉向新節點,從而實現平滑的遷移。
  5. 加權輪詢法 當集羣內機器的配置不一致時,對於高帶寬機器可以適當增加一些權重,增大被輪詢的次數,從而分攤更多的流行,充分利用系統資源。
  6. 加權隨機法 與加權輪詢法本質一樣,都是爲了充分利用系統資源。
  7. 最少連接數法 將請求分發到連接數/請求數最少的候選服務器,已達到負載均衡的目的。客戶端的每一次請求服務在服務器停留的時間可能會有較大的差異,隨着工作時間加長,如果採用簡單的輪循或隨機均衡算法,每一臺服務器上的連接進程可能會產生極大的不同,並沒有達到真正的負載均衡。最少連接數均衡算法對內部中需負載的每一臺服務器都有一個數據記錄,記錄當前該服務器正在處理的連接數量,當有新的服務連接請求時,將把當前請求分配給連接數最少的服務器,使均衡更加符合實際情況,負載更加均衡。此種均衡算法適合長時處理的請求服務,如FTP。
  8. 最快響應速度法根據請求的響應時間,來動態調整每個節點的權重,將響應速度快的服務節點分配更多的請求,響應速度慢的服務節點分配更少的請求。負載均衡設備對內部各服務器發出一個探測請求(例如Ping),然後根據內部中各服務器對探測請求的最快響應時間來決定哪一臺服務器來響應客戶端的服務請求。此種均衡算法能較好的反映服務器的當前運行狀態,但這最快響應時間僅僅指的是負載均衡設備與服務器間的最快響應時間,而不是客戶端與服務器間的最快響應時間。

三、單服務網絡通信模型

單服務網絡通信模型,是指描述單個應用在接受網絡請求、處理、響應整個過程核心步驟的模型。

3.1 PPC

在計算機發展初期,用戶羣體沒有那麼大,當用戶發送一個請求後,服務器就會新建一個進程去專門處理該請求,這是傳統的UNIX網絡服務器所採用的模型,請求與進程之間的關係是一對一,也就是Process Per Connection,縮寫爲PPC。

通信模型:

當應用起來後進行網絡通訊的標準流程:創建socket,綁定端口號、監聽網絡請求、接受網絡請求、處理用戶請求、關閉通訊;

在PPC中處理用戶請求這一步,當一個請求過來之後會fork一個子進程,由子進程對讀取請求入參等信息,按照業務需求處理完畢後再將結果響應給客戶端,最後關閉連接釋放資源。

整體流程非常簡單,也很好理解,使用起來也比較方便,但性能不高;創建進程操作系統需要申請大量CPU、IO等資源,此過程十分耗時,且系統的資源是一定的,這也註定該模型僅使用與小型應用。

改進 當用戶請求過來後採取創建進程,而創建進程有十分耗時,性能不高;對該問題常見的優化思路就是使用”池化技術“,提前創建好進程池,當用戶請求過來後,從進程池中獲取一個進程處理用戶請求,處理完畢後再歸還進程到進程池中。

雖然一定程度上可以提高優化性能,進程比較消耗系統資源,龐大的進程僅處理一個請求,顯然有點浪費資源;既然創建進程需要消耗大量系統資源,將進程替換成更輕量級的線程呢?似乎也可以跑的通,於是就衍生了新的通信模型:TPC

3.2 TPC

TPC(Thread Per Connection),每次有新的連接就新建一個線程去專門處理這個連接的請求。

通信模型:

運行流程、優點與PPC類似不在重複敘述。

缺點:

  1. TPC是PPC的另一種優化思路,線程雖然資源較少但不意味着不消耗資源,當千級別用戶請求過來機器就無法響應了。
  2. 線程的引入勢必引入線程常見的問題,如死鎖,線程安全等。

改進

與PPC改進方式類似,也會引入”池化技術“優化頻繁創建線程導致的性能問題。

都是一個請求對應一個處理模型,網絡模型決定了上限,如果換一種方式:讓多個請求由一個線程呢?接下來我們看下Reactor模型

3.3 Reactor

Reactor 是一個基於多路複用、由事件驅動的IO模型。多個用戶請求事件由統一內容分發器接收,然後根據事件類型轉發給對應的事件處理器,如下圖所示:

關鍵詞說明:

service handler: 通過封裝selector(多路複用)接收用戶的的請求,根據請求事件類型將請求轉發給不同事件處理器。

request handler 事件處理器,用於處理用戶的請求事件,完成用戶的具體操作。

以上只是Reactor的模型,在實際實現上常見有三種方式:單線程reactor、多線程Reactor、主從Reactor;

3.3.1 單線程reactor

執行流程:

  1. 用戶請求過來後,reactor通過select接收用戶IO事件,收到事件後通過dispatch進行轉發。
  2. 如果事件是建立連接事件,調用acceptor建立網絡連接,然後創建handler對象實例執行後續流程。
  3. 如果事件是不建立連接事件,將請求轉發到網絡連接對應的handler進行處理。
  4. handler處理請求的過程是read(讀取網絡數據) -> 業務處理 -> send(將處理結果響應給客戶端)

注:圖中的hander1、hander2表示handler實例對象,而不是不同的handler,這裏只是想表達handler有很多個實例。

優點:相對簡單;缺點則是無法充分發揮多核CPU優勢;當一個業務處理阻塞則直接影響整個服務。

3.3.2 多線程reactor

執行流程:

  1. 用戶請求過來後,reactor通過select接收用戶IO事件,收到事件後通過dispatch進行轉發。
  2. 如果事件是建立連接事件,調用acceptor建立網絡連接,然後創建handler對象實例執行後續流程。
  3. 如果事件是不建立連接事件,將請求轉發到網絡連接對應的handler進行處理。
  4. handler處理請求的過程是read(讀取網絡數據) -> 業務處理 -> send(將處理結果響應給客戶端)。其中在業務處理這一步會直接將請求交給業務線程池。

說明: 與單線程Reactor相比,將業務處理部分通過多線程的方式進行處理,可以充分發揮多核CPU的性能,也一定程度上緩解了一個業務流程執行慢從而影響整個服務的問題。

多線程reactor只是將業務處理部分使用多線程進行優化,當用戶請求比較多時,一個線程需要與用戶建立網絡連接、讀取用戶請求、響應結果,尤其讀取、響應屬於高IO操作的,IO本身十分消耗性能,使得這裏容易成爲系統瓶頸,爲此還需要再次優化。

3.3.3 主從線程reactor

相對於多線程Reactor,將原Reactor功能拆分成主從兩個Reactor,其中主Reactor僅負責網絡連接、身份認證、IP黑白名單過濾等;讀取網絡請求、響應處理結果這種高IO交給從reactor池處理,一般來說從Reactor數量與CPU核心數量保持一致,不同業務可能有所不同。 執行流程:

  1. 用戶請求過來後,主reactor通過select接收用戶IO事件,收到事件後通過dispatch進行轉發。
  2. 如果事件是建立連接事件,調用acceptor建立網絡連接,然後將建立好的網絡連接交給從Reactor,然後從Reactor創建handler對象實例執行後續流程。
  3. 如果事件是不建立連接事件,將請求轉發給子Reactor。
  4. 子reactor通過selector監聽到用戶的請求事件後,將請求轉發到網絡連接對應的handler進行處理。
  5. handler處理請求的過程是read(讀取網絡數據) -> 業務處理 -> send(將處理結果響應給客戶端)。其中在業務處理這一步會直接將請求交給業務線程池。

3.3.4 總結

Reactor是一個多路複用的簡單、高性能、擴展性好的同步非阻塞IO模型,主要體現在:

  1. 同步非阻塞:讀取IO、響應是同步的,建立網絡連接、處理業務請求是非阻塞的。
  2. 簡單:模型整體簡單易理解,實現上也不復雜,無需過多處理多線程及同步問題。
  3. 高性能:單機可以支持很高的用戶請求。
  4. 高擴展性:可以方便地通過增加Reactor實例個數來充分利用CPU資源;事件處理與Reactor模型分開,事件的變化不會影響Reactor本身,新增、修改事件只需增加類型和處理類即可,很容易擴展;

3.4 Proactor

Proactor 異步、非阻塞的IO模型,理論上Proactor比Reactor效率要高一些,但目前業界並沒有成熟的實現,導致知名度較低。

Reactor可以理解爲“來了事件我通知你,你來處理”,而Proactor可以理解爲“來了事件我來處理,處理完了我通知你”。這裏的“我”就是操作系統內核,“事件”就是有新連接、有數據可讀、有數據可寫的這些I/O事件,“你”就是我們的程序代碼。

執行流程:

  1. Proactor Initiator負責創建Proactor和Handler,並將Proactor和Handler都通過Asynchronous Operation Processor註冊到內核。
  2. Asynchronous Operation Processor負責處理註冊請求,並完成I/O操作。
  3. Asynchronous Operation Processor完成I/O操作後通知Proactor。
  4. Proactor根據不同的事件類型回調不同的Handler進行業務處理。
  5. Handler完成業務處理,Handler也可以註冊新的Handler到內核進程。

四、架構設計業界著名理論

4.1 CAP理論

理論內容: 在一個分佈式系統(指互相連接並共享數據的節點的集合)中,只能保證一致性(Consistence)、可用性(Availability)、分區容錯性(Partition Tolerance)三者中的兩個,另外一個必須被犧牲,這裏的犧牲並不是指完全放棄,只是無法做到100%而已!

一致性(Consistency): 對於上游客戶端來說,每次查詢的數據都可以返回最新操作的寫結果。

可用性(Availability):正常節點在合理的時間內均可以返回正確的結果,正確的結果不包含熔斷、超時等異常響應。

分區容忍性(Partition Tolerance):分佈式系統出現網絡分區的時候,仍然能夠對外提供服務。這裏的網路分區是指分佈式系統中,多個節點之前的網絡本來是連通的,但是因爲某些故障(比如部分節點網絡出了問題)某些節點之間不連通了,整個網絡就分成了幾塊區域,這就叫網絡分區。

應用

在實際的分佈式應用中,網絡不可能做到100%可靠,因此P是必須保留的,也就是我們只能在AP、CP中作選擇。我們常用的Zookeeper 是CP架構,Eureka是AP架構。

關鍵細節點

  1. CAP關注的粒度是數據,而不是整個系統;一個系統包含的模塊、數據有很多,不同的模塊、數據對CAP的要求是不一樣的,例如下單時計算訂單金額要求CP,訂單列表則要求AP;
  2. CAP是忽略網絡延遲的;在分佈式系統中,無論採用什麼架構,數據的同步都一定存在,那怕是幾毫秒。對於一些場景幾毫米延遲都是無法容忍的,因此一些場景可能會採取CA架構,例如熱門商品的庫存。
  3. 正常運行情況下,不存在CP和AP的選擇,可以同時滿足CA。
  4. CAP理論中的放棄並不等於什麼都不做,只是無法做到100%,仍需要爲被放棄的一項做努力。

4.2 BASE理論

BASE是指基本可用BA(Basically Available)、軟狀態S( Soft State)、最終一致性E( Eventual Consistency)的簡寫,本質上是對CAP的延伸和補充,是對CAP中的AP方案的一個補充,即在選擇AP方案的情況下,如何更好地最終達到C。

基本可用(Basically Available):分佈式系統在出現故障時,允許損失部分可用性,保證核心可用。例如當服務器壓力過大,對部分非核心功能進行降級。

軟狀態(Soft State):允許系統存在中間狀態,而該中間狀態不會影響系統整體可用性。這裏的中間狀態就是CAP理論中的數據不一致。例如允許分區之間有同步延遲。

最終一致性(Eventual Consistency):系統中的所有數據副本經過一定時間後,最終能夠達到一致的狀態。

五、FMEA方法

失效模式與影響分析(英文:Failure mode and effects analysis,FMEA),又稱爲失效模式與後果分析、失效模式與效應分析、故障模式與後果分析或故障模式與效應分析等,是一種操作規程,旨在對系統範圍內潛在的失效模式加以分析,以便按照嚴重程度加以分類,或者確定失效對於該系統的影響。--來自維基百科

作用: 計算出故障嚴重程度值,以嚴重程度優先級別最高的失效着手,採取行動措施,從而消除或減少故障;

內容: 按照分析表列出有哪些功能點、這些功能點可能發生的故障有哪些、故障的影響範圍、發生概率等,根據驗證程度思考應對方案,從而優化我們的架構。

具體分析項:

  1. 功能點: 站在用戶角度分析有哪些功能點。
  2. 故障: 指的是系統會出現什麼樣的故障,包括故障點和故障形式,例如搜索速度很慢,三四秒才返回搜索結果。一個故障可能原因很多,可以按照故障*原因窮舉所有結果。注意故障的描述要儘量精確,多使用量化描述(不需要準確,粗估即可),避免使用泛化的描述。例如,推薦使用“MySQL響應時間達到3秒”,而不是“MySQL響應慢”。
  3. 故障影響: 當發生故障時對用戶的影響是什麼,例如功能完全不可用,部分用戶可用,少量用戶不可用;注意影響範圍儘量也描述使用量化描述(不需要準確,粗估即可),例如,50%用戶不可用
  4. 嚴重程度: 嚴重程度指站在業務的角度故障的影響程度,一般分爲“致命/高/中/低/無”五個檔次。嚴重程度按照這個公式進行評估:嚴重程度 = 功能點重要程度 × 故障影響範圍 × 功能點受損程度。當出現敲不定嚴重程度時,讓leader拍板就行,不要在此浪費過多時間。
  5. 故障原因: 在”故障“描述了故障時怎麼樣的,但原因不同,例如搜索很慢可能是帶寬被佔滿,也可能是性能問題,不同原因解決方案不同。
  6. 故障概率: 基於”故障原因“定出該原因出現概率,分爲高中低就行。
  7. 風險程度: 將故障的嚴重程度和發生概率相結合,計算出風險程度,爲後續應對做準備;風險程度=嚴重程度*發生概率
  8. 已有措施: 基於風險程度、原因系統是否已經作出了相應的處理措施。
  9. 規避措施: 減少或消除該風險要做的事情,不限於技術。例如爲了提高數據庫可用型,購買雲廠商的服務。
  10. 解決措施: 風險的應對方案,一般都是技術要做的事情;爲了提供可用性,將單機換成主從架構。
  11. 後續規劃: 風險過多無法一次完成,可以分階段完成;風險解決方案需要消耗很長時間,一次性解決成本過大,分期迭代來完成。

案例 假設某電商平臺需要實現一個下單和列表查詢功能;當下單後需要扣除庫存,爲了放到數據庫被大流量打垮,將庫存放到緩存中,異步寫入數據庫中;列表查詢直接查詢數據庫即可。

功能點 故障 故障影響 嚴重程度 故障原因 故障概率 風險程度 已有措施 規避措施 解決措施 後續規劃
下單 服務器無法訪問 全部用戶 致命 設備故障 定期巡檢設備,臨期設備及時更換 採用集羣,一臺故障還有其他集羣頂替
下單 MYSQL響應超過3秒 10%的用戶 寬帶被佔滿 增加寬帶使用監控,當超過某個值時及時告警,到紅線值自動擴容;大促時期提前擴容 增加帶寬
下單 MYSQL響應超過3秒 10%的用戶 慢SQL 慢SQL檢測,及時告警 殺死慢SQL執行請求
下單 數據庫與緩存超過1個小時庫存不一致 BUG 編寫腳本對比數據庫與緩存差異 解決BUG
訂單列表 MYSQL響應超過3秒 10%的用戶 慢SQL 慢SQL檢測,及時告警 殺死慢SQL執行請求

經過以上表格分析,我們需要做的一些改進:

  1. 數據庫、Redis、服務都需要集羣架構;
  2. 完善數據庫運維,增加數據庫慢SQL監控;

於是我們得出最終的架構:

FMEA是高可用架構設計的一個非常有用的方法,不僅能夠發現架構中隱藏的高可用問題,在項目管理過程中也有類似方案,感興趣的可以自行搜索。

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