基本應(yīng)用

在Redis的事務(wù)里面,采用的是樂觀鎖,主要是為了提高性能,減少客戶端的等待。由幾個(gè)命令構(gòu)成:WATCH, UNWATCH, MULTI, EXEC, DISCARD。
通過WATCH,可以實(shí)現(xiàn)CAS操作。使用WATCH監(jiān)聽一些鍵,然后去檢查鍵的值,然后根據(jù)鍵的值來決定是否還需要進(jìn)行MULTI,如果鍵的值被改了,則重新。(因?yàn)橛锌赡茉趫?zhí)行WATCH前,鍵的值被改了,所以需要先WATCH,然后再作判斷)。在執(zhí)行MULTI命令后,如果中途W(wǎng)ATCH的鍵的值被修改了,后續(xù)再執(zhí)行EXEC時(shí),整個(gè)事務(wù)都會(huì)被終止。

CAS使用示例:
假設(shè)存在一個(gè)String類型的狀態(tài)值,state,需要對(duì)其進(jìn)行CAS操作:

   WATCH state
   value  = GET state;   if value == 1
       UNWATCH state       Return false;
   MULTI   SET state 1
   result = EXEC   if result == success       return true;   return false;

原理

Redis事務(wù)實(shí)現(xiàn)原理

通過上述的基本應(yīng)用可以知道,Redis是通過WATCH命令,來保證當(dāng)前事務(wù)的數(shù)據(jù)是否被修改過,如果被修改了,則整個(gè)事務(wù)會(huì)中止,不再執(zhí)行。那么,Redis在實(shí)現(xiàn)的時(shí)候,會(huì)保存對(duì)應(yīng)的watch key,然后中途如果該Key被修改了,則會(huì)將對(duì)應(yīng)的所有客戶端的標(biāo)志位都置為CLIENT_DIRTY_CAS,表示數(shù)據(jù)被修改,后續(xù)執(zhí)行EXEC的時(shí)候則會(huì)被中斷,從而實(shí)現(xiàn)事務(wù)。而UNWATCH命令則是從保存的watch_keys里面移除。MULTI命令僅僅將客戶端的標(biāo)志位flags置為CLIENT_MULTI,表示處于MULTI狀態(tài),該狀態(tài)下,后續(xù)的命令(除了MULTI/WATCH/DISCARD/EXEC)外,其它命令都會(huì)被保存到一個(gè)列表里面,直到EXEC或者DISCARD命令執(zhí)行。如果中途出現(xiàn)了語法錯(cuò)誤之類的命令,則會(huì)將flags置為CLIENT_DIRTY_EXEC。后續(xù)執(zhí)行EXEC時(shí),如果flags存在CLIENT_DIRTY_CAS或者CLIENT_DIRTY_EXEC,則整個(gè)事務(wù)會(huì)被中止,不執(zhí)行任何命令。

ACID分析

針對(duì)Redis的事務(wù)實(shí)現(xiàn),對(duì)于ACID,個(gè)人認(rèn)為,對(duì)于Atomicity和Durability以及Consistency,Redis是不滿足的。為什么會(huì)對(duì)ACID進(jìn)行分析呢,一部分原因是為了作對(duì)比學(xué)習(xí),另一部分是因?yàn)椤禦edis設(shè)計(jì)與實(shí)現(xiàn)》19章事務(wù)ACID性質(zhì)里面提到了一些觀點(diǎn),個(gè)人不太認(rèn)同,所以進(jìn)行了一些對(duì)比。

  1. Atomicity
    指的是要么不執(zhí)行,要么全部執(zhí)行。當(dāng)其中一部分執(zhí)行了,但是另外一部分沒有執(zhí)行,那么作為整個(gè)事務(wù),是全部要回滾,都不執(zhí)行的,而Redis在執(zhí)行過程中,如果出現(xiàn)操作和類型不一致,則會(huì)導(dǎo)致一部分執(zhí)行,而一部分錯(cuò)誤的情況,即不滿足原子性。當(dāng)然,除去部分失誤外,還是能夠保證原子性的,但是這并不是嚴(yán)格的原子性要求。

  2. Durability
    持久性,事務(wù)提交后,無論出現(xiàn)任何情況,包括系統(tǒng)斷電之類的,重啟后都是可以恢復(fù)的。對(duì)于Redis來說,即使開啟了AOF以及設(shè)置為always,也存在命令執(zhí)行一部分后,系統(tǒng)宕機(jī)而導(dǎo)致數(shù)據(jù)不一致的情況,不能恢復(fù)。一般都是通過write-ahead-logging來實(shí)現(xiàn)的,即事先寫日志,而Redis是邊執(zhí)行邊寫日志。

  3. Consistency

    網(wǎng)友評(píng)論