hbase 原子操作cas
在高并发的情况下,对数据row1 column=cf1:qual1, timestamp=1, value=val1的插入或者更新可能会导致非预期的情况,
例如:原本客户端A需要在value=val1的条件下将value更新成val_A,高并发下客户端B可能抢先将数据value=val1更新成value=val_B,这个时候客户端A如果还继续更新将不符合预期。
HBase中的CAS(compare-and-set)API用来解决这个数据一致性问题,简单的说CAS操作可以让你在put数据之前先经过某些条件的验证,只有满足条件的put才会入库。
hbase1.0版本的API:
checkAndPut(byte.md row, byte.md family, byte.md qualifier, byte.md value, Put put)
其中,put方法的最后一个参数是你需要录入的数据的put对象;
value是与服务端check的预期值,只有服务器端对应rowkey的数据与你预期的值相同时,你的put操作才能被提交的服务端。
但是这个API在2.0版本已经被弃用
新的API是checkAndMutate,一个流式API。checkAndMutate在后续的版本中还在持续改进中。
1、创建一个测试表demoTable,模拟一些测试数据
//清除并插入测试数据
private static void createDemoTable() throws IOException {
String tableNameString = "demoTable";
if (helper.existsTable(tableNameString))
helper.dropTable(tableNameString);
helper.createTable(tableNameString, 100, "cf1", "cf2");
helper.put(tableNameString,
new String[]{"row1"},
new String[]{"cf1", "cf2"},
new String[]{"qual1", "qual2", "qual3"},
new long[]{1, 2, 3},
new String[]{"val1", "val2", "val3"});
System.out.println("Before check and mutate calls...");
helper.dump("testtable", new String[]{"row1"}, null, null);
}
结果类似这样:

2、测试cas,checkAndMutate支持流式函数格式
2.1 如果列数据还不存在就插入预期数据
String tableNameString = "demoTable";
Table table = helper.getConnection().getTable(TableName.valueOf(tableNameString)); boolean res = false;
Put put = null; put = new Put(Bytes.toBytes("row1"));
put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("qual4"), 4, Bytes.toBytes("val1"));
// 如果row1 cf1 qual4 不存在值就插入put数据
res = table.checkAndMutate(Bytes.toBytes("row1"), Bytes.toBytes("cf1"))
.qualifier(Bytes.toBytes("qual4"))
.ifNotExists()
.thenPut(put);
System.out.println("1 result is (expected true) :" + res);
执行结果:1 result is (expected true) :true
执行第二遍将返回false

2.2 如果列值相等就更新数据
put = new Put(Bytes.toBytes("row1"));
put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("qual1"), 4, Bytes.toBytes("val1"));
//如果row1 cf1 qual1 val1存在就插入put,因为这个value已经存在所以可以插入,结果返回true,时间戳变为4
res = table.checkAndMutate(Bytes.toBytes("row1"), Bytes.toBytes("cf1"))
.qualifier(Bytes.toBytes("qual1")).ifEquals(Bytes.toBytes("val1"))
.thenPut(put);
System.out.println("2 result is (expected true) :" + res);
执行结果:2 result is (expected true) :true

2.3 如果列值不等于则更新
put = new Put(Bytes.toBytes("row1"));
put.addColumn(Bytes.toBytes("cf1"),Bytes.toBytes("qual1"),5,Bytes.toBytes("val2"));
////如果row1 cf1 qual1 不等于val2在就插入put
res = table.checkAndMutate(Bytes.toBytes("row1"), Bytes.toBytes("cf1"))
.qualifier(Bytes.toBytes("qual1"))
.ifMatches(CompareOperator.NOT_EQUAL,Bytes.toBytes("val2"))
.thenPut(put);
System.out.println("3 result is (expected true) :" + res);

2.4 多个条件组合判断,多个操作执行
put = new Put(Bytes.toBytes("row1"));
put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("qual5"),1,Bytes.toBytes("val1"));
put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("qual6"),1,Bytes.toBytes("val1"));
Delete delete = new Delete(Bytes.toBytes("row1"));
delete.addColumns(Bytes.toBytes("cf1"), Bytes.toBytes("qual4"));
//RowMutations这个版本还没定型
RowMutations mutations = new RowMutations(Bytes.toBytes("row1"));
mutations.add(put);
mutations.add(delete);
//row1 cf1 qual4 val1存在,row1 cf1 qual5和row1 cf1 qual6无值则插入qual5和qual6的值,并删除qual4的值
res = table.checkAndMutate(Bytes.toBytes("row1"),Bytes.toBytes("cf1")).qualifier(Bytes.toBytes("qual4"))
.ifEquals(Bytes.toBytes("val1"))
.qualifier(Bytes.toBytes("qual5")).ifNotExists()
.qualifier(Bytes.toBytes("qual6")).ifNotExists()
.thenMutate(mutations);
System.out.println("1 result is (expected true) :" + res);

