前言
最近留意到了一款優(yōu)秀的國(guó)產(chǎn)數(shù)據(jù)庫(kù)tidb
金刁,研究了一下他們實(shí)現(xiàn)的分布式事務(wù)织咧,屬于二段提交(2PC)胀葱。tidb
借鑒了 google 用于實(shí)現(xiàn) big table 的分布式事務(wù)實(shí)踐 Percolator 。下面會(huì)講一下分布式事務(wù)的樂觀和悲觀鎖抵屿。
悲觀 or 樂觀庆锦?
拿去餐廳用餐等位置的經(jīng)歷來舉例
樂觀者
這個(gè)時(shí)候餐廳應(yīng)該不會(huì)很多人吧轧葛?我去先去看看排的隊(duì)長(zhǎng)不長(zhǎng)搂抒,長(zhǎng)我就先回家等等,不長(zhǎng)我就去用餐了求晶。
悲觀者
這個(gè)時(shí)候餐廳應(yīng)該會(huì)很多人吧?我先打個(gè)電話預(yù)約一下餐桌衷笋,免得到時(shí)候人多白跑一趟。
分析
不難發(fā)現(xiàn)辟宗,樂觀者會(huì)先假設(shè)餐廳是相對(duì)空閑的一個(gè)狀態(tài)爵赵,避免了占用資源但是暫時(shí)不使用的浪費(fèi)資源現(xiàn)象泊脐。而悲觀者會(huì)基于資源是相對(duì)繁忙的一個(gè)情況空幻,會(huì)先對(duì)資源進(jìn)行預(yù)約占用(上鎖)。
樂觀事務(wù)
下面來講一下樂觀事務(wù)的事務(wù)流程秕铛。在事務(wù)提交之前,會(huì)先把數(shù)據(jù)的 update/delete 操作緩存到內(nèi)存缩挑。然后大體分為兩個(gè)步驟完成事務(wù)提交。
Prewrite
把需要修改的 key 分為兩部分:隨機(jī)1個(gè) primary 调煎、其他作為 secondaries 镜遣。
- 首先把 primary 上鎖士袄,會(huì)有兩種情況上鎖失敱亍:
- key 已經(jīng)被上鎖
- 在本次事務(wù)開始時(shí)間戳(startTs)后娄柳,已經(jīng)有過寫操作寓辱,此處稱為沖突(Conflict)。
- 把 secondaries 用 primary key 類似的上鎖方法上鎖
Commit
Prewrite 完成之后秫筏,需要開始進(jìn)行提交操作诱鞠。
- 提交 primary key:寫入數(shù)據(jù)这敬,記錄事務(wù)提交時(shí)間戳(commitTs)航夺。
- 解開 primary key 的鎖
- 異步進(jìn)行提交 secondaries key 操作。
重試
由于在 Prewrite 階段有可能會(huì)產(chǎn)生失敗阳掐,失敗就會(huì)產(chǎn)生回滾和重試。在一些大事務(wù)當(dāng)中冷蚂,沖突率有可能非常高,導(dǎo)致頻繁重試蝙茶。此時(shí)需要引入悲觀事務(wù)艺骂。
悲觀事務(wù)
悲觀鎖事務(wù)其實(shí)整體流程都非常類似樂觀鎖事務(wù)隆夯。不同的是钳恕,把 prewrite 階段的鎖,提前到客戶端開啟事務(wù)中的DML語句當(dāng)中苞尝。
版權(quán)聲明
本文版權(quán)歸作者所有,請(qǐng)勿私自轉(zhuǎn)載文章宦芦,感謝!