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