理解數(shù)據(jù)庫(kù)的事務(wù),ACID,CAP和一致性

什么是事務(wù)

事務(wù)是指由一系列數(shù)據(jù)庫(kù)操作組成的一個(gè)完整的邏輯過(guò)程,這個(gè)過(guò)程中的所有操作要么都成功,要么都不成功。比如:常見(jiàn)的例子就是銀行轉(zhuǎn)賬的例子,一次轉(zhuǎn)賬操作會(huì)包含多個(gè)數(shù)據(jù)庫(kù)操作,而這些數(shù)據(jù)庫(kù)操作需要放到一個(gè)事務(wù)當(dāng)中,保證其要么都成功,要么都不成功。

什么是ACID

ACID是事務(wù)的四個(gè)特性,指的是atomicity,原子性;consistency,一致性;isolation,隔離性;durability,持久性。

  1. 原子性(atomicity): 指所有在事務(wù)中的操作要么都成功,要么都不成功,所有的操作都不可分割,沒(méi)有中間狀態(tài)。一旦某一步執(zhí)行失敗,就會(huì)全部回滾到初始狀態(tài)。
  2. 一致性(consistency): 指的是邏輯上的一致性,即所有操作是符合現(xiàn)實(shí)當(dāng)中的期望的。具體參考下一節(jié)
  3. 隔離性(isolation): 即不同事務(wù)之間的相互影響和隔離的程度。比如,不同的隔離級(jí)別,事務(wù)的并發(fā)程度也不同,最強(qiáng)的隔離狀態(tài)是所有的事務(wù)都是串行化的(serializable)(即一個(gè)事務(wù)完成之后才能進(jìn)行下一個(gè)事務(wù)),這樣并發(fā)性也會(huì)降到最低,在保證了強(qiáng)一致性的情況下,性能也會(huì)受很大影響,所以在實(shí)際工程當(dāng)中,往往會(huì)折中一下。
  4. 持久性(durability): 可以簡(jiǎn)單地理解為事務(wù)執(zhí)行完畢后數(shù)據(jù)不可逆并持久化存儲(chǔ)于存儲(chǔ)系統(tǒng)當(dāng)中

理解一致性

實(shí)際上我們通常說(shuō)的數(shù)據(jù)庫(kù)事務(wù)的一致性和分布式系統(tǒng)的一致性并不是一個(gè)概念。這里可以區(qū)分成“內(nèi)部一致性”和“外部一致性”?!皟?nèi)部一致性”搞數(shù)據(jù)庫(kù)的人很少這么說(shuō),一般就直接說(shuō)一致性,更準(zhǔn)確的說(shuō)是“Consistency in ACID”(“事務(wù) ACID 屬性中的一致性”);“外部一致性”是針對(duì)分布式系統(tǒng)而言的,分布式領(lǐng)域提及的 Consistency 表示系統(tǒng)的正確性模型,著名的也是臭名昭著的 CAP 理論中的 C 就是這個(gè)范疇的。這主要是由于分布式系統(tǒng)寫入和讀取都可能不在同一臺(tái)機(jī)器上,而這必然會(huì)有一段時(shí)間導(dǎo)致不同機(jī)器上所存的數(shù)據(jù)不一致的情況,這就是所謂的“不一致時(shí)間窗口”。

內(nèi)部一致性

要理解內(nèi)部一致性也就是我們通常所說(shuō)的ACID中的一致性,就必須從反面考慮什么情況下是不一致的。不一致的情況主要有以下幾種情況:


丟失修改、不可重復(fù)讀、臟讀
  • 修改丟失:丟失修改是事務(wù)A和B先后更改數(shù)據(jù)數(shù)據(jù)x(假設(shè)初始是x0),但是在A未正式更改前,B已經(jīng)讀取了原先的數(shù)據(jù)x0,最后A更改后為x1,B更改的并不是A更新后的x1,而是更改的x0,更改后假設(shè)為x2,這時(shí)x2將x1覆蓋了,相當(dāng)于事務(wù)A針對(duì)x的更改丟失了。
  • 臟讀: 事務(wù)T1讀取了T2更改的x,但是T2在實(shí)際存儲(chǔ)數(shù)據(jù)時(shí)可能出錯(cuò)回滾了,這時(shí)T1讀取的實(shí)際是無(wú)效的數(shù)據(jù),這種情況下就是臟讀
  • 不可重復(fù)讀:是說(shuō)在T1讀取x時(shí),由于中間T2更改了x,所以T1前后兩次讀取的x值不相同,這就是所謂的不可重復(fù)讀
  • 幻讀:在T1讀取符合某個(gè)條件的所有記錄時(shí),T2增加了一條符合該條件的記錄,這就導(dǎo)致T1執(zhí)行過(guò)程中前后讀取的記錄可能不一致,即T2之后讀取時(shí)會(huì)多出一條記錄。

