HBase并行写机制(mvcc)
HBase在保证高性能的同时,为用户提供了便于理解的一致性数据模型MVCC (Multiversion Concurrency Control),即多版本并发控制技术,把数据库的行锁与行的多个版本结合起来,从而去提高数据库系统的并发性能。
要理解mvcc,首先需知道为什么需要进行并发控制,我们知道关系型数据库一般都提供了跨越所有数据的ACID特性,为了性能考虑,HBase只提供了基于单行的ACID,维基上是这样介绍ACID的:
- 原子性(Atomicity):事务作为一个整体被执行,包含在其中的对数据库的操作要么全部被执行,要么都不执行。
- 一致性(Consistency):事务应确保数据库的状态从一个一致状态转变为另一个一致状态。一致状态的含义是数据库中的数据应满足完整性约束。
- 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
- 持久性(Durability):已被提交的事务对数据库的修改应该永久保存在数据库中。
具体写入数据时是以KeyValue为数据单位的,对于上图中的数据来说,实际写入时有四个KeyValue,每个写入线程负责写入两个KeyValue,如果HBase没有相应的并发控制,则这四个KeyValue写入MemStore的顺序是无法预料的,可能会出现以下情况:
最终得到的结果是:
这样就得到了不一致的结果。显然我们需要对并发写操作进行同步。最简单的一种方案是在对某一行进行操作之前,首先显式对该行进行加锁操作,加锁成功后才进行相应操作,否则只能等待获取锁,此时,写入流程如下:
- (0) 获取行锁
- (1) 写WAL文件
- (2) 更新MemStore:将每个cell写入到memstore
- (3) 释放行锁
引入行锁的机制后,就可以避免并发情景下,对同一行数据进行操作(写入或更新)时出现数据交错的情况。
二、读写同步
可见需要对读和写也进行并发控制,不然会得到不一致的数据。最简单的方案就是读和写公用一把锁。这样虽然保证了ACID特性,但是读写操作同时抢占锁会互相影响各自的性能。
最简单的方案是和写入一样,在读取操作前后分别加入获取锁与释放锁的步骤,这样的话,性能一下子就下来了。HBase使用了一种mvcc的策略来避免读取的锁操作。
mvcc对于写操作:
- (w1) 获取行锁后,每个写操作都立即分配一个写序号
- (w2) 写操作在保存每个数据cell时都要带上写序号
- (w3) 写操作需要申明以这个写序号来完成本次写操作
对于读操作:
- (r1) 每个读操作开始都分配一个读序号,也称为读取点
- (r2) 读取点的值是所有的写操作完成序号中的最大整数(所有的写操作完成序号<=读取点)
- (r3) 对某个(row,column)的读取操作r来说,结果是满足写序号为“写序号<=读取点这个范围内”的最大整数的所有cell值的组合
使用了MVCC策略的执行过程如下:
采用MVCC后,每一次写操作都有一个写序号(即w1步),每个cell数据写memstore操作都有一个写序号(w2,例如:“Cloudera [wn=1]”)),并且每次写操作完成也是基于这个写序号(w3)。
如果在“Restaurant [wn=2]” 这步之后,“Waiter [wn=2]”这步之前,开始一个读操作。根据规则r1和r2,读的序号为1。根据规则3,读操作以序号1读到的值是:
这样就实现了以无锁的方式读取到一致的数据了。
总结:
引入MVCC后写入操作流程如下:
- (0) 获取行锁
- (0a) 获取写序号
- (1) 写WAL文件
- (2) 更新MemStore:将每个cell写入到memstore
- (2a) 以写序号完成操作
- (3) 释放行锁
参考英文:https://blogs.apache.org/hbase/tags/mvcc
HBase并行写机制(mvcc)的更多相关文章
- hadoop_并行写操作思路
这篇文章是关于,如何修改hadoop的src以实现在client端上传大文件到HDFS的时候, 为了提高上传的效率实现将文件划分成多个块,将块并行的写入到datanode的各个block中 的初步的想 ...
- MySQL多版本并发控制机制(MVCC)-源码浅析
MySQL多版本并发控制机制(MVCC)-源码浅析 前言 作为一个数据库爱好者,自己动手写过简单的SQL解析器以及存储引擎,但感觉还是不够过瘾.<<事务处理-概念与技术>>诚然 ...
- hbase的TTL机制清除opentsdb的超时数据
我们发现用opentsdb向hbase写数据之后,磁盘占用率飙升得很快,我们存的业务数据只用保存一个月的即可,了解hbase的TTL机制可以清除相关表.相关行的超时数据,之前在数据备份时,我介绍了,o ...
- Linux页快速缓存与回写机制分析
參考 <Linux内核设计与实现> ******************************************* 页快速缓存是linux内核实现的一种主要磁盘缓存,它主要用来降低 ...
- IDEA中Spark往Hbase中写数据
import org.apache.hadoop.hbase.HBaseConfiguration import org.apache.hadoop.hbase.io.ImmutableBytesWr ...
- linux块设备的IO调度算法和回写机制
************************************************************************************** 參考: <Linux ...
- HDFS写机制
HDFS写机制: 1.client客户端调用分布式文件系统对象DistributedFileSystem对象的create方法,创建一个文件输出流FSDataOutputStream对象. 2.Dis ...
- Cache写机制
Cache 写机制分为:Write-through和Write-back Write-through(直写模式) 定义:在数据更新时,同时写入缓存Cache和后端存储(主存): 优点:操作简单: 缺点 ...
- HBase的写事务,MVCC及新的写线程模型
MVCC是实现高性能数据库的关键技术,主要为了读不影响写.几乎所有数据库系统都用这技术,比如Spanner,看这里.Percolator,看这里.当然还有mysql.本文说HBase的MVCC和0.9 ...
随机推荐
- 基于Ubuntu Server 16.04 LTS版本安装和部署Django之(二):Apache安装和配置
基于Ubuntu Server 16.04 LTS版本安装和部署Django之(一):安装Python3-pip和Django 基于Ubuntu Server 16.04 LTS版本安装和部署Djan ...
- AR技术介绍(Located in Android)
一,什么是AR 在说AR技术之前,先来说说VR. 虚拟现实(VR:Virtual Reality)是采用以计算机技术为核心的技术,生成逼真的视,听,触觉等一体化的虚拟环境,用户借助必要的设备以自然的方 ...
- 在Linux中安装和配置OpenVPN Server的最简便方法!
本文介绍了如何在基于RPM和DEB的系统中安装和配置OpenVPN服务器.我们在本文中将使用一个名为openvpn-install的脚本,它使整个OpenVPN服务器的安装和配置过程实现了自动化.该脚 ...
- 自动化测试---mybatis的使用
mybatis如何实现了对数据库的操作: 1.通过Resources.getResourceAsReader()或者 Resources.getResourceAsStream()加载mybatis. ...
- 在Kotlin上怎样用Mockito2 mock final 类(KAD 23)
作者:Antonio Leiva 时间:Mar 2, 2017 原文链接:https://antonioleiva.com/mockito-2-kotlin/ 如我们在前面文章中谈到的,Kotlin最 ...
- C变量之间的转换
int main(){ //定义了三个变量分别是abc ab的值分别是5跟8 c没有赋值 把b的值给c 把a的值给b 把c的值给a 形成了一个ab值得转换: int a=5; int b=8; in ...
- 01-Mysql数据库----前戏
MySql的前戏 在学习Mysql之前,我们先来想一下一开始做的登录注册案例,当时我们把用户的信息保存到一个文件中: #用户名 |密码root|123321 alex|123123 上面文件内容的规则 ...
- font and face, 浅探Emacs字体选择机制及部分记录
缘起 最近因为仰慕org-mode,从vim迁移到了Emacs.偶然发现org-mode中调出的calendar第一行居然没有对齐,排查一下发现是字体的问题.刚好也想改改Emacs的字体,于是我就开始 ...
- LeetCode - 66. Plus One(0ms)
Given a non-empty array of digits representing a non-negative integer, plus one to the integer. The ...
- 在 C/C++ 中使用 TensorFlow 预训练好的模型—— 间接调用 Python 实现
现在的深度学习框架一般都是基于 Python 来实现,构建.训练.保存和调用模型都可以很容易地在 Python 下完成.但有时候,我们在实际应用这些模型的时候可能需要在其他编程语言下进行,本文将通过 ...