架構應用之高可用、高複用

高可用包括:存儲高可用,計算高可用,業務高可用。

架構應用之高可用、高複用

一、存儲高可用

存儲的高可用,主要是通過數據冗餘的方式來實現高可用,複雜性主要是在如何保持數據一致性,複製延遲和網絡中斷都會帶來數據不一致。主要考慮的就是,數據如何複製,如何應對複製延遲,如何應對複製中斷,各個節點的職責是什麼。

常見的存儲架構:主從,主備,主主,集群,分區。

1.主備,最常見最簡單的一種存儲方案。

主機存儲數據,通過複製通道將數據複製到備機,客戶端無論讀寫操作 ,都發送給主機。

備機不對外提供任何讀寫服務。

主機故障情況下,此時整個系統處於不可用狀態,不能讀寫數據,如果主機不能恢復(例如,機器硬盤損壞,短時間內無法恢復), 則需要人工操作, 將備機升為主機。

優點:

對於客戶端來說,不需要感知備機的存在。即使災難恢復後,客戶端無須知道是原來的備機升級為主機了 。

對於主機和備機來說 , 雙方只需要進行數據複製即可,無須考慮太複雜的數據一致性問題。

缺點:

備機僅僅只為備份,並沒有提供讀寫操作 ,硬件成本上有浪費。

故障後需要人工干預,無法自動恢復。

綜合主備複製架構的優缺點,內部的後臺管理系統使用主備複製架構的情況會比較多,數據變更頻率很低,即使在某些場景下丟失,也可以通過人工的方式補全。

2.主從,主機負責讀寫操作,從機只負責讀操作,不負責寫操作。

主機存儲數據,通過複製通道將數據複製到從機。

正常情況下,客戶端寫操作發送給主機,讀操作可發送給主機也可以發送給從機。

主機故障情況下,客戶端無法進行寫操作,但可以將讀操作發送 給從機,從機繼續響應讀操作。如果主機不能恢復(例如,機器硬盤損壞,短時間內無法恢復), 則需要人工操作, 將備機升為主機。

如果主從間數據複製延遲,則會出現主從讀取的數據不一致的問題。

主從複製與主備複製相比,有以下不同的優缺點 :

主從複製在主機故障時,讀操作相關的業務不受影響;發揮了硬件的性能;

主從複製要比主備複製複雜更多,主要體現在客戶端需要感知主從關係,並將不同的操作發給不同的機器進行處理 。

綜合主從複製的優缺點 , 一般情況下,寫少讀多的業務使用主從複製的存儲架構比較多。例如,論壇、 BBS 、新聞網站這類業務。

主備倒換與主從倒換:

主機故障後,無法進行寫操作 ,需要人工指定新的主機角色。

主備倒換和主從倒換方案就是為了解決上述問題而產生的。簡單來說,這兩個方案就是在原有方案的基礎上增加 “倒換”功能, 即系統自動決定主機角色, 並完成角色切換 。

倒換方案的實現的要點:

主備間狀態判斷,狀態傳遞的渠道(相互連接,還是第三方仲裁),狀態檢測的內容(進程存在,響應緩慢等)

倒換決策,什麼情況下備機升級為主機,原來主機恢復後是否要再次倒換,倒換是完全自動,還是半自動需要人工確認。

數據衝突解決,原故障主機恢復後,新舊主機之間可能存在數據衝突。

3.主主複製,兩臺主機都存儲數據,客戶端將讀寫操作發送給任意一臺主機。

主主複製架構,必須保證數據能夠雙向複製,對數據的設計有嚴格的要求,一般適合於那些臨時性,可丟失,可覆蓋的數據場景。例如用戶的session數據,用戶的行為日誌數據,論壇的草稿數據等。

4.數據集群,這裡主要指數據分散集群,每臺服務器負責存儲一部分數據,同時每臺服務器會備份一部分數據。

設計集群時考慮點:

均衡性,保證服務器上的數據分區基本是均衡的。