其中前三種(丟失修改、不能重復(fù)讀、臟讀)都是由于并發(fā)事務(wù)在修改同一份數(shù)據(jù)的時(shí)候?qū)е碌膯?wèn)題,此類問(wèn)題可以通過(guò)對(duì)同一個(gè)資源加鎖的方式來(lái)解決,而最后一種情況是由于不同事務(wù)并發(fā)時(shí),新增數(shù)據(jù)導(dǎo)致的問(wèn)題,對(duì)于新增的記錄是無(wú)法加鎖的,此種情況只能通過(guò)事務(wù)的串行化來(lái)解決。而串行化與并發(fā)是矛盾的,所以要在性能和事務(wù)的一致性強(qiáng)度上取得一個(gè)平衡,就涉及到不同的隔離等級(jí),關(guān)于隔離等級(jí),詳見(jiàn)理解隔離性一節(jié)。

外部一致性

在分布式系統(tǒng)中我們所說(shuō)的一致性,也就是外部一致性,通常會(huì)分為強(qiáng)一致性,弱一致性,還有最終一致性,而要理解外部一致性,需要對(duì)CAP理論(Consistency,Availability和Partition Tolerance)有所了解,關(guān)于CAP詳見(jiàn)CAP定理一節(jié)。

  • 強(qiáng)一致性:指系統(tǒng)中的某個(gè)數(shù)據(jù)被成功更新后,后續(xù)任何對(duì)該數(shù)據(jù)的讀取操作都將得到更新后的值
  • 弱一致性:弱一致性是相對(duì)于強(qiáng)一致性而言,它不保證總能得到最新的值;
  • 最終一致性:是弱一致性的特殊形式,即保證在沒(méi)有新的更新的條件下,經(jīng)過(guò)一段“不一致時(shí)間窗口”,最終所有的訪問(wèn)都是最后更新的值。最常見(jiàn)的是DNS服務(wù),更新域名指向的機(jī)器后,多級(jí)緩存要等到expiration time的時(shí)候才會(huì)更新,但是隨著時(shí)間的推移,最終數(shù)據(jù)會(huì)趨于一致。

理解隔離性

事務(wù)的隔離級(jí)別從低到高有
讀未提交(Read uncommitted)、讀提交(read committed)、可重復(fù)讀(repeatable read)和串行化(Serializable)

  • Read Uncommitted:事務(wù)讀數(shù)據(jù)時(shí)不會(huì)加鎖,寫數(shù)據(jù)時(shí)會(huì)有行級(jí)共享鎖。假設(shè)事務(wù)1先于事務(wù)2,當(dāng)事務(wù)1更新數(shù)據(jù)的時(shí)候,事務(wù)2可以讀取事務(wù)1未提交的數(shù)據(jù),但是不能更新事務(wù)1正在更新的數(shù)據(jù)。而如果事務(wù)1只是讀數(shù)據(jù),那么事務(wù)2既可以讀數(shù)據(jù),也可以更新數(shù)據(jù)。
    這種情況下無(wú)法規(guī)避臟讀,不可重復(fù)讀的問(wèn)題。
  • Read Committed:即在一個(gè)事務(wù)修改數(shù)據(jù)過(guò)程中,如果事務(wù)還沒(méi)提交,其他事務(wù)不能讀該數(shù)據(jù),或者說(shuō)只能讀取committed的數(shù)據(jù)。事務(wù)讀數(shù)據(jù)的瞬間會(huì)加行級(jí)共享鎖,一旦讀完該行,立即釋放該行級(jí)共享鎖;而寫數(shù)據(jù)的瞬間會(huì)加行級(jí)排它鎖,直到事務(wù)結(jié)束。這種情況下就避免了臟讀,但是卻不能避免不可重復(fù)讀的問(wèn)題
  • Repeatable Read:當(dāng)然就再升一級(jí),為的就是避免不可重復(fù)讀的問(wèn)題,所以名字叫repeatable read。怎么實(shí)現(xiàn)的呢,我們知道read committed是,事務(wù)讀操作只在讀的一瞬間加鎖,讀完這行就釋放鎖了,而repeatable read級(jí)別是讀的一瞬間加鎖,但是一直到事務(wù)結(jié)束才釋放鎖。但是repeatable read不能解決幻讀的問(wèn)題,因?yàn)榛米x是增加記錄,并不是更改原先的記錄。
  • Serialization:到達(dá)這一級(jí)別的隔離,可以徹底解決一致性的所有問(wèn)題。一般來(lái)說(shuō)是通過(guò)加表鎖來(lái)解決串行化的問(wèn)題。

