HBase之MVCC

来源:互联网 发布:淘宝怎么同城购物平台 编辑:程序博客网 时间:2024/06/07 23:24

HBase在保证写数据一致性的同时,还保证读取的高性能。这一机制的实现就是通过MultiVersionConsistencyControl来控制的,简称MVCC

HBase为什么需要并发控制?

我们知道HBase是可以通过客户端往服务器写数据的,如果存在多个客户端,可能同时在操作某一个Region的某一行的某一列。

我们首先假定一个并发写的场景:


假设两个客户端同时往表中同一个Row的同一个Family(general)的两个列(qualifier)name和 price写数据,对于MemStore来讲这些数据是并发写入的。

写数据流程如下:

写入MemStore:讲每一个cell单元格写入MemStore缓存起来

写入HLog

上面例子中其实有4个key-value也就是4个cell,每一个请求来的时候,MemStore会写两个,但是这四个key-value写入顺序我们是无法在并发环境下保证的,就可能会出现以下情况:



本来在写完general:name= Gibson Guitar的时候,然后接着写入122.89

但是这个时候另一个线程抢在它之前执行了写入349.99

怎么办呢?

#我们可以先获取Row Lock

#更新MemStore,写入cell

#再将cell写入HLog

#释放Row Lock

 

那现在写的问题解决了,那我们读取数据的时候会不会有问题呢?



我们试想一下:当第一组数据general:name和 general:price<Gibson Guitar,122.89>已经写入完毕,已经释放锁

第二组数据开始写,正在写或准备写price349.99的时候,读请求过来,他已经把general:name=>GibsonGuitar更细了,但是还没有更新general:price=>349.99,这时候读取的数据就是



很显然这是有问题的。

怎么办呢?我们对读请求加锁,毫无疑问这肯定是没有问题的

但是不管读还是写都会涉及到锁的竞争,降低了系统的吞吐量。

所以MVCC出场了。

 

原理如下:

无论读写,每一次都被给一个Number,写操作叫做WriteNumber,读操作叫做memstoreRead。

一般情况下,为了确保数据一致性,在对数据进行写操作的时候,需要等到前面的操作完成,不然可能造成数据丢失。

所以当一个写操作来的时候,会把这个请求写入链表末尾writeQueue

,完成的操作标记为完成,并且从链表头部删除。

而最大的writeNumber会记录在memstoreRead,从而告知其他的所有的等待者,现在操作的最新sequenceId是多少,保证每一个等待着看到的数据都是最新的

 


原创粉丝点击