java分布式面試CAP分別代表含義分析
引言
上一節(jié)講面試中被問到分布式系統(tǒng)概念相關(guān)的,講完了分布式系統(tǒng)的概念,優(yōu)點(diǎn)缺點(diǎn)和 RPC 后,我以為這個(gè)問題就到此結(jié)束了,沒想到成功給自己挖了個(gè)坑(微笑臉),關(guān)于 CAP,以前只是聽說過,并沒有詳細(xì)點(diǎn)整理過,這一次問好好整理了下。
CAP 問題已經(jīng)成了計(jì)算機(jī)科學(xué)中一個(gè)研究領(lǐng)域,之前說到分布式系統(tǒng)有哪些優(yōu)勢(shì)時(shí)講到三個(gè)提升:
1. 系統(tǒng)可用性提升。
2. 系統(tǒng)并發(fā)能力提升。
3. 系統(tǒng)容錯(cuò)能力提升。
那么這三方面在實(shí)施起來可以同時(shí)滿足嗎?答案是不能,設(shè)計(jì)分布式系統(tǒng)的時(shí)候,設(shè)計(jì)者需要理解一個(gè)重要的理論概念,CAP 定理。
1、面試官,說到 CAP 定理,那能詳細(xì)說說 CAP 分別代表什么嗎?
問題分析:一個(gè)很經(jīng)典的概念性面試題。
答:關(guān)于 CAP,它是 2000 年 7 月,加州大學(xué)伯克利分校的 Eric Brewer 教授在 ACM PODC 會(huì)議上提出 CAP 猜想。2 年后,麻省理工學(xué)院的 Seth Gilbert 和 Nancy Lynch 從理論上證明了 CAP。之后,CAP 理論正式成為分布式計(jì)算領(lǐng)域的公認(rèn)定理。
C 的全拼是 Consistency,代表 一致性的意思。
A 的全拼是 Availability,代表 可用性的意思。
P 的全拼是 Partition tolerance,代表 分區(qū)容錯(cuò)性的意思。
2、面試官:聽起來很簡單,這只是概念,但是具體是什么意思呢?
問題分析:下次這種問題不能等面試官來問了,這面試有點(diǎn)擠牙膏的感覺,不如我一次說完,讓面試官閉嘴。
答:一個(gè)分布式系統(tǒng)最多同時(shí)滿足一致性 (Consistency),可用性 (Availability) 和分區(qū)容忍性 (Partition Tolerance) 這三項(xiàng)中的兩項(xiàng)。
- 同時(shí)滿足一致性(C)和可用性(A)就要犧牲掉容錯(cuò)性(P)
- 同時(shí)滿足可用性(A)和分區(qū)容錯(cuò)性(P)就要犧牲掉一致性(C)
- 同時(shí)滿足一致性(C)和分區(qū)容錯(cuò)性(P)就要犧牲掉可用性(A)
(開始拿起紙筆畫了三個(gè)圈圈)
這三個(gè)象限,只能同時(shí)滿足其中兩個(gè)圓圈的交集。
面試官:行了行了,這個(gè)理論性的問題就到這,時(shí)間有限,我們聊點(diǎn)別的。
舉例深入分析
用 Redis Cluster 高可用架構(gòu)舉例:Redis 就能會(huì)將數(shù)據(jù)分片到多個(gè)實(shí)例 (按照 slot 存儲(chǔ)) 中,即一個(gè)機(jī)房分擔(dān)一部分?jǐn)?shù)據(jù)。Master 負(fù)責(zé)寫,Master 會(huì)自動(dòng)同步到 Slave。
Redis 去中心集群架構(gòu)優(yōu)點(diǎn):
1. 無中心架構(gòu):三機(jī)房部署,其中一主一從構(gòu)成一個(gè)分片,之間通過異步復(fù)制同步數(shù)據(jù),異步復(fù)制存在數(shù)據(jù)不一致的時(shí)間窗口,保證高性能的同時(shí)犧牲了部分一致性。一旦某個(gè)機(jī)房掉線,則分片上位于另一個(gè)機(jī)房的 slave 會(huì)被提升為 master 從而可以繼續(xù)提供服務(wù)。
2. 可擴(kuò)展性:可線性擴(kuò)展到 1000 多個(gè)節(jié)點(diǎn),節(jié)點(diǎn)可動(dòng)態(tài)添加或刪除。
3. 降低運(yùn)維成本,提高系統(tǒng)的擴(kuò)展性和可用性。
分析,這個(gè)分布式架構(gòu)中滿足了 CAP 中哪個(gè)兩個(gè)定理?
優(yōu)點(diǎn) 1 中講到,三機(jī)房部署,每個(gè)機(jī)房有一主一從,即一個(gè) Master 對(duì)應(yīng)一個(gè) Slave ,但是你會(huì)發(fā)現(xiàn),機(jī)房 1 中的 Master 1 連接的 Slave 在機(jī)房 2,機(jī)房 2 中的 Master 2 連接的 Slave 在機(jī)房 3,機(jī)房 3 中的 Master 3 連接的 Slave 在機(jī)房 1,這樣構(gòu)成一個(gè)環(huán),為什么要這樣設(shè)計(jì)?
假設(shè):機(jī)房斷電 or 火災(zāi) or 其他各種原因,反正就是機(jī)房 1 所有機(jī)器都不能用了。
這個(gè)時(shí)候那機(jī)房 1 的全部數(shù)據(jù)都不能訪問了嗎?這顯然是我們不希望的。前面已經(jīng)說了 Master 負(fù)責(zé)寫,Master 會(huì)自動(dòng)同步到 Slave,如果 Master 寫服務(wù)宕機(jī),Slave 讀服務(wù)會(huì)被提升為 Master ,也就是說機(jī)房 1 的數(shù)據(jù)在機(jī)房 2 的 Slave2 上還有備份,數(shù)據(jù)還在,在宕機(jī)的 Master 沒有恢復(fù)前 Slave 要同時(shí)承擔(dān)讀寫服務(wù),雖然累一點(diǎn),但是還能用,這樣設(shè)計(jì)是為了提高可用性(A),和容錯(cuò)性(P)。系統(tǒng)準(zhǔn)許你一臺(tái)機(jī)器或者整個(gè)機(jī)房都宕機(jī),系統(tǒng)仍然能用。
但是你會(huì)發(fā)現(xiàn),單個(gè)機(jī)房如果距離很遠(yuǎn), Master 1 的數(shù)據(jù)同步到 Slave2 上是跨機(jī)房,跨機(jī)房同步肯定不如同機(jī)房塊,這樣一來 Slave2 負(fù)責(zé)的讀就會(huì)有延遲,Master1 要更新的數(shù)據(jù)還沒有同步到他在另一個(gè)機(jī)房的備份前,讀操作就是不一致的,這樣設(shè)計(jì)顯然是犧牲掉一致性(C)。相信這樣分析應(yīng)該能理解 CAP 定理了。
進(jìn)一步分析:
讓同一組 Master - Slave 放在一個(gè)機(jī)房,同機(jī)房復(fù)制數(shù)據(jù)不是更快?這樣能不能解決數(shù)據(jù)一致(C)問題,答案是能,還有更好的解決一致性的辦法就是不要 Master - Slave 組合,就一臺(tái)機(jī)器,一臺(tái)機(jī)器同時(shí)擔(dān)任讀寫請(qǐng)求,沒有延遲不存在數(shù)據(jù)一致性問題。這是時(shí)候如果宕機(jī)了怎么辦?這樣的架構(gòu)下,那就真的是不可用了,解決了一致性(C)卻犧牲了可用性(A)和容錯(cuò)性(P),太不劃算了。
總之,分布式系統(tǒng)下,CAP 確實(shí)無法同時(shí)滿足,在 Redis 去中心集群架構(gòu)中,最優(yōu)的解決方案還是滿足可用性(A)和分區(qū)容錯(cuò)性(P)就要犧牲掉一致性(C),即使跨機(jī)房同步數(shù)據(jù),延遲也不過 1s,數(shù)據(jù)不一致的問題只出現(xiàn)在 1s 內(nèi),日常開發(fā)中,很少遇到要求強(qiáng)一致性的場(chǎng)景。例如訂單系統(tǒng),用戶更新了訂單支付狀態(tài),讀訂單狀態(tài)是在從庫,有什么讀場(chǎng)景等不來這一秒?
如果真的必須要求強(qiáng)一致性,那可能就必須調(diào)整分布式架構(gòu)方案來。
總結(jié)
本文主要講解了 CAP 定理的概念,為什么要學(xué)習(xí)這個(gè)概念,設(shè)計(jì)高可用分布式系統(tǒng)時(shí),你必須知道系統(tǒng)的短處,懂得 CAP 能讓你根據(jù)實(shí)際情況有舍有得。面試會(huì)被經(jīng)常問到,比如,你說你使用了消息隊(duì)列,解決了系統(tǒng)耦合問題,提高了響應(yīng)速度,那面試官問題:使用消息隊(duì)列有啥缺點(diǎn)?如果你知道 CAP 定理這個(gè)問題還難嗎?
顯然消息的延遲會(huì)帶來數(shù)據(jù)不一致問題。理想情況下消息不丟失那數(shù)據(jù)會(huì)最終一致,你能保證消息不丟失嗎?如何解決機(jī)問題,如果是我,我會(huì)選擇 “最終一致性”,就是說不管消息延遲多久甚至丟失,設(shè)計(jì)一個(gè)離線定時(shí)任務(wù),定期去掃描兩個(gè)系統(tǒng)的數(shù)據(jù),有不一致的情況就主動(dòng)刷新同步,這樣保證最終一致。
以上就是java分布式面試CAP分別代表含義分析的詳細(xì)內(nèi)容,更多關(guān)于java分布式面試CAP含義的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java8新特性之接口中的默認(rèn)方法和靜態(tài)方法詳解
今天帶大家學(xué)習(xí)的是Java8新特性的相關(guān)知識(shí),文章圍繞著Java接口中的默認(rèn)方法和靜態(tài)方法展開,文中有非常詳細(xì)的的代碼示例,需要的朋友可以參考下2021-06-06用Rational Rose逆向工程(java)生成類圖(教程和錯(cuò)誤解決)
Rational Rose有個(gè)很方便的功能,將項(xiàng)目中的JAVA代碼自動(dòng)轉(zhuǎn)換成UML類圖2013-02-02java實(shí)現(xiàn)一個(gè)簡單TCPSocket聊天室功能分享
這篇文章主要為大家分享了java實(shí)現(xiàn)的一個(gè)簡單TCPSocket聊天室功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-04-04如何將maven項(xiàng)目導(dǎo)出jar包(最簡單方法)
大家都知道對(duì)于將maven項(xiàng)目導(dǎo)出jar包有好幾種方式,本文給大家分享一種方式最容易且最方便,感興趣的朋友跟隨小編一起看看吧2023-11-11SpringBoot--Banner的定制和關(guān)閉操作
這篇文章主要介紹了SpringBoot--Banner的定制和關(guān)閉操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2018-05-05Java實(shí)現(xiàn)調(diào)用對(duì)方http接口得到返回?cái)?shù)據(jù)
這篇文章主要介紹了Java實(shí)現(xiàn)調(diào)用對(duì)方http接口得到返回?cái)?shù)據(jù),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09Spring中的@Conditional注解實(shí)現(xiàn)分析
這篇文章主要介紹了Spring中的@Conditional注解實(shí)現(xiàn)分析, @Conditional是Spring 4出現(xiàn)的注解,但是真正露出價(jià)值的是Spring Boot的擴(kuò)展@ConditionalOnBean等,需要的朋友可以參考下2023-12-12Spring boot項(xiàng)目使用thymeleaf模板過程詳解
這篇文章主要介紹了Spring boot項(xiàng)目使用thymeleaf模板過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07