騰訊云域名價格seo神器
分布式事務的問題可以分為兩部分:
- 并發(fā)控制 concurrency control
- 原子提交 atomic commit
分布式事務問題的產(chǎn)生場景:一份數(shù)據(jù)被分片存在多臺服務器上,那么每次事務處理都涉及到了多臺機器。
可序列化(并發(fā)控制):
- 定義了事務執(zhí)行的正確性
- 真正地并行執(zhí)行事務,獲得真正的并行速度提升。 如果事務涉及到的數(shù)據(jù)不在同一臺機器上,那么可以同時在多臺機器上讀需要的數(shù)據(jù)。
原子提交:
處理在事務過程中服務器宕機的情況。如果事務執(zhí)行過程中修改了部分值,然后機器宕機,需要能夠具有故障恢復的能力。
一、并發(fā)控制
- 悲觀并發(fā)控制。 沖突頻繁比較適合,避免頻繁abort事務。
- 樂觀并發(fā)控制。事務最后的時候,再檢查有無其它的事務干擾,如果有其它事務干擾,那么必須Abort當前事務。
2PL (Strongly 2PL)
規(guī)則:1. 使用任何數(shù)據(jù)之前,在執(zhí)行任何數(shù)據(jù)的讀寫之前,先獲取鎖。
- 事務必須持有任何已經(jīng)獲得的鎖,直到事務提交或abort(這是嚴格2PL…)
規(guī)則2的例子:
不能在結(jié)束了對x的操作以后就立即釋放鎖,比如說:
t1: ① ④ t2: ② ③, 這個鎖無用了,還是會導致事務交叉執(zhí)行。
同時,2PL也無法解決死鎖,簡單例子如下:
二、原子提交
原子提交協(xié)議需要保證:事務的每一個部分都執(zhí)行,或者任何一個部分都不執(zhí)行。All-or-nothing
需要有一個計算機管理事務(事務協(xié)調(diào)者,Transaction Coordinator, TC)
2PC正常情況:
如果B在回復prepare yes之前崩潰: TC會發(fā)現(xiàn)B沒有回復yes,也就不能commit,因為它需要等待所有參與者回復yes
同時,B如果發(fā)現(xiàn)自己故障,可以主動發(fā)起abort。 有一種情況,B故障,內(nèi)存中數(shù)據(jù)丟失,所以再次接受prepare的時候,完全不知道參與了該次事務,因此直接發(fā)送No
如果B在發(fā)出prepare yes之后崩潰:
接下來極有可能發(fā)生的事情是,事務協(xié)調(diào)者從所有的參與者獲得了Yes的回復,并將Commit消息發(fā)送給了A,所以A實際上會執(zhí)行事務分包給它的那一部分,持久化存儲結(jié)果,并釋放鎖。這樣的話,為了確保All-or-Nothing原子性,我們需要確保B在故障恢復之后,仍然能完成事務分包給它的那一部分。在B故障的時候,不知道事務是否能Commit,因為它還沒有收到Commit消息。但是B還是需要做好Commit的準備:
這要求參與者B在prepare時候必須持久化一些狀態(tài),比如說記住所有的修改和事務持有的鎖 (這些其實都以log的形式存在)然后才會回復yes
這樣,如果B在發(fā)送完prepare yes后就崩潰,那么恢復的時候可以查看自己的log。之后,B最終收到了commit,那么就可以完成它在事務中的那部分工作。
如果B在發(fā)出commit ok之后崩潰:此時B已經(jīng)完成修改,數(shù)據(jù)以及持久化到磁盤上了,故障重啟之后不需要做任何事情。
如果事務協(xié)調(diào)者在發(fā)送commit之前崩潰:那么沒有一個參與者會commit事務
如果事務協(xié)調(diào)者在發(fā)送完一個或多個commit消息后崩潰:要重發(fā),可以看Log來確定進展狀況。
既然已經(jīng)發(fā)送了,就不允許TC忘記相關(guān)的事務。這要求TC在發(fā)送任何commit之前,都必須先將事務信息寫入持久化存儲中。重啟后可以看到哪些事務執(zhí)行了一般,哪些事務commit,哪些事務abort,對于執(zhí)行了一半的事務,事務協(xié)調(diào)者會向所有的參與者重發(fā)Commit消息或者Abort消息,以防在崩潰前沒有向參與者發(fā)送這些消息。這也是為什么參與者需要準備好接收重復commit消息的原因。
TC發(fā)送prepare卻沒有收到所有回復?
- 重發(fā)
- 決定abort
發(fā)送commit卻沒有收到所有回復?
- block。 只能block,因為其他的參與者可能已經(jīng)回復ok并提交事務
TC獲得了所有的ack,此時TC可以刪除Log中有關(guān)事務的信息;參與者發(fā)送ack之后也可以刪除log(忘記這個事務…)
然后問題就來了,這個ack丟失了咋辦。那此時TC會再次發(fā)送commit消息,參與者收到后發(fā)現(xiàn)自己不知道這個事務,但因為這是一個commit消息,說明自己一定是發(fā)送了ack后把log刪除了,因此此時參與者會再次發(fā)送ack。
三、總結(jié)
2PC的性能
- 由于有多輪消息,非常慢
- 由于存在Block,很慢。
與Raft對比
Raft目標高可用,而2PC并不是高可用的。原因在于,Raft中的每臺機器做一樣的事情;而2PC中的機器在做不一樣的事情(為了完成一個事務)
Raft+2PL實現(xiàn)高可用+ 分布式事務 原子提交?