CAP理論被不少人拿來做爲分佈式系統設計的金律,然而感受你們對CAP這三個屬性的認識卻存在很多誤區,那麼什麼是CAP理論呢?CAP本來是一個猜測,2000年PODC大會的時候大牛Brewer提出的,他認爲在設計一個大規模可擴放的網絡服務時候會遇到三個特性:一致性(consistency)、可用性(Availability)、分區容錯(partition-tolerance)都須要的情景,然而這是不可能都實現的。以後在2003年的時候,Mit的Gilbert和Lynch就正式的證實了這三個特徵確實是不能夠兼得的。數據庫
CAP是Consistency、Availablity和Partition-tolerance的縮寫。分別是指:
1)一致性(Consistency):每次讀操做都能保證返回的是最新數據。也就是說全部的節點數據一致!
2)可用性(Availablity):任何一個沒有發生故障的節點,會在合理的時間內返回一個正常的結果。也就是說一個或者多個節點失效,不影響服務請求!
3)分區容忍性(Partition-torlerance):當節點間出現網絡分區,照樣能夠提供服務。也就是說節點間的網絡鏈接失效,仍然能夠處理請求!網絡
其實,任何一個分佈式系統,須要知足這三個中的兩個。CAP理論指出:CAP三者只能取其二,不可兼得。其實這一點很好理解,理由以下:
1- 首先,單機都只能保證CP。
2- 有兩個或以上節點時,當網絡分區發生時,集羣中兩個節點不能相互通訊(也就是說不能保證可用性A)。此時若是保證數據的一致性C,那麼必然會有一個節點被標記爲不可用的狀態,違反了可用性A的要求,只能保證CP。
3- 反正,若是保證可用性A,即兩個節點能夠繼續各自處理請求,那麼因爲網絡不通不能同步數據,必然又會致使數據的不一致,只能保證AP。異步
1、單實例
單機系統和顯然,只能保證CP,犧牲了可用性A。單機版的MySQL,Redis,MongoDB等數據庫都是這種模式。分佈式
實際中,咱們須要一套可用性高的系統,即便部分機器掛掉以後仍然能夠繼續提供服務。spa
2、多副本線程
相比於單實例,這裏多了一個節點去備份數據。
對於讀操做來講,由於能夠訪問兩個節點中的任意一個,因此可用性提高。設計
對於寫操做來講,根據更新策略分爲三種狀況:
1)同步更新:即寫操做須要等待兩個節點都更新成功才返回。這樣的話若是一旦發生網絡分區故障,寫操做便不可用,犧牲了A。
2)異步更新:即寫操做直接返回,不須要等待節點更新成功,節點異步地去更新數據(FastDFS文件系統的存儲節點就是用這種方式,寫完一份數據以後當即返回結果,副本數據由同步線程寫入其餘同group的節點)。這種方式,犧牲了C來保證A,即沒法保證數據是否更新成功,還有可能會因爲網絡故障等緣由,致使數據不一致。
3)折衷:更新部分節點成功後便返回。blog
3、分片同步
相比於單實例,這裏多了一個節點去分割數據。
因爲全部數據只有一份,一致性得以保證;節點間不須要通訊,分區容忍性也有。
然而,當任意一個節點掛掉,丟失了一部分的數據,系統可用性得不到保證。it
綜上,這和單機版的方案同樣,都只能保證CP。
那麼,有哪些好處呢?
1)某個節點掛掉只會影響部分服務,即服務降級;
2)因爲分片了數據,能夠均衡負載;
3)數據量增大/減少後能夠相應的擴容/縮容。
大多數的數據庫服務都提供了分片的功能。如Redis的slots,Cassandra的patitions,MongoDB的shards等。
基於分片解決了數據量大的問題,但是咱們仍是但願咱們的系統是高可用的,那麼,如何犧牲必定的一致性去保證可用性呢?
4、集羣
能夠看到,上面這種方式綜合了前兩種方式。同上分析,採用不一樣的數據同步策略,系統CAP保證各有不一樣。不過,通常數據庫系統都會提供可選的配置,咱們根據不一樣的場景選擇不一樣的特性。
其實,對於大多數的非金融類互聯網公司,要求並不是強一致性,而是可用性和最終一致性的保證。這也是NoSQL流行於互聯網應用的一大緣由,相比於強一致性系統的ACID原則,它更加傾向於BASE:
- Basically Available:基本可用性,即容許分區失敗,除了問題僅服務降級;
- Soft-state:軟狀態,即容許異步;
- Eventual Consistency:最終一致性,容許數據最終一致性,而不是時刻一直。
5、總結基本上,上面討論的幾種方式已經涵蓋了大多數的分佈式存儲系統了。其實對於大規模分佈式系統來講,CAP是很是穩固的,能夠擴展的地方也很少。它很大程度上限制了大規模計算的能力,經過一些設計方式來繞過CAP管轄的區域或許是下一步大規模系統設計的關鍵。能夠看到,這些個方案老是須要經過犧牲一部分去換取另外一部分,總無法達到100%的CAP。選擇哪一種方案,依據就是在特定場景下,究竟哪些特性是更加劇要的了。