先不管CAP是什麼,就談談對於一個分散式的系統,它有哪些特徵或行為。
(1)分散式系統會把服務部署在多個節點上
(2)每個節點都有可能存儲數據,一份數據可能在多個節點上有副本
(3)節點之間通過網路進行數據的同步
假設有個服務,需要部署在3個節點上,每個節點都需要存儲同一份數據id,id的初始值都是1。

現在對節點1寫入id=2,當網路正常的情況下,節點1會向節點2與節點3進行數據同步,此時3個節點的id值都是2。不管訪問哪個節點,讀取的id都是一樣的值。

再對節點1寫入id=3時,由於此時發生網路閃斷,節點1無法聯繫到節點2與節點3,那麼此時訪問節點1與節點2將會得到不一樣的值,出現了不一致性。

CAP理論是分散式系統中的核心理論,由三個單詞的首字母組成,分別是
C(Consistence)一致性,對於指定的副本數據,訪問任意一個節點,都能讀到相同的值。
A(Availability)可用性,訪問非故障的節點,總能在合理的時間內得到合理的響應。
P(Partition Tolerance)分區容錯性,發生網路分區時,整個系統依然能對外提供服務。
一致性
對節點1執行數據更新的操作後,如果不進行同步操作,這個時候再去讀取節點2的數據,就會得到不一樣的結果,從而產生不一致。如果任意用戶能在任意時間訪問不同節點,都能得到相同的數據,那麼這個分散式系統就是強一致的。
CAP中的C代表的就是強一致性,並且不考慮數據同步之間的延遲。
此外,還有
弱一致性,指的是在更新某個節點的數據之後,訪問其餘一小部分的節點得不到最新的結果。
最終一致性,指的是某個節點的數據之後,在一段時間內訪問其他節點得不到最新的結果,但在稍後的某一個時刻,能夠得到最新的結果。
可用性
指的是能在合理的時間內得到合理的響應,或者說在有限的時間內得到一個可以理解的響應。對於不同的系統,有不同的「有限時間」。「可以理解的響應」指的是要麼返回執行成功,要麼執行失敗(但狀態碼是200),而不是返回404、500等。
分區容錯性
網路分區指的是,由於網路是不可靠的,本來A機房與B機房可以互相訪問,是一個整體。當A機房與B機房的光纖斷了,A機房便不能與B機房進行通信,整體被劃分成了兩個區域(區域內部是可以互相通信的),於是網路也被劃分成了兩個區域,形成所謂的網路分區。
對於一個分散式系統,發生網路分區是必然存在的。必定不發生網路分區的系統,那就是一個單體系統,並不是分散式系統。
當然,一個分散式系統,在極端的情況下,如果要犧牲P保證AC也是可以的。
一般來說,分散式系統都會選擇滿足P。
那麼,剩餘的CA可以同時滿足嗎?
先說結論,在存在網路分區的情況下(即滿足P),那就不可以同時滿足A與C。
假設節點1存在於分區a中,節點2與節點3存在於分區b中。

此時修改節點1的副本數據,將id變為2

由於存在網路分區,無法將id的新值2同步到其他分區的節點下。
如果此時要滿足A(可用性),且節點2與節點3隻是在另外一個分區中,並沒有發生節點本身的故障,由可用性的定義,三個節點都可以進行訪問。
此時用戶訪問節點1,得到id=2,訪問節點2時,得到id=1,發生數據不一致的情況。
所以,滿足A的情況下,就滿足不了C(一致性)。
如果一開始要滿足C呢?
為了保證訪問各個節點,都能用戶最新更新的值,就要禁止任何對節點2與節點3的讀寫操作,這就違背了A。
所以,在滿足C的情況下,就滿足不了A。
既然在發生網路分區的時候,不能同時滿足A與C,那麼怎麼在兩者之間進行權衡呢?
選擇AP
在發生網路分區的情況下,選擇可用性,就要放棄一致性。
Eureka就是典型的AP系統
在Eureka集群中,各個server節點沒有主從之分,都是相互平等的個體。
各個server節點會互相複製數據,產生衝突時,直接用最新的數據覆蓋掉舊數據即可。
每一個client只會向一個server節點註冊,server會將該client的ip等信息放入到註冊列表中。
之後client會向server節點定時發送心跳並同時拉取註冊列表到client的本地緩存中,超過一定時間不發送,server會將該client從註冊列表中剔除。
如果一個client下線,首先需要過一段時間才能在server的註冊列表中體現出來,隨後才能在其他的client上的本地緩存中體現出來。因此client上本地緩存中的服務註冊數據並不是最新的,因此這裡不能保證強一致性。
一個server節點宕機或出現網路分區聯繫不上其他節點,其他節點仍然能提供註冊與查詢服務,因此保證了可用性。該server節點沒有將自己的註冊列表同步到其他節點,就會使得部分client的註冊信息丟失,因此這裡不能保證一致性。
當上述server節點重新上線或網路穩定後,就能將當前的註冊列表同步到其他節點,整體又能達到最終一致性。
Eureka作為一個專門的服務註冊與發現的系統,能夠容忍數據不一致的情況(例如當A調用B,B已經下線,但A查詢server時,依然能夠獲得B的註冊信息。A隨後發起對B的調用,結果肯定是調用失敗,這個時候A選擇重試或者直接熔斷即可)。即使發生不一致的情況,也基本上是少數數據的不一致,如果這個時候直接強行讓註冊中心不可用,顯然是忍受不了的。
原創文章,作者:投稿專員,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/228368.html