來源:北大青鳥總部 2023年03月01日 13:24
隨著互聯網的快速發(fā)展,分布式的思想已經廣泛應用在各個行業(yè)中了。分布式是與中心化相對的概念,中心化的思想是把關鍵的內容集中處理,這樣的好處是提高了效率、更專注專一,壞處是如果中心系統掛了,所有的內容都沒有了。
分布式的思想是把整個模塊分成多個模塊去處理,每個人負責一部分,這樣的好處是即使某一部分沒有了,其它的內容還存在,造成的損失不大,壞處是多模塊協調溝通成本高。
比如在企業(yè)管理中不會把核心模塊只交給某個人負責,而是培養(yǎng)多個人都了解此模塊,這樣即使核心人員離職了,企業(yè)還是可以正常運轉,不會有多大影響。
而在計算機系統的世界中,分布式系統的出現是為了用便宜的、普通的機器完成單個計算機無法完成的計算存儲任務,更好的利用資源處理更多的任務。
早期的時候一套應用程序全部署在一臺機器上,但隨著業(yè)務量的增長、用戶請求的增加,該機器已經不能滿足更多的計算存儲任務,即使換更好的機器或者單獨升級某個組件能力(比如加磁盤、加內存、換更好的CPU)也不能解決問題,這時候只能采用SOA或微服務設計、分布式模式進行部署了,在系統架構上把業(yè)務進行拆分,子業(yè)務與子業(yè)務之間通過網絡進行通信,共同協調完成任務,在部署模式上把不同的子業(yè)務部署在不同的機器上,子業(yè)務扛不住業(yè)務壓力時再加新的機器支撐。
在業(yè)務拆分細?;I(yè)務部署集群化的情況下就會帶來新的問題,不過戴上CAP的帽子后,問題多多的分布式系統也能變得很可愛~
那么什么是CAP定理呢?CAP是一致性Consistency、可用性Availability、分區(qū)容錯性PartitionTolerance,CAP定理是說這三個目標不能同時滿足。
首先我們來看看分區(qū)容錯性,在分布式系統中,大部分系統都分布在子網絡內,每個子網絡就是一個區(qū),比如你的服務一臺部署在北京,一臺部署在上海,這就是兩個區(qū)。而這兩臺服務器可能由于網絡問題而無法通信,這就是分區(qū)容錯,一般來說,由于客觀原因,分區(qū)容錯是不能避免的。
下圖中G1和G2在不同的區(qū),G1向G2發(fā)送消息,但由于鏈路壞了或其它原因,G2可能收不到。
然后我們再來看看一致性,一致性的意思就是數據必須一致。比如你位于北京區(qū)域,然后在淘寶下單買了一個商品,這時候在北京區(qū)域的訂單系統服務器上有了你的訂單記錄,但是在上海區(qū)域的服務器系統沒有獲取這個信息,所以就會存在你在北京時能看到自己的訂單記錄,但到了上海后沒有訂單記錄的情況(基于CDN內容分發(fā)網絡原則,網絡請求往最近的服務器區(qū)域發(fā)送)。如下圖所示,客戶端往服務器G1寫了一條數據V0,G1必須要往G2服務器再寫入V0這條數據,這樣當客戶端向G2服務器請求數據時才能獲取V0這條數據的同步,如果G1沒有向G2同步寫數據,就會出現客戶端向G2請求時數據不一致。
最后我們來看看可用性,可用性就是服務任何時候都可以用,只要客戶端發(fā)起請求,服務器端就必須響應。
那么一致性和可用性為什么不能并存呢?比如為了保障G2的一致性,那么G1在寫操作的時候,就必須鎖定G2的讀操作和寫操作,只有數據同步后才能開放G2的讀寫,在鎖定的時候,G2就必然不可用;而如果保障G2的可用性,那么G1在寫操作的時候,G2就不能被鎖定,數據就會不一致。因此CA只能擇一,魚和熊掌畢竟也不能兼得。
在某些業(yè)務,比如交易場景中,因為涉及到了金錢,所以必須要數據一致,有任何差錯,老板就會拿刀架你脖子上了。
Zookeeper就是保障了數據一致性的方案。在Zookeeper中使用專有的ZAB原子廣播協議來保障數據的一致性,在該協議中會包含三個角色Leader領導者、Follower跟隨者、Observer觀察者,Leader是唯一處理寫請求的人;Follower是接收客戶端的請求,處理讀請求但不處理寫請求,并且可以參加或投票Leader的選舉(當Leader掛了的時候);Observer是不能參加也不能投票的Follower。
當客戶端向服務器發(fā)送請求,要寫入數據時,服務器會根據自己的角色和該請求的類型進行判斷,如果自己是leader那么就處理該請求;如果自己是Follower,那么服務器會根據請求類型進行決策,如果是寫請求,就轉發(fā)給Leader,Leader會給所有的Follower都發(fā)一個提議,讓大家來投票,如果超過一半的服務器都同意這個提議,那么Leader才會進行操作,從而保障了數據的一致性。
比如在我們剛剛的訂單場景中,當用戶在客戶端發(fā)起一個商品購買請求給到訂單系統服務器時,服務器集群中的Leader判斷這是一個寫請求,需要往數據庫里插入一條某某用戶已購買某某商品的記錄,它會把這個記錄直接放在自己的服務器的數據庫里,并同步給其它的服務器也需要寫入該記錄。
如果客戶端的請求發(fā)送給了Follower的服務器,那么它會轉發(fā)給Leader,Leader就給所有的服務器都發(fā)通知,問他們是否可以寫入此條記錄,如果超過一半的人都表示可以操作,那么Leader、對應的服務器就會把數據寫入在服務器里。
在某些業(yè)務,比如電商場景中,對于服務的可用性要求非常高,雙十一的時候打不開商品的頁面簡直是會要了女人的命啊,當然打開了就會要了男人的命,哈哈哈,開個小玩笑。
所以在電商場景中服務的可用性是非常重要的,Eureka就是保障了服務可用性的方案。在Eureka集群中,服務器與服務器是通過Replicate來同步數據的,不區(qū)分master節(jié)點、slave節(jié)點,每個應用都指向其它應用,當某個服務器宕機時,該應用就切換到新的服務器節(jié)點執(zhí)行任務,待宕機服務器恢復正常后,再將服務切回來。
如下圖所示,還是以訂單場景來講解,在北京、上海、西安機房的服務器里都部署了訂單服務的應用程序,但是可能西安機房斷電了出了故障,從而導致西安的用戶使用訂單服務時就不能正常的使用了,但是因為整個大系統采用的是跨地區(qū)的高可用的集群部署模式,因此當西安的服務不可用時,用戶的請求就會走到上海,由上海的機房來提供服務,同時把數據同步給到北京的服務器,但這時候就會出現一個問題:西安機房的服務器由于斷電了沒能提供服務,因此斷電這段時間內的服務數據時沒有的,就出現了北京上海西安的數據不一致的情況。在業(yè)務場景中通常采用人工校對、客服等的方式可以解決。
Zookeeper我所欲也,Eureka亦我所欲也,二者不可得兼??捎眯晕宜玻恢滦砸辔宜?,然二者不可得兼,同學們根據自己的業(yè)務場景選擇合適的分布式協調框架即可~~