3、hbase的cas操作针对是同一个行键下的数据。
hbase 原子操作cas的更多相关文章
- java并发编程系列二:原子操作/CAS
什么是原子操作 不可被中断的一个或者一系列操作 实现原子操作的方式 Java可以通过锁和循环CAS的方式实现原子操作 CAS( Compare And Swap ) 为什么要有CAS? Compar ...
- Java并发编程(十一)——原子操作CAS
一.原子操作 syn基于阻塞的锁的机制,1.被阻塞的线程优先级很高,2.拿到锁的线程一直不释放锁怎么办?3.大量的竞争,消耗cpu,同时带来死锁或者其他安全. CAS的原理 CAS(Compare A ...
- java原子操作CAS
本次内容主要讲原子操作的概念.原子操作的实现方式.CAS的使用.原理.3大问题及其解决方案,最后还讲到了JDK中经常使用到的原子操作类. 1.什么是原子操作? 所谓原子操作是指不会被线程调度机制打断的 ...
- 原子操作cas
一.概念, 基于处理器指令,把比较和交换合成一个指令完成,保证了原子性: 因为是针对一个内存地址值的,一个内存地址指向一个变量,所以只对一个共享变量能保证原子性: 二.原子操作类 锁只有synchro ...
- 并发之ATOMIC原子操作--CAS乐观锁原理(二)
1.乐观锁介绍 程序完成并发操作时,访问数据时每次不加锁,假设没有冲突去完成某项操作,如果因为冲突失败就重试,直到成功为止.就是当去做某个修改或其他操作的时候它认为不会有其他线程来做同样的操作(竞争) ...
- CAS 原子操作
理会CAS和CAS: 有时候面试官面试问你的时候,会问,谈谈你对CAS的理解,这时应该有很多人,就会比较懵,当然,我也会比较懵,当然我和很多人的懵不同,很多人可能,并不知道CAS是一个什么东西,而在我 ...
- 原子操作&普通锁&读写锁
一:原子操作CAS(compare-and-swap) 原子操作分三步:读取addr的值,和old进行比较,如果相等,则将new赋值给*addr,他能保证这三步一起执行完成,叫原子操作也就是说它不能再 ...
- CAS 无锁式同步机制
计算机系统中,CPU 和内存之间是通过总线进行通信的,当某个线程占有 CPU 执行指令的时候,会尽可能的将一些需要从内存中访问的变量缓存在自己的高速缓存区中,而修改也不会立即映射到内存. 而此时,其他 ...
- CAS无锁实现原理以及ABA问题
CAS(比较与交换,Compare and swap) 是一种有名的无锁算法.无锁编程,即不使用锁的情况下实现多线程之间的变量同步,也就是在没有线程被阻塞的情况下实现变量的同步,所以也叫非阻塞同步(N ...
随机推荐
- Altium中坐标的导出及利用坐标快速布局
器件的坐标其实在我们处理布局的时候,非常有用,例如A板布局导入B板. 1.在A板PCB中执行菜单命令“File-Assembly-Generates Pick and Place File”对器件的坐 ...
- 我在华为,软件测试人员在工作中如何运用Linux?
从事过软件测试的小伙们就会明白会使用Linux是多么重要的一件事,工作时需要用到,面试时会被问到,简历中需要写到.对于软件测试人员来说,不需要你多么熟练使用Linux所有命令,也不需要你对Linux系 ...
- Minor GC&Full GC&Major GC区别及触发条件
Minor GC:从年轻代回收内存 触发条件 1.Eden区域满 2.新创建的对象大小 > Eden所剩空间 Full GC:清理整个堆空间,包括年轻代和老年代 触发条件 1.每次晋升到 ...
- 402. Remove K Digits/738.Monotone Increasing Digits/321. Create Maximum Number
Given a non-negative integer num represented as a string, remove k digits from the number so that th ...
- java多线程相关代码
1.创建线程的三种方式 使用Thread package com.wpbxx.test; //1.自定义一个类,继承java.lang包下的Thread类 class MyThread extends ...
- Apache 性能配置优化
前言 最近在进行apache性能优化设置.在修改apache配置)文件之前需要备份原有的配置文件夹conf,这是网站架设的好习惯.以下的apache配置调优均是在red had的环境下进行的. htt ...
- JS进阶系列之闭包
刚刚总结完作用域链,我觉得很有必要马上对闭包总结一下,因为,之前也写过自己对闭包的理解,那时候只知道,闭包就是可以访问别的函数变量的函数,就是在函数里面的函数就叫做闭包,可是并没有深入探究,为什么,可 ...
- TeamWork#3,Week5,Scrum Meeting 11.6, 11.7, 11.11, 11.12
11.6:到目前为止基本已完成相关知识的学习,各方面工作都开始进行,一开始进行比较慢. 11.7:项目遇到困难,需要补充相关知识,进度慢了下来. 11.11:各方面工作进展比较顺利,没有什么大问题. ...
- 团队博客作业Week3 --- 项目选择&&需求疑问
项目选择 经过团队内所有成员一致探讨,我们团队选择完善和改进之学霸系统的第二个子模块,即:网站内容结构定义和数据处理.具体的要求如下:(摘自Xueba系统项目需求) 网站内容结构定义和数据处理(Con ...
- 20162328蔡文琛 week10 大二
20162328 2017-2018-1 <程序设计与数据结构>第十周学习总结 教材学习内容总结 理解图与有向图.无向图 理解带权图 会应用带权图 理解图的广度优先遍历和深度优先遍历 掌握 ...