MVCC (Multiversion Concurrency Control),即多版本并發(fā)控制技術(shù),它使得大部分支持行鎖的事務(wù)引擎,不再單純的使用行鎖來進(jìn)行數(shù)據(jù)庫的并發(fā)控制,取而代之的是,把數(shù)據(jù)庫的行鎖與行的多個版本結(jié)合起來,只需要很小的開銷,就可以實現(xiàn)非鎖定讀,從而大大提高
MVCC (Multiversion Concurrency Control),即多版本并發(fā)控制技術(shù),它使得大部分支持行鎖的事務(wù)引擎,不再單純的使用行鎖來進(jìn)行數(shù)據(jù)庫的并發(fā)控制,取而代之的是,把數(shù)據(jù)庫的行鎖與行的多個版本結(jié)合起來,只需要很小的開銷,就可以實現(xiàn)非鎖定讀,從而大大提高數(shù)據(jù)庫系統(tǒng)的并發(fā)性能。
HBase正是通過行鎖+MVCC保證了高效的并發(fā)讀寫。
HBase系統(tǒng)本身只能保證單行的ACID特性。ACID的含義是:
傳統(tǒng)的關(guān)系型數(shù)據(jù)庫一般都提供了跨越所有數(shù)據(jù)的ACID特性;為了性能考慮,HBase只提供了基于單行的ACID。
下面是一個hbase并發(fā)寫的例子。
原始數(shù)據(jù)如下
從Apache HBase Write Path一文可以知道hbase寫數(shù)據(jù)是分為兩步:
1. 寫Write-Ahead-Log(WAL)文件
2. 寫MemStore:將每個cell[(row,column)對]的數(shù)據(jù)寫到內(nèi)存中的memstore
假定對寫沒有采取并發(fā)控制,并考慮以下的順序:
最終得到的結(jié)果是:
這樣就得到了不一致的結(jié)果。顯然我們需要對并發(fā)寫操作進(jìn)行同步。
最簡單的方式是提供一個基于行的獨(dú)占鎖來保證對同一行寫的性。所以寫的順序是:
盡管對并發(fā)寫加了鎖,但是對于讀呢?見下面的例子:
如果在上面的圖中紅線所示的地方進(jìn)行讀操作,最終得到的結(jié)果是:
可見需要對讀和寫也進(jìn)行并發(fā)控制,不然會得到不一致的數(shù)據(jù)。最簡單的方案就是讀和寫公用一把鎖。這樣雖然保證了ACID特性,但是讀寫操作同時搶占鎖會互相影響各自的性能。
HBase采用了MVCC算法來避免讀操作去獲取行鎖。
對于寫操作:
對于讀操作:
在采用MVCC后的數(shù)據(jù)執(zhí)行圖:
注意到采用MVCC算法后,每一次寫操作都有一個寫序號(即w1步),每個cell數(shù)據(jù)寫memstore操作都有一個寫序號(w2,例如:“Cloudera [wn=1]”)),并且每次寫操作完成也是基于這個寫序號(w3)。
如果在“Restaurant [wn=2]” 這步之后,“Waiter [wn=2]”這步之前,開始一個讀操作。根據(jù)規(guī)則r1和r2,讀的序號為1。根據(jù)規(guī)則3,讀操作以序號1讀到的值是:
這樣就實現(xiàn)了以無鎖的方式讀取到一致的數(shù)據(jù)了。
重新總結(jié)下MVCC算法下寫操作的執(zhí)行流程:
本文是基于HBase 0.92. 在HBase 0.94中會有些優(yōu)化策略,比如 HBASE-51 提到的。
英文原文:https://blogs.apache.org/hbase/entry/apache_hbase_internals_locking_and
參考:深入理解MVCC多版本并發(fā)控制
原文地址:hbase的行鎖與多版本并發(fā)控制(MVCC), 感謝原作者分享。
聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。TEL:177 7030 7066 E-MAIL:11247931@qq.com