MVCC/分佈式事務簡介

以前咱們學習了RocksDB,但這還只是一個最基礎的存儲引擎。若是想把它在生產環境中用起來,還須要解決不少問題:html

  • 如何從單機擴展到分佈式?
  • 如何實現事務,並對事務進行併發控制?
  • 用戶接口能不能高級一點?不要只有get/set?

此次咱們就來解決這三個問題。git

 

如何從單機擴展到分佈式

分佈式的一大意義就是把單機放不下的數據分散到多個節點上。咱們不妨按照key將不一樣範圍的key分紅多個region:好比[a-c]是region1,[d-f]是region2。而後用這種方法存儲:github

這樣實現了一個基本的load balancing。一個Region裏全部的數據分散存儲在多個replica上,每一個實例只會存一部分的region。固然分佈式以後咱們是要支持節點的動態增減的,具體細節暫時忽略數據庫

分佈式以後還有一個重要的問題就是如何保證多個節點的一致性。還記得paxos嘛?就用它了!固然用Raft也可併發

 

 

 

 

如何實現事務,並對事務進行併發控制?

事務是數據庫系統中一個很重要的概念。好比咱們的數據庫要拿給銀行去用,而後銀行要把帳戶A的100塊錢轉給帳戶B,就須要執行以下操做:mvc

if (A.balance>=100){
    A.balance-=100;
    B.balance+=100;
    return(DB_OK);
}
else{
    return(DB_ERROR);
}

固然在數據庫系統中事務是用SQL實現的。分佈式

在事務的執行過程當中,整段事務須要保證要麼全都不執行,要麼全都執行完,不容許出現執行到一半退出了的狀況(即應該是個原子操做)。除此以外,像這樣的約束條件還有不少,整理起來就是事務的ACID特性性能

爲了保證事務的執行能知足ACID特性,咱們能夠把事務的執行抽象成兩種操做:commit(執行完整個事務)和rollback(好比事務跑到一半數據庫崩潰了,重啓後就要撤銷以前執行到一半的工做,恢復到事務沒執行的狀態)。commit的實現很顯然,直接執行就完事了......而爲了實現rollback能夠給數據庫加上日誌恢復技術,這樣就能夠恢復到過去的時間點了。學習

MVCCatom

若是事務是串行執行的,那麼到這裏差很少就能夠了。但假設咱們的數據庫要拿去進行雙十一秒殺,就須要支持多個事務的併發運行,這時候就須要進行併發控制。在數據庫課本上咱們學習過一些簡單的併發控制模型和實現方法(如基本的加鎖解鎖、2pc)。但咱們知道,一次事務執行時被加鎖的資源越多,整個db的並行度就越低。簡單的方法就無法保證用戶能流暢的秒殺了......那麼如何使得並行度儘量高呢?MYSQL中使用了MVCC模型,這裏咱們也比葫蘆畫瓢用一下。

併發控制的做用就是防止出現併發一致性問題。還記得5105課上學過在Client-centric consistency models中,多個client對同一資源進行讀寫的幾個模型嗎(Monotonic-Read、Monotonic-write、Read your write、Write follow reads)?在5105課上咱們學習了爲了保證最終一致性,這些操做應該怎麼執行、怎麼加鎖。這個思路放到數據庫的併發控制中一樣適用。

MVCC是一種多版本併發控制機制。MVCC能夠在大多數狀況下代替行級鎖,下降系統開銷。
MVCC的本質就是copy on write,可以作到寫不阻塞讀MVCC可以作到寫讀不衝突,讀讀不衝突,讀寫也不衝突,惟一衝突的就是寫和寫,這樣系統併發讀就能夠很是高。MVCC 提供了時點(point in time)一致性視圖。MVCC 併發控制下的讀事務通常使用時間戳或者事務 ID去標記當前讀的數據庫的狀態(版本),讀取這個版本的數據。讀、寫事務相互隔離,不須要加鎖。讀寫並存的時候,寫操做會根據目前數據庫的狀態,建立一個新版本,併發的讀則依舊訪問舊版本的數據。一句話講,MVCC就是用同一份數據臨時保留多版本的方式 ,實現併發控制。MYSQL的併發控制就是用MVCC實現的。

那麼怎麼把MVCC用到咱們的kv數據庫中呢?咱們能夠給key-value鍵值對也加上timestamp。而後在運行的過程當中,遵守如下規則:

  • All modifies are adding a new version.
  • The same row(就是同一個key-value鍵值對) may have multiple versions.
  • Old versions dropped by GC.

在分佈式併發事務的具體實現中,會用到一個Percolator Transaction Model。它是來自Google的一篇paper。Percolator的設計是爲了解決2pc在分佈式環境中的一些問題,至關因而2pc的加強版。用於在保證分佈式一致性的基礎上保證事務執行的ACID特性。

Percolator:分佈式併發事務的實現

rocksdb提供了Column Families (CF) 特性,能夠用來實現上面的Percolator事務模型。CF是對數據庫作的一個logical partition,能夠類比關係數據庫中的視圖,但比視圖支持更多的高級功能:

  • Atomic writes across Column Families are supported. This means you can atomically execute Write({cf1, key1, value1}, {cf2, key2, value2}).
  • Consistent view of the database across Column Families.
  • Ability to configure different Column Families independently.
  • On-the-fly adding new Column Families and dropping them. Both operations are reasonably fast.

爲了實現Percolator事務模型,好比咱們能夠設置以下三個CF:

  • DefaultCF:存儲數據
  • WriteCF:存儲已提交的事務commit時的timestamp
  • LockCF:存儲正在執行,還未提交的事務產生的鎖

好比一開始咱們有一個用來存儲帳戶存款的key-value數據庫,咱們能夠這樣給它擴展成三個CF:

Percolator的核心就是2pc的改進版。經過利用client做爲協調者,解決了協調者掛了對總體服務能力的影響,而在事務相關信息的一致性和持久性上充分利用了BigTable的簡單事務支持以及GFS的多副本可靠性能力,另外Percolator在數據模型上是mvcc。

好比咱們要執行一個事務,把Bob的7塊錢轉給Joe。使用Percolator執行事務的過程以下:

1111111

使用Percolator模型實現MVCC

 

 

 

 


 

Ref:

MVCC

http://www.javashuo.com/article/p-efjbfsjq-de.html

http://www.javashuo.com/article/p-xzozrljn-bq.html

 

分佈式事務

http://www.javashuo.com/article/p-zhgmwhrn-hh.html

https://blog.csdn.net/maxlovezyy/article/details/88572692

https://blog.csdn.net/u013045749/article/details/50855823

https://xiking.win/2018/06/22/percolator-paper/

https://github.com/pingcap/blog/blob/master/2016-11-17-mvcc-in-tikv.md

http://int64.me/2017/MVCC%20In%20TiKV.html

https://andremouche.github.io/tidb/transaction_in_tidb.html

https://dzone.com/articles/how-to-do-performance-tuning-on-tidb-a-distributed

相關文章
相關標籤/搜索