标签归档:mvcc

hbase的行锁与多版本并发控制(MVCC)

MVCC (Multiversion Concurrency Control),即多版本并发控制技术,它使得大部分支持行锁的事务引擎,不再单纯的使用行锁来进行数据库的并发控制,取而代之的是,把数据库的行锁与行的多个版本结合起来,只需要很小的开销,就可以实现非锁定读,从而大大提高数据库系统的并发性能。

HBase正是通过行锁+MVCC保证了高效的并发读写。

为什么需要并发控制

HBase系统本身只能保证单行的ACID特性。ACID的含义是:

  • 原子性(Atomicity)
  • 一致性(Consistency)
  • 隔离性(Isolation)
  • 持久性(Durability)

传统的关系型数据库一般都提供了跨越所有数据的ACID特性;为了性能考虑,HBase只提供了基于单行的ACID。

下面是一个hbase并发写的例子。

原始数据如下
mvcc

Apache HBase Write Path一文可以知道hbase写数据是分为两步:
1. 写Write-Ahead-Log(WAL)文件
2. 写MemStore:将每个cell[(row,column)对]的数据写到内存中的memstore

写写同步

假定对写没有采取并发控制,并考虑以下的顺序:

mvcc

最终得到的结果是:

mvcc

这样就得到了不一致的结果。显然我们需要对并发写操作进行同步。
最简单的方式是提供一个基于行的独占锁来保证对同一行写的独立性。所以写的顺序是:

  • (0) 获取行锁
  • (1) 写WAL文件
  • (2) 更新MemStore:将每个cell写入到memstore
  • (3) 释放行锁

读写同步

尽管对并发写加了锁,但是对于读呢?见下面的例子:
mvcc

如果在上面的图中红线所示的地方进行读操作,最终得到的结果是:
mvcc

可见需要对读和写也进行并发控制,不然会得到不一致的数据。最简单的方案就是读和写公用一把锁。这样虽然保证了ACID特性,但是读写操作同时抢占锁会互相影响各自的性能。

MVCC算法

HBase采用了MVCC算法来避免读操作去获取行锁。

对于写操作:

  • (w1) 获取行锁后,每个写操作都立即分配一个写序号
  • (w2) 写操作在保存每个数据cell时都要带上写序号
  • (w3)
--> 阅读全文