CAP理論是分佈式系統構建中的基礎理論之一,其中的C(Consistency),一致性即指全部的節點都能訪問同一份最新的數據副本、A(Availability),可用性即指每一個請求都能接收到一個響應,而P(Partition Tolerance),分區容忍性即指除了整個網絡的故障外,其餘的故障(集)都不能致使整個系統沒法正確響應。CAP理論的核心便是一個分佈式系統不可能同時很好的知足一致性,可用性和分區容錯性這三個需求,最多隻能同時較好的知足兩個。在筆者剛纔描述的服務端應用程序構建的場景中,一樣能夠用相似於CAP理論的方式進行描述。github
Partition Tolerance:在上文的描述中,咱們業務系統構建的一個目標是在乾淨整潔的代碼的基礎上提供靈活多變的接口,這就好像飯店同樣,若是咱們爲Consumer提供了一盤作好的黃燜雞米飯,Consumer是很難再把它變成炒雞雜。而若是咱們提供的是原料食材,那麼Consumer想作成什麼均可以。封裝程度越高的Service/API的可重用性與可組合性越低。筆者在上文說起,任何一個複雜的應用程序皆能夠表示爲簡單的CURD操做的排列組合,而若是咱們的Service層或者API層只提供最基本的,即粒度最小的操做,那麼Controller層或者Consumer的自由組合的能力也就越強,整個應用系統的靈活性與可變性也就越高。總結而言,Partition Tolerance便是衡量一個服務端應用系統能夠提供對外的API的粒度,粒度越低表明着分割容忍性越好。最極端的狀況便是Server只提供最基本的CRUD操做,就好像只是對於數據庫作了簡單的封裝。數據庫
Consistency:直觀的說,若是咱們以保證靈活性、可變性爲目標,勢必會減小對於數據庫鏈接操做的使用。換言之,本來一條SQL語句鏈接查詢得到的內容變成了執行兩次SQL語句,這就致使了可能在兩次查詢的間隙數據已經發生了變化,最終致使返回給Consumer的數據存在不一致性。編程
Availability:在Server中,可用性即指某個API的性能,或者說是響應時間。若是要保證分割容忍性,勢必會將本來能夠一次執行的SQL語句分爲屢次,致使查詢效率急劇降低,也就致使了可用性受到影響。而若是要保證一致性,那麼可使用事務的方式,一樣會致使可用性的減少。緩存
目前絕大部分的Server端的實現都是以CA爲目標,即犧牲了分割容忍性,保證強一致性與可用性,這也是ACID理論的表現。不少狀況下咱們會發生某個API其實只是執行了某條及其複雜的SQL語句,該SQL語句可能鏈接查詢了十幾張表而且返回數據。這也就致使了API的可變性極差,你要修改API返回的某個字段也就意味着要修改最底層被執行的那個SQL語句,等於從新構建了一個新的API。若是咱們的系統目標是保證CP,即犧牲可用性。那麼咱們能夠引入事務或者鎖,即在一個Session的屢次查詢中鎖定全表,從而保證返回數據的一致性。若是咱們的系統目標是保證PA,即犧牲一致性,那麼最好的方式就是引入緩存機制,能夠設置在固定時間或者事件觸發的狀況下再進行真實查詢操做,其餘狀況下能夠從緩存中獲取數據,這樣就可以較好地保證用戶的響應時間。網絡
隨着分佈式系統的發展,eBay工程師提出大規模分佈式系統的實踐總結,在ACM上發表文章提出 Bash 理論是基本可用、軟狀態和最終一致性。不要求實時一致性,但必定要實現最後一點。筆者目前秉持的在Server端的開發過程當中也是遵循BASE理論,這在下面會有詳細介紹,這裏仍是闡述下BASE的內涵:分佈式
基本可用(Basically Available)。分佈式系統在故障時容許損失可用性,保證核心業務可用。音頻直播或是作活動時,當業務量很是大的時候能夠降級。作遊戲也是,在戰鬥的時候最關心數值的增加,看了多少人都無所謂,緩解核心內容的壓力。性能
軟狀態(Soft State)。容許系統中出現的中間狀態,中間狀態不會耽誤可用性。在寫代碼、編程業務的設計上,必須容忍有必定的臨時數據同步,考慮到全局鎖和數據多版本的對比,把各個節點的相關數據都上鎖,這是一個悲觀鎖,一旦寫任務,其餘人都能改個人數據,這是比較悲觀的心態。spa