在什么情况下,当要检查的行与Put的行不同时,checkAndPut很有用?

时间:2018-04-21 14:43:42

标签: hbase

这是checkAndPut API

public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put)

如果我的理解是正确的,row参数可能与put的行不同。但为什么这有用呢?我认为checkAndPut就像在硬件架构中找到的CompareAndSwap(CAS)操作一样。 CAS正在比较和设置单个变量。但checkAndPut似乎支持不同行的操作。这有用吗?或者我们需要保证row实际上与put的行相同?

1 个答案:

答案 0 :(得分:4)

checkAndPut()是CAS的HBase变体,现在不推荐使用,而应使用checkAndMutate。 如javadoc中所指定的,API以原子方式检查行/系列/限定符值是否与预期值匹配。如果是的话,它会添加看跌期权。如果传递的值为null,则检查是否缺少列(即:不存在)。

让我们使用列族“cf1”获取示例表't1'并理解以下场景中的行为 -

创建要插入的行

val put = new Put(Bytes.toBytes("r1"))
put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("q1"), Bytes.toBytes("v1"))

案例1 - 表

中不存在行,列族或列

结果 - 插入新记录,res = true

var res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q1"), null, put)

案例2 - 重新插入案例1中插入的​​相同记录

结果 - 由于列已存在,因此不会发生upsert,res = false

res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q1"), null, put)

案例3 - 使用cf1:q1添加新的行键r2,而Put仍设置为rowkey = r1。

结果 - 没有upsert发生,我们得到一个例外 - “Action的getRow必须匹配传递的行”,这意味着checkAndPut中的行键设置应该与Put相同,这个API是按顺序检查行,列族和列限定符的存在以及Put

中指定的值
res = table.checkAndPut(Bytes.toBytes("r2"), Bytes.toBytes("cf1"), Bytes.toBytes("q1"), null, put)

案例4 - 将新的列族cf2添加到行键r1和列q1,而Put仍设置为rowkey = r1,列族cf1。

结果 - 没有upsert发生,我们得到一个例外 - “在't1'表中区域t1,1524474825488.a1f7efa76e78f38d64f95b63222cbfa8中不存在列族cf2 .....”

res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf2"), Bytes.toBytes("q1"), null, put)

案例5 - 我们正在检查checkAndPut()中是否存在q2而不是检查q1

结果 - 这里API将检查列q2是否存在,在我们的情况下不会,因此相同的列q1将更新,因为Put仍然设置为值v1,只有时间戳/版本的q1将改变,res = true

res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q2"), null, put)

案例6 - 在之前的所有示例中,第4个参数都设置为null,这里我们指定了实际值

结果 - checkAndPut将为q1指定的值与Put进行比较,因为它比较等于插入发生,res = true

res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q1"), Bytes.toBytes("v1"), put)

案例3和4回答了问题的最后部分。

从可用性的角度来看,我认为这个API在可能发生同一行/列的大量并发更新的情况下非常有用,为了避免任何冲突和陈旧数据,我们读取验证然后写入,如OCC - https://en.wikipedia.org/wiki/Optimistic_concurrency_control#OCC_phases

要对多行/列执行upsert,应使用checkAndMutate。 [检查 - What is the difference between Hbase checkAndPut and checkAndMutate?]

希望这有帮助。

相关问题