系統的可用性(Availability)是描述應用系統可有效訪問的特性。算法
咱們都知道,硬件故障是常態,網站的高可用架構設計的主要目的就是保證服務器硬件故障時服務依然可用、數據依然保存並可以被訪問。數據庫
實現上述高可用架構的主要手段是數據和服務的冗餘備份及失效轉移,一旦某些服務器宕機,就將服務切換到其餘可用的服務器上,若是磁盤損壞,則從備份的磁盤讀取數據。segmentfault
一個典型的網站設計一般遵循應用層、服務層、數據層的基本分層架構模型。各層之間具備相對獨立性,應用層主要負責具體業務邏輯處理;服務層負責提供可複用的服務;數據層負責數據的存儲與訪問。緩存
在應用層,能夠經過負載均衡設備將一組服務器組成一個集羣共同對外提供服務,當負載均衡設備經過心跳檢測等手段監控到某臺服務器不可用時,就將其從集羣列表中剔除,並將請求分發到集羣中其餘可用的服務器上,使整個集羣保持可用,從而實現應用高可用。服務器
服務層的狀況和應用層相似,也是經過集羣方式實現高可用,只是這些服務器被應用層經過分佈式服務調用框架訪問,分佈式服務調用框架會在應用層客戶端程序中實現軟件負載均衡,並經過服務註冊中心對提供服務的服務器進行心跳檢測,發現有服務不可用,當即通知客戶端程序修改服務訪問列表,剔除不可用的服務器。網絡
位於數據層的服務器狀況比較特殊,爲了保證服務器宕機時數據不丟失,數據訪問服務不中斷,須要在數據寫入時進行數據同步複製,將數據寫入多臺服務器上,實現數據冗餘備份。當數據服務器宕機時,應用程序將訪問切換到有備份數據的服務器上。架構
應用層主要處理網站應用的業務邏輯,所以有時也稱做業務邏輯層,用戶的請求都是由這層來處理,而大多數狀況下請求都是無狀態的。併發
負載均衡,顧名思義,主要使用在業務量和數據量較高的狀況下,當單臺服務器不足以承擔全部的負載壓力時,經過負載均衡手段,將流量和數據分攤到一個集羣組成的多臺服務器上,以提升總體的負載處理能力。負載均衡
當服務器集羣中的服務器均可用時,負載均衡服務器會把用戶的請求分發到任意一臺服務器上進行處理,而當某臺服務器宕機時,負載均衡服務器經過心跳檢測機制發現該服務器失去響應,就會把它從服務器列表中刪除,而將請求發送到其餘服務器上,請求在任何一臺服務器中處理都不會影響最終的結果。框架
不過事實上,業務老是有狀態的,例如在交易類的電子商務網站,須要有購物車記錄用戶的購買信息。在使用負載均衡的集羣環境中,因爲負載均衡服務器可能會將請求分發到集羣任何一臺應用服務器上,因此保證每次請求依然可以得到正確的Session比單機時要複雜不少。
集羣環境下,Session管理主要有如下幾種手段。
Session複製是早期應用系統使用較多的一種服務器集羣Session管理機制。它的原理是在集羣中的服務器之間同步Session對象,使得每臺服務器上都保存全部用戶的Session信息,而服務器使用Session時,只須要在本機獲取便可。
這種方案雖然簡單,從本機讀取Session信息也很快速,但只能使用在集羣規模比較小的狀況下。當集羣規模較大時,集羣服務器間須要大量的通訊進行Session複製,佔用服務器和網絡的大量資源,系統不堪負擔。
Session綁定能夠利用負載均衡的源地址Hash算法實現,負載均衡服務器老是未來源於同一IP的請求分發到同一臺服務器上。這樣在整個會話期間,用戶全部的請求都在同一臺服務器上處理,保證Session總能在這臺服務器上獲取。
可是Session綁定的方案顯然不符合咱們對系統高可用的需求,由於一旦某臺服務器宕機,那麼該機器上的Session也就不復存在了,用戶請求切換到其餘機器後由於沒有Session而沒法完成業務處理。
目前的主流方案是使用Session服務器。利用獨立部署的Session服務器(集羣)統一管理Session,應用服務器每次讀寫Session時,都訪問Session服務器。
這種解決方案事實上是將應用服務器的狀態分離,分爲無狀態的應用服務器和有狀態的Session服務器,而後針對這兩種服務器的不一樣特性分別設計其架構。
對於有狀態的Session服務器,一種比較簡單的方法是利用分佈式緩存如Redis等,在這些產品的基礎上進行包裝,使其符合Session的存儲和訪問要求。
服務模塊爲業務產品提供基礎公共服務,這些服務一般都獨立分佈式部署,被具體應用遠程調用。服務是無狀態的,所以可使用相似負載均衡的失效轉移策略實現高可用。除此以外,具體實踐中,還有如下幾點高可用的策略。
運維上將服務器進行分級管理,核心應用和服務優先使用更好的硬件,在運維響應速度上也有更高優先級。例如,用戶及時付款購物比能不能評價商品更重要,因此訂單、支付服務比評價服務有更高優先級。
同時在服務部署上也進行必要的隔離,避免故障的連鎖反應。低優先級的服務經過部署在不一樣的容器或虛擬機上進行隔離,而高優先級的服務則須要部署在不一樣的物理機上,核心服務和數據甚至須要部署在不一樣地域的數據中心。
因爲服務端宕機、線程死鎖等緣由,可能致使應用程序對服務端的調用失去響應,進而致使用戶請求長時間得不到響應,同時還佔用應用程序的資源,不利於及時將訪問請求轉移到正常的服務器上。
能夠在應用程序中設置服務調用的超時時間,一旦超時,通訊框架就拋出異常,應用程序根據服務調度策略,可選擇繼續重試或將請求轉移到提供相同服務的其餘服務器上。
應用對服務的調用經過消息隊列等異步方式完成,避免一個服務失敗致使整個應用請求失敗的狀況。如提交一個新用戶註冊請求,應用須要調用三個服務:將用戶信息寫入數據庫,發送帳戶註冊成功郵件,開通對應權限。若是採用同步服務調用,當郵件隊列阻塞不能發送郵件時,會致使其餘兩個服務也沒法執行,最終致使用戶註冊失敗。
若是採用異步調用的方式,應用程序將用戶註冊信息發送給消息隊列服務器後當即返回用戶註冊成功響應。而記錄用戶註冊信息到數據庫、發送用戶註冊成功郵件、調用用戶服務開通權限這三個服務做爲消息的消費者任務,分別從消息隊列獲取用戶註冊信息異步執行。即便郵件服務隊列阻塞,郵件不能成功發送,也不會影響其餘服務的執行,用戶註冊操做可順利完成,只是晚一點收到註冊成功的郵件而已。
固然不是全部服務調用均可以異步調用,對於獲取用戶信息這類調用,採用異步方式會延長響應時間,得不償失。對於那些必須確認服務調用成功才能繼續下一步操做的應用也不適合使用異步調用。
在網站訪問高峯期,服務可能由於大量的併發調用而性能降低,嚴重時可能會致使服務宕機。爲了保證核心應用和功能的正常運行,須要對服務進行降級。降級有兩種手段:拒絕服務及關閉服務。
拒絕服務:拒絕低優先級應用的調用,減小服務調用併發數,確保核心應用正常使用;或者隨機拒絕部分請求調用,節約資源,讓另外一部分請求得以成功。
關閉功能:關閉部分不重要的服務,或者服務內部關閉部分不重要的功能,以節約系統開銷,爲重要的服務和功能讓出資源。例如淘寶在每一年的「雙十一」促銷中,在系統最繁忙的時段關閉「評價」、「確認收貨」等非核心服務,以保證核心交易服務的順利完成。
應用調用服務失敗後,會將調用請求從新發送到其餘服務器,可是這個失敗可能不是真正的失敗。好比服務已經處理成功,但由於網絡故障應用沒有收到響應,這時應用從新提交請求就致使服務重複調用,若是這個服務是一個轉帳操做,就會產生嚴重後果。
服務重複調用是沒法避免的,應用層也不須要關心服務是否真的失敗,只要沒有收到調用成功的響應,就能夠認爲調用失敗,並重試服務調用。所以必須在服務層保證服務重複調用和調用一次產生的結果相同,即服務具備冪等性。
不一樣於高可用的應用和服務,因爲數據層服務器上保存的數據不一樣,當某臺服務器宕機的時候,數據訪問請求不能任意切換到集羣中其餘的機器上。
保證數據存儲高可用的手段主要是數據備份和失效轉移機制。數據備份是保證數據有多個副本,任意副本的失效都不會致使數據的永久丟失,從而實現數據徹底的持久化。而失效轉移機制則保證當一個數據副本不可訪問時,能夠快速切換訪問數據的其餘副本,保證系統可用。
對於數據層的「守護神」緩存服務,也須要保證簡單的高可用。對於緩存服務器集羣中的單機宕機,若是緩存服務器集羣規模較大,那麼單機宕機引發的緩存數據丟失比例和數據庫負載壓力變化都較小,對整個系統影響也較小。
擴大緩存服務器集羣規模的一個簡單手段就是全部應用共享同一個分佈式緩存集羣,單獨的應用只須要向共享緩存集羣申請緩存資源便可。而且經過邏輯或物理分區的方式將每一個應用的緩存部署在多臺服務器上,任何一臺服務器宕機引發的緩存失效都隻影響應用緩存數據的一小部分,不會對應用性能和數據庫負載形成太大影響。
在討論高可用數據服務架構以前,必須先討論的一個話題是,爲了保證數據的高可用,系統一般會犧牲另外一個也很重要的指標:數據一致性。
高可用的數據層有以下幾個層面的含義:
CAP原理認爲,一個提供數據服務的存儲系統沒法同時知足數據一致性(Consistency)、數據可用性(Availibility)、分區耐受性(Patition Tolerance,系統具備跨網絡分區的伸縮性)這三個條件,如圖所示。
在大型應用中,數據規模老是快速擴張的,所以可伸縮性即分區耐受性必不可少,規模變大之後,機器數量也會變得龐大,這時網絡和服務器故障會頻繁出現,要想保證應用可用,就必須保證數據可用性。因此在大型網站中,一般會選擇強化分佈式存儲系統的可用性(A)和伸縮性(P),而在某種程度上放棄一致性(C)。
通常說來,數據不一致一般出如今系統高併發寫操做或者集羣狀態不穩(故障恢復、集羣擴容……)的狀況下,應用系統須要對分佈式數據處理系統的數據不一致性有所瞭解並進行某種意義上的補償和糾錯,以免出現應用系統數據不正確。
CAP原理對於可伸縮的分佈式系統設計具備重要意義。由於難以知足數據強一致性,系統一般會綜合成本、技術、業務場景等條件,結合應用服務和其餘的數據監控與糾錯功能,使存儲系統達到用戶一致,保證最終用戶訪問數據的正確性。
數據備份是一種古老而有效的數據保護手段,早期的數據備份手段主要是數據冷備。冷備的優勢是簡單和廉價,成本和技術難度都較低。缺點是不能保證數據最終一致,因爲數據是按期複製,所以備份設備中的數據比系統中的數據陳舊,若是系統數據丟失,那麼從上個備份點開始後更新的數據就會永久丟失。同時也不能保證數據可用性,從冷備存儲中恢復數據須要較長的時間,而這段時間沒法訪問數據,系統也不可用。
所以,數據冷備做爲一種傳統的數據保護手段,依然在網站平常運維中使用,同時在網站實時在線業務中,還須要進行數據熱備,以提供更好的數據可用性。數據熱備可分爲異步熱備方式和同步熱備方式。
異步方式是指多份數據副本的寫入操做異步完成,應用程序正常狀況下只鏈接主存儲服務器,數據寫入時,由主存儲服務器的寫操做代理模塊將數據寫入本機存儲系統後當即返回寫操做成功響應,而後經過異步線程將寫操做數據同步到從存儲服務器。
同步方式是指多份數據副本的寫入操做同步完成,即應用程序收到數據服務系統的寫成功響應時,多份數據都已經寫操做成功。可是當應用程序收到數據寫操做失敗的響應時,可能有部分副本或者所有副本都已經寫成功了(由於網絡或者系統故障,沒法返回操做成功的響應)。
延伸閱讀:【分佈式—要點】數據複製
若數據服務器集羣中任何一臺服務器宕機,那麼應用程序針對這臺服務器的全部讀寫操做都須要從新路由到其餘服務器,保證數據訪問不會失敗,這個過程叫做失效轉移。失效轉移操做由三部分組成:失效確認、訪問轉移、數據恢復。
判斷服務器宕機是系統進行失效轉移的第一步,系統確認一臺服務器是否宕機的手段有兩種:心跳檢測和應用程序訪問失敗報告。對於應用程序的訪問失敗報告,控制中心還須要再一次發送心跳檢測進行確認,以避免錯誤判斷服務器宕機。
確認某臺數據存儲服務器宕機後,就須要將數據讀寫訪問從新路由到其餘服務器上。對於徹底對等存儲的服務器(幾臺存儲服務器存儲的數據徹底同樣),當其中一臺宕機後,應用程序根據配置直接切換到對等服務器上。若是存儲是不對等的,那麼就須要從新計算路由,選擇存儲服務器。
由於某臺服務器宕機,因此數據存儲的副本數目會減小,必須將副本的數目恢復到系統設定的值,不然,再有服務器宕機時,就可能出現沒法訪問轉移(全部副本的服務器都宕機了),數據永久丟失的狀況。所以系統須要從健康的服務器複製數據,將數據副本數目恢復到設定值。