容錯性,當部分服務器故障時,將原來分配給故障服務器的數據分區分配給其他服務器。

可伸縮性,當集群容量不夠,擴充新服務器後,能夠自動將部分數據分區遷移至新服務器,保證擴容後的均衡性。

數據分散集群中的每臺服務器都可以處理讀寫請求,必須有一個角色來負責執行數據分配算法,就像hadoop中的namecode。

分佈式事務

數據可能分佈在不同的集群節點上,由於節點間只能通過消息進行通信,因此分佈式事務只能依賴消息通知,消息的不可靠性,這就帶來了分佈式事務的複雜性。

分佈式事務算法中常見的有“二階段提交”和“三階段提交”

二階段提交,“commit請求階段”和“commit提交階段”,(1)存在一個節點協調者,協調者向所有參與者發送詢問是否可以執行提交事務;(2)參與者執行事務操作,執行成功,則將undo信息和redo信息寫入日誌,鎖定資源返回YES不提交事務,執行失敗,返回NO給協調者;(3)協調者收到響應消息都為YES時,發送COMMIT請求,如果任一參與者返回NO,則發送ROLLBACK請求,參與者執行事務操作,返回ACK消息,協調者收到反饋後確認是完成或取消事務。

實現簡單,但缺點也很明顯:同步阻塞,協調者和參與者互相等待響應消息,如果某個節點響應消息比較慢,則整個系統全部被拖慢,不適合高併發場景;狀態不一致,某一參與者如果沒有收到commit消息,會一直等待直到超時後回滾事務,其他參與者都已提交事務,導致事務狀態不一致。

三階段提交,協調者先向所有參與者發送一個詢問是否可以執行事務,協調者在超時時間內收到所有yes後進入第二階段;協調者發送準備提交請求,參與者執行事務操作,記錄undo和redo事務日誌,返回ACK消息;協調者收到所有ACK消息後,發送commit請求,如果沒有收到全部ACK,則會發出回滾請求,參與者收到請求執行操作,如果等待超時還是會執行commit請求。

5.數據分區,指將數據按照一定的規則進行分區,不同分區分佈在不同的地理位置上。

通過這種方式來規避地理級別的故障造成的巨大影響。

常見的分區複製規則:(1)集中式,備份指存在一個總的備份中心,所有的分區都將數據備份到備份中心。設計簡單,分區間無交互,擴展容易,成本較高。(2)互備式,每個分區備份另外一個分區的數據,設計複雜,分區相互間互相關聯和影響,擴展複雜,成本低,直接利用已有的設備。(3)獨立式,每個分區自己有獨立的備份中心,設計簡單,擴展容易,成本高。

二、計算高可用

當部分硬件損壞時,計算任務能夠繼續正常運行。通過增加更多服務來達到計算高可用。

主備架構是計算高可用最簡單的架構,可以細分為冷備架構和福備架構,常用溫備架構 。

溫備架構,備機上的業務系統己經啟動,只是不對外提供服務,主機故障後,人工只需要將任務分 配器的任務請求切換為發送到備機即可。

高可用計算的集群

對稱集群,集群中每個服務器的角色都是一樣的,都可以執行所有任務,更通俗的叫法是負載均衡集群。

非對稱集群, 集群中的 服務器分為多個不同的角色,不同的角色執行不同的任務,例如,最常見的 Master-Slave 角色。

不同角色的服務器承擔不同的職責 。 以 Master-Slave 為例,部分任務是 Master 服務器才能執行,部分任務是 Slave 服務器才能執行。當指定類型的服務器故障時,需要重新分配角色。例如 ,Master 服務器故障後, 需要將剩餘的 Slave 服務器中的一個重新指定為 Master服務器;Slave服務器故障,只需要剔除就可以了。

以 ZooKeeper 為例:

( 1 )任務分配器: ZooKeeper 中不存在獨立的任務分配器節點,每個 Server 都是任務分配器, Follower 收到請求後會進行判斷,如果是寫請求就轉發給 Leader,如果是讀請求就自己處理。