CAP定理

CAP理論主要是針對(duì)分布式存儲(chǔ)系統(tǒng)的,C是指Consistency一致性,A是指Availability可用性,P是指Partition tolerance分區(qū)容忍性。CAP定理認(rèn)為分布式系統(tǒng)中這三個(gè)特性最多只能同時(shí)滿足兩個(gè)特性。下面我們來(lái)分別看下這三個(gè)特性究竟是什么意思。


CAP
  • 一致性(Consistency): 指在分布式系統(tǒng)中的所有數(shù)據(jù)備份,在同一時(shí)刻是否同樣的值。(等同于所有節(jié)點(diǎn)訪問(wèn)同一份最新的數(shù)據(jù)副本)
  • 可用性(Availability): 在集群中一部分節(jié)點(diǎn)故障后,集群整體是否還能響應(yīng)客戶端的讀寫請(qǐng)求。(對(duì)數(shù)據(jù)更新具備高可用性)
  • 分區(qū)容忍性(Partition tolerance): 即當(dāng)節(jié)點(diǎn)之間無(wú)法正常通信時(shí),就產(chǎn)生了分區(qū),而分區(qū)產(chǎn)生后,依然能夠保證服務(wù)可用,那么我們就說(shuō)系統(tǒng)是分區(qū)容忍的。顯然如果節(jié)點(diǎn)越多,且備份越多,分區(qū)容忍度就越高(因?yàn)榧幢闶瞧渲幸粋€(gè)或多個(gè)節(jié)點(diǎn)掛了,仍然有其它節(jié)點(diǎn)和備份可用)。

那么,為什么說(shuō)三個(gè)特性無(wú)法全部保證呢?首先,假如我們要保證分區(qū)容忍性,必然要做多個(gè)副本節(jié)點(diǎn),而這必然會(huì)帶來(lái)一致性的問(wèn)題,即保證多個(gè)節(jié)點(diǎn)的數(shù)據(jù)是相同的,但是,要讓多個(gè)節(jié)點(diǎn)數(shù)據(jù)相同,就必須要花時(shí)間去復(fù)制數(shù)據(jù),這還是能夠正常通信的情況下,那么在數(shù)據(jù)復(fù)制的過(guò)程中為了保持一致性,就不能對(duì)外提供服務(wù),所以這段時(shí)間就無(wú)法滿足可用性的問(wèn)題。
實(shí)際工程通常會(huì)采取一些折中措施,比如并不保證強(qiáng)一致性,只保證最終一致性,什么意思呢?比如,有三個(gè)數(shù)據(jù)節(jié)點(diǎn)互為備份,某份數(shù)據(jù)在節(jié)點(diǎn)A更改后,需要將更改復(fù)制到節(jié)點(diǎn)B和C,假設(shè)復(fù)制過(guò)程中,有客戶訪問(wèn)該數(shù)據(jù),那么此時(shí)不保證是一致的,即訪問(wèn)A節(jié)點(diǎn)的用戶得到的是最新數(shù)據(jù),而訪問(wèn)B和C節(jié)點(diǎn)的用戶得到是老數(shù)據(jù),但是最終,數(shù)據(jù)會(huì)復(fù)制完成,所以最終A、B、C三個(gè)節(jié)點(diǎn)的數(shù)據(jù)是一致的。(比如像文章點(diǎn)贊這種數(shù)據(jù),延遲下也沒(méi)有關(guān)系啦)

Reference

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容