hbase checkandput
HBaseEveryDay_Atomic_compare_and_set
基本概念
在HBase中Insert和Update操作没有了明确的区分,那么如果我插入时不小心把以前的数据覆盖了怎么办?虽然我们可以通过timestamp将原先的数据找回,但事后弥补还是很麻烦,我想经过验证再插入库怎么办呢。 HBase中有个CAS(compare-and-set)操作用来解决这个问题(数据一致性),简单的说CAS操作可以让你在put数据之前先经过某些条件的验证,只有满足条件的put才会入库。
相关API
可以用HTable的checkAndPut(byte row, byte family, byte qualifier, byte value, Put put)方法来使用这个功能。方法的最后一个参数是你需要录入的数据的put对象,而前面的参数是与服务端check的预期值,只有服务器端对应rowkey的数据与你预期的值相同时,你的put操作才能被提交的服务端。
实战
同样写了个例子程序来验证这个功能。
package com.lurker.hbase.practise;
import java.io.IOException;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.HBaseConfiguration;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.util.Bytes;
public class CheckandPutTest {
public static void main(String[] args) throws Exception {
Configuration conf = HBaseConfiguration.create();
conf.set("hbase.zookeeper.quorum", "132.35.81.207");
conf.set("zookeeper.znode.parent", "/hbase1");
HTable table = new HTable(conf, "usertable");
Put put1 = new Put(Bytes.toBytes("row1"));
put1.add(Bytes.toBytes("myfam"), Bytes.toBytes("col1"),
Bytes.toBytes("val1"));
// check一下,如果改列有没有值,则执行put操作。
boolean res1 = table.checkAndPut(Bytes.toBytes("row1"),
Bytes.toBytes("myfam"), Bytes.toBytes("col1"), null,put1);
// 输出结果看是否执行了put
System.out.println("Put applied:" + res1);
// 再次put一条同样的记录
boolean res2 = table.checkAndPut(Bytes.toBytes("row1"),
Bytes.toBytes("myfam"), Bytes.toBytes("col1"), null,put1);
// 输出执行结果(应当返回false)
System.out.println("Put applied:" + res2);
Put put2 = new Put(Bytes.toBytes("row1"));
put2.add(Bytes.toBytes("myfam"), Bytes.toBytes("col2"),
Bytes.toBytes("val2"));
// check一下,如果之前val1录入成功,则录入新值
boolean res3 = table.checkAndPut(Bytes.toBytes("row1"),
Bytes.toBytes("myfam"), Bytes.toBytes("col1"),
Bytes.toBytes("val1"), put2);
// 输出执行结果,看是否执行了Put
System.out.println("Put applied:" + res3);
Put put3 = new Put(Bytes.toBytes("row2"));
put3.add(Bytes.toBytes("myfam"), Bytes.toBytes("col1"),
Bytes.toBytes("val3"));
// check一下,row1的值是否存在,如果存在则插入row2
// 会抛出异常(org.apache.hadoop.hbase.DoNotRetryIOException: Action's getRow must match the passed row)
boolean res4 = table.checkAndPut(Bytes.toBytes("row1"),
Bytes.toBytes("myfam"), Bytes.toBytes("col1"),
Bytes.toBytes("val1"), put3);
// 输出执行结果,看是否执行了Put
System.out.println("Put applied: " + res4);
}
}
执行结果如下:
Put applied:true
Put applied:false
Put applied:true
Exception in thread "main" org.apache.hadoop.hbase.DoNotRetryIOException:org.apache.hadoop.hbase.DoNotRetryIOException: Action's getRow must match the passed row
at org.apache.hadoop.hbase.regionserver.HRegion.checkAndMutate(HRegion.java:1544)
at org.apache.hadoop.hbase.regionserver.HRegionServer.checkAndMutate(HRegionServer.java:1740)
at org.apache.hadoop.hbase.regionserver.HRegionServer.checkAndPut(HRegionServer.java:1762)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.apache.hadoop.hbase.ipc.HBaseRPC$Server.call(HBaseRPC.java:570)
at org.apache.hadoop.hbase.ipc.HBaseServer$Handler.run(HBaseServer.java:1039)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at org.apache.hadoop.hbase.RemoteExceptionHandler.decodeRemoteException(RemoteExceptionHandler.java:96)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.translateException(HConnectionManager.java:1275)
at org.apache.hadoop.hbase.client.HConnectionManager$HConnectionImplementation.getRegionServerWithRetries(HConnectionManager.java:1021)
at org.apache.hadoop.hbase.client.HTable.checkAndPut(HTable.java:754)
at com.lurker.hbase.practise.CheckandPutTest.main(CheckandPutTest.java:54)
- 可以看到我们第一次check库里的row1:myfam:col1是否有值,结果是没有,成功插入数据row1:myfam:col1:val1。
- 第二次做了与第一次同样的操作,因为刚才已经插入。row1:myfam:col1:val1,所以这次check不通过,没能插入数据。
- 第三次new了另一个put对象,插入数据row1:myfam:col2:val2,插入之前check row1:myfam:col1:val1,同样可以成功插入数据。
- 第四次new了一个put对象,插入数据row2:myfam:col1:val3,先check row1:myfam:col1:val1,但这时抛出异常org.apache.hadoop.hbase.DoNotRetryIOException: Action's getRow must match the passed row,可以看出checkAndPut和其他dml操作一样,都属于行级原子操作,只对单行有效。
hbase checkandput的更多相关文章
- hbase开发实例
1.put/checkAndPut package com.testdata; import java.io.IOException; import org.apache.hadoop.conf.Co ...
- HBase中MVCC的实现机制及应用情况
MVCC(Multi-Version Concurrent Control),即多版本并发控制协议,广泛使用于数据库系统.本文将介绍HBase中对于MVCC的实现及应用情况. MVCC基本原理 在介绍 ...
- Hbase之原子性插入
/** * Created by similarface on 16/8/16. */ import java.io.IOException; import org.apache.hadoop.con ...
- HBase学习笔记
关键类: HBaseAdmin 管理Hbase的,主要负责DDL操作 HTable 管理表中数据,主要负责DML操作 1.为了避免热点,更多的建表方法 在Shell中: },{SPLITS=>[ ...
- HBase的JavaAPI操作
如果是DDL的操作就找HbaseAdmin. 如果是表上的增删改查的操作就找HTable. 附录代码: mport java.util.Arrays; import org.apache.hadoop ...
- [翻译]HBase 的 MVCC 和内建的原子操作
翻译一篇:HBase MVCC and built-in Atomic Operations 作者:Lars Hofhansl HBase 有一些特殊的原子操作: checkAndPut, check ...
- HBase 二级索引与Join
二级索引与索引Join是Online业务系统要求存储引擎提供的基本特性.RDBMS支持得比较好,NOSQL阵营也在摸索着符合自身特点的最佳解决方案. 这篇文章会以HBase做为对象来探讨如何基于Hba ...
- HBase篇--HBase操作Api和Java操作Hbase相关Api
一.前述. Hbase shell启动命令窗口,然后再Hbase shell中对应的api命令如下. 二.说明 Hbase shell中删除键是空格+Ctrl键. 三.代码 1.封装所有的API pa ...
- HBASE 基础命令总结
HBASE基础命令总结 一,概述 本文中介绍了hbase的基础命令,作者既有记录总结hbase基础命令的目的还有本着分享的精神,和广大读者一起进步.本文的hbase版本是:HBase 1.2.0-cd ...
随机推荐
- 使用 IDEA 创建 Maven Web 项目 (三)- 编写一个简单的 WEB 应用
编写 Servlet 类 首先,需要在 java 目录下,创建一个名为 org.smart4j.chapter1 的包.然后,在该包下创建一个 HelloServlet 的类,代码如下: packa ...
- Andy的生活
Andy是一个善良的男孩,希望优雅地生活. 现实是残酷的. 现实是,Andy像狗一样活着. Andy犯的错是,错误地认为狗一样的生活将在高考结束的那一刻结束. 大学四年时间根本没有静下心来学习,却在生 ...
- 怎么删除hao.qquu8.com绑定
运行 输入 regedit 编辑 - 查找 hao.qquu8.com 然后修改成 你想绑定的 主页 就好
- Objective-C运行时态消息传递--拼接方法名
做IOS开发的人都知道,Objective-C语言中方法的调用是运行时采取绑定的,在编译过程中只声明该方法的存在. 那么我们来简单说下在运行时,类的消息传递. 在运行时,每个方法如[self meth ...
- Node.js调用百度地图Web服务API的Geocoding接口进行点位反地理信息编码
(从我的新浪博客上搬来的,做了一些修改.) 最近迷上了node.js以及JavaScript.现在接到一个活,要解析一个出租车点位数据的地理信息.于是就想到使用Node.js调用百度地图API进行解析 ...
- Linux 中 sudo、su命令
sudo : 暂时切换到超级用户模式以执行超级用户权限,提示输入密码时该密码为当前用户的密码,而不是超级账户的密码.不过有时间限制,Ubuntu默认为一次时长15分钟.su : 切换到某某用户模式,提 ...
- ConfigurationManager 缓存刷新
服务没有停止的情况下,如果修改了配置,如果不刷新,是不会生效的,需要在每次重新读取配置前刷新配置文件,具体如下: ConfigurationManager.RefreshSection("a ...
- WPF Application
Application类作为启动的入口,在VS中,通常自动代码为我们继承了Application类,这样做的有点,我还没有理解到,但是我们先学到这个知识点. 为了能够更好的控制整个启动过程,包括得到A ...
- 【IE6的疯狂之九】li在IE中底部空行的BUG
曾经写过[IE6的疯狂之六]li在IE中底部3像素的BUG(增加浮动解决问题),原文地址:http://www.css88.com/archives/421: IE6 BUG大全: http://ww ...
- 【hihoCoder 1466】后缀自动机六·重复旋律9
http://hihocoder.com/problemset/problem/1466 建出A串和B串的两个后缀自动机 对后缀自动机的每个状态求出sg值. 求出B串的\(sum(x)\),表示B有多 ...