(2 )角色指定: ZooKeeper 通過 ZAB 協議來選舉 Leader,當 Leader 故障後,所有的 Follower 節點會暫停讀寫操作,開始進行選舉,直到新的 Leader 選舉出來後才繼續對 Client 提供服務 。

三、業務高可用

業務高可用,如果保證了存儲高可用和計算高可用,業務高可用的保障也已經很高了,通常來說已經可以滿足大部分系統的需求了。這裡再談一下異地多活,針對極端情況的高可用方案。還有接口級故障方案,系統沒有宕機網絡也沒問題情況下,表現為響應慢。

1.異地多活

異地就是指地理位置上不同的地方 通常指不同的機房, 類似於“不要把雞蛋都放在同一籃子裡”;

多活就是指不同地理位置上的系統都能夠提供業務服務。

實現異地多活有很高的代價,具體表現為:

• 系統複雜度會發生質的變化,需要設計複雜的異地多活架構。

• 成本會上升,畢竟要多在一個或多個機房搭建獨立的一套業務系統。

異地多活通常可以分為三種,同城異區,跨城異地,跨國異地。

同城異區指的是將業務部署在同一個城市不同區的多個機房 。關鍵在於搭建高速網絡將兩個機房連接起來,達到近似一個本地機房的效果。架構設計 上可以將兩個機房當作本地機房來設計,無須額外考慮 。

跨城異地指的是業務部署在不同城市的多個機房,而且距離最好要遠一些。跨城異地距離較遠帶來的網絡傳輸延遲問題,給業務多活架構設計帶來了複雜性,在數據短時間不一致的情況下,還能夠正常提供業務 。架構設計的主要目的就是為了解決這個矛盾。

跨城異地肯定會導致數據不一致,如何解決這個問題呢?

重點還是在“數據”上,即根據數據的特性來做不同的架構。如果 是強一致性要求的數據,例如,銀行存款餘額,支付寶餘額等,這類數據實際上是無法做到跨 城異地多活的 。

支付寶等金融相關的系統,對餘額這類數據,不能做跨 城異地的多活架構,而只能採用同城異區這種架構 。

跨國異地指的是業務部署在不同國家的多個機房。跨國異地的距離更加遠 了,因此數據同步的延時會更長,正常情況下可能就有幾秒鐘了。主要是面向不同地區用戶提供業務,或者提供只讀業務,對架構設計要求不高。

跨城異地多 活架構設計的一些技巧和步驟 :

技巧:

(1)保證核心業務的異地多活

(2)核心數據最終一致性,數據同步是異地多活架構的設計核心 。儘量減少數據同步,只同步核心業務相關的數據,保證最終一致性,不保證實時一致性。

採用多種手段同步數據:

存儲系統本身都會有同步的功能,MySQL 的主備複製、 Redis 的 Cluster 功能、 Elasticsearch 的集群功能 。

當我們只考慮存 儲系統本身的同步功能時,就會發現無法做到真正的異地多活。以 MySQL 為例, MySQL5.l 版本的複製是單線程的複製,在網絡抖動或大量數據 同步時 , 經常發生延遲較長的問題,短則延遲十幾秒,長則可能達到十幾分鍾 。

解決的方案就是拓展思路,避免只使用存儲系統的同步功能,可以將多種手段配合存儲系 統的同步來使用:1.消息隊列方式,將數據通過消息隊列同步到其他業務中心。2.二次讀取方式,B 中心在讀取本地數據失敗時,可以根據路由規則,再去 A 中心訪問一次。3.存儲系統同步方式。4.回源讀取方式,不同步數據,根據路由回原中心讀取。5.重新生成數據方式。

步驟:

第一步:業務分級,挑選出核心的業務,只為核心業務設計異地多活,降低方案複雜度和成本。

第二步:數據分類,識別所有的數據及數據特徵,數據特徵會影響後面的方案設計。

數據特徵分析維度:

數據量、唯一性(同類數據必須保證唯一 ,例如用戶 ID)、可丟失性、可恢復性

