CAP 定理是分布式系統(tǒng)理論的基礎,它的核心內容是說,在存在分區(qū)(如網(wǎng)絡故障)的情況下,一個系統(tǒng)無法同時保證一致性(consistency)和可用性(availability),只能二選其一。
有些數(shù)據(jù)庫選擇了一致性,那么這類系統(tǒng)就被稱為 CP 系統(tǒng)。而有些系統(tǒng)更看重可用性,也就是 AP 系統(tǒng)。一致性和可用性對于任何一個業(yè)務系統(tǒng)來說都是至關重要的,如何在這兩者之間做出選擇也就變成一個大難題。
這篇文章將說明如何在保證系統(tǒng)一致性的同時仍然能夠保證高可用性,并以 CockroachDB 為例來解釋 CAP 定理,以及為什么對于大多數(shù)數(shù)據(jù)庫來說一致性更重要。
高可用性
在 CAP 定理里,可用性具有嚴格的二元性:一個系統(tǒng)要么可用,要么不可用。但在服務級別協(xié)議(SLA)里,可用性具有連續(xù)性。
例如,一個系統(tǒng)可以保證99.99%的可用性(4個9,也就是說每年允許宕機的時間不超過一個小時)。100%的可用性是不現(xiàn)實的。工程上的高可用性要求對各種中斷的嚴重程度進行評估,并在降低故障率所要花費的成本上做出平衡。
一個具有一致性保證的系統(tǒng)有時候因為網(wǎng)絡分區(qū)出現(xiàn)不可用,但即使是具有可用性保證的系統(tǒng),也會因為各種原因出現(xiàn)不可用。在一個良好的網(wǎng)絡環(huán)境里,因網(wǎng)絡分區(qū)造成的故障不會比其他類型的故障更常見。既然故障是不可避免的,進而導致不可用,那為什么不先保證一致性呢?
Brewer 博士說 Google 的網(wǎng)絡很少會出現(xiàn)分區(qū),Spanner 數(shù)據(jù)庫理論上是“CP”,但實際上幾乎是“CA”的。這聽起來有點跑題了,不過卻也說明了在可用性方面做出一些權衡,其影響面不會太大。
合理的權衡
在分布式系統(tǒng)里,權衡無處不在,我們總是要在一致性、可用性、性能和靈活性之間做出權衡。而 CAP 定理將選擇的范圍縮小到一致性和可用性之間,但無法涵蓋所有可能造成不可用的問題根源。
有各種原因可能造成系統(tǒng)中斷,比如硬件單點故障、應用程序的缺陷或運維人員的人為錯誤。而從整個系統(tǒng)層面來看,如果能夠處理好網(wǎng)絡分區(qū)問題,那么就有可能在不犧牲一致性的前提下提升可用性。CAP 的可用性不一定會帶來實質性的可用性保證,但如果犧牲了一致性,將會給應用程序的代碼帶來復雜性,也意味著更高的工程成本。
假設有一個應用程序,它部署在3個數(shù)據(jù)中心里,客戶端的流量經(jīng)過負載均衡器連接到應用程序上。如果其中的一個數(shù)據(jù)中心因網(wǎng)絡故障掉線,那么連接到這個數(shù)據(jù)中心的客戶端將會遭遇中斷,而不管底層的數(shù)據(jù)庫是 CP 還是 CA 的。而如果負載均衡器將這些中斷的客戶端流量重定向到活躍的數(shù)據(jù)中心,不管底層的數(shù)據(jù)庫如何處理網(wǎng)絡分區(qū)問題,服務仍然可用。
只有當數(shù)據(jù)中心復本之間無法通信而客戶端仍然能夠與各個數(shù)據(jù)中心對話時,AP 系統(tǒng)仍然可用,而 CP 系統(tǒng)不可用。如果把整個系統(tǒng)作為整體部署來考慮,可以不用遵循 CAP 定理所要求的需要每個節(jié)點都要返回響應的原則,從而達到高可用性。
如果 AP 系統(tǒng)所能帶來的可用性價值不高,那么為什么要為此犧牲一致性呢?理由只有一個,因為寫入延遲。一致性系統(tǒng)在執(zhí)行寫入操作的時候需要協(xié)調各個節(jié)點來保證一致性(當然,有些系統(tǒng)對一致性讀也有很高要求)。非一致性系統(tǒng)允許丟失數(shù)據(jù),所以可以很快返回響應。對于速度比健壯性更重要的系統(tǒng)來說,或許這會是更好的選擇。
CockroachDB 的 CAP
CockroachDB是 CP 系統(tǒng):每一份數(shù)據(jù)至少有3個復本,在寫入數(shù)據(jù)時要求每個復本之間進行通信。在數(shù)據(jù)讀取方面,其中的一個復本被授予一段時間的租期或一個數(shù)據(jù)子集的臨時所有權,這個復本可以在不與其他復本通信的情況下處理讀取請求。如果這個復本與其他復本失去聯(lián)系,在租期內(默認是9秒鐘)它仍然能夠提供讀取數(shù)據(jù)服務(但不能寫入)。在租約到期之后,另外兩個復本中的一個會得到新的租約。這樣可以確保系統(tǒng)能夠快速地從中斷中恢復,提供最高的可用性,盡管它不符合 CAP 定理對可用性的定義。
CockroachDB的強一致性基因讓它有可能為分布式數(shù)據(jù)庫提供與傳統(tǒng)的非分布式數(shù)據(jù)庫一樣的一致性保證,同時保持高可用。對于大多數(shù)應用程序來說,CP 數(shù)據(jù)庫會是更好的選擇,盡管存在潛在的延遲,但它也為開發(fā)者提供了一些保證。
大部分最近的寫入對后續(xù)的讀取是可見的。其他開發(fā)人員無法破壞應用整體的一致性。發(fā)生分區(qū)事件時,系統(tǒng)會阻塞,而不是返回不完整的數(shù)據(jù)。