第三步 : 數據同步,根據不同的數據設計不同的同步方案。

第四步:異常處理,一旦出現極端異常的情況,總是會有部分數據出現異常的。出現這些問題時,系統將採 取什麼措施來應對。

常見的異常處理措施有如下幾類。

( 1 )多通道同步 。採取多種方式來進行數據同步,其中某條通道故障的情況下 ,系統可以通過其他方式來進行同步。

( 2 )同步和訪問結合。訪問指異地機房通過系統的接口來進行數據訪問 。

( 3 )日誌記錄 。用於故障恢復後對數據進行恢復。

2.接口級故障應對方案——降級、熔斷、限流、排隊

接口級故障的典型表現就是系統並沒有宕機, 網絡也沒有中斷, 但業務卻出現問題了 。 例如,業務響應緩慢, 大量訪問超時, 大量訪問出現異常 ( 給用戶彈出提示“無法連接數據庫勺, 這類問題的主要原因在於系統壓力太大, 負載太高, 導致無法快速處理業務請求, 由此引發更多的後續問題。最終用戶看到的現象就是訪問很慢。

導致接口級故障的原因,一般有如下幾種 :

• 內部原因 程序 bug 導致死循環, 某個接口導致數據庫慢查詢, 程序邏輯不完善導致耗盡內存等。

• 外部原因 黑客攻擊、促銷或搶購引入了超出平時幾倍甚至幾十倍的用戶訪問, 第三方系統大量請求,第三系統響應緩慢, 等等 。

解決接口級故障的核心思想和異地多活基本類似:優先保證核心業務 , 優先保證絕大部分用戶 。

(1)降級,系統將某些業務或接口的功能降低,可以是隻提供部分功能,優先保證核心業務。

常見的實現降級 的方式有如下幾種 :

• 系統後門降級,系統預留了後門用於降級操作,系統提供一個降級 URL, 當訪問這個URL時 ,就相當於執行降級指令。

• 獨立降級系統,將降級操作獨立到一個單獨的系統中。

(2)熔斷,降級的目的是應對系統自身的故障,而熔斷的目的是應對依賴的外部系統故障的情況。

A 服務的 X 功能依賴 B 服務的某個接口,當 B 服務的接口響應很慢的時候, A 服務的 X 功能響應肯定也會被拖慢,進一步導致 A 服務的線程都被卡在 X 功能處 理上,此時 A 服務的其他功能都會被卡住或響應非常慢 。 這時就需要熔斷機制了,即 A 服務不 再請求 B 服務的這個接口, A 服務內部只要發現請求 B 服務的這個接口就立即返回錯誤,從而 避免 A 服務整個被拖慢甚至拖死。

熔斷機制實現的關鍵是需要有一個統一的 API 調用層,由 API 調用層來進行採樣或統計, 如果接口調用散落在代碼各處就沒法進行統一處理了 。

另外一個關鍵是闊值的設計。1 分鐘內 30% 的請求響應時間超過 l 秒就熔斷,這個策略中的“ 1 分鐘”“ 30% ”“ l 秒”都對最終的熔斷效果有影響 。

(3)限流,限流則是從用戶訪問壓力的角度來考慮如何應對故障。 限流指只允許系統能夠承受的訪問量進來,超出系統訪問能力的請求將被丟棄。

限流一般都是系統內實現的 ,常見的限流方式可以分為兩類:基於請求限流和基於資源限流。

基於請求限流指從外部訪問的請求角度考慮限流,常見的方式有限制總量和限制時間量 。

基於資源限流是從系統內部考慮 的, 即找到系統內部影響性能的關鍵資源,對其使用上限進行限制 。 常見的內部資源有連接數、文件句柄 、 線程 數、請求隊列等 。

(4)排隊,排隊實際上是限流的一個變種 ,限流是直接拒絕用 戶 ,排隊是讓用戶等待很長時間,

一般情況下, 排隊需要用獨立的系統去實現。例如,使用 Kafka 這類消息隊列來緩存用戶請求。


分享到:


相關文章: