public boolean checkAndPut(byte[] row, byte[] family, byte[] qualifier, byte[] value, Put put)
如果我的理解是正确的,该row参数可以与put. 但是为什么这很有用呢?我认为checkAndPut就像CompareAndSwap(CAS)在硬件架构中发现的操作一样。CAS正在比较和设置单个变量。但checkAndPut似乎支持对不同行的操作。这有帮助吗?还是我们需要保证row实际上是同排的put?
checkAndPut() 是 CAS 的 HBase 变体,现在已弃用,应改用 checkAndMutate。如 javadoc 中所指定,API 自动检查行/系列/限定符值是否与预期值匹配。如果是,它会添加看跌期权。如果传递的值为空,则检查是否缺少列(即:不存在)。
让我们以列族为“cf1”的表“t1”为例,了解以下场景中的行为 -
创建要插入的行
val put = new Put(Bytes.toBytes("r1"))
put.addColumn(Bytes.toBytes("cf1"), Bytes.toBytes("q1"), Bytes.toBytes("v1"))
Run Code Online (Sandbox Code Playgroud)
案例 1 - 表中不存在行、列族或列
结果- 插入新记录, res = true
var res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q1"), null, put)
Run Code Online (Sandbox Code Playgroud)
案例 2 - 重新插入案例 1 中插入的相同记录
结果- 由于该列已存在,因此不会发生 upsert,res = false
res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q1"), null, put)
Run Code Online (Sandbox Code Playgroud)
情况 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)
Run Code Online (Sandbox Code Playgroud)
案例 4 - 向行键 r1 和列 q1 添加新的列族 cf2,而 Put 仍设置为 rowkey = r1, 列族 cf1。
结果- 没有 upsert 发生,我们得到一个异常 - “列族 cf2 不存在于区域 t1,,1524474825488.a1f7efa76e78f38d64f95b63222cbfa8. 在表 't1'.....”
res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf2"), Bytes.toBytes("q1"), null, put)
Run Code Online (Sandbox Code Playgroud)
案例 5 - 我们不是检查 q1,而是检查 checkAndPut() 中 q2 的存在
结果- 这里 API 将检查列 q2 是否存在,在我们的例子中不存在,因此相同的列 q1 将被更新,因为 Put 仍然设置为值 v1,只有 q1 的时间戳/版本会改变,res = true
res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q2"), null, put)
Run Code Online (Sandbox Code Playgroud)
案例 6 - 在之前的所有示例中,第 4 个参数设置为 null,这里我们指定了实际值
结果- checkAndPut 将 q1 指定的值与 Put 进行比较,因为它比较等于插入发生, res = true
res = table.checkAndPut(Bytes.toBytes("r1"), Bytes.toBytes("cf1"), Bytes.toBytes("q1"), Bytes.toBytes("v1"), put)
Run Code Online (Sandbox Code Playgroud)
案例 3 和案例 4 回答了您问题的最后一部分。
从可用性的角度来看,我认为这个 API 在同一行/列上可能发生大量并发更新的场景中很有用,为了避免任何冲突和陈旧数据,我们读取验证然后写入,如 OCC - https://en.wikipedia .org/wiki/Optimistic_concurrency_control#OCC_phases
要在多行/多列上执行更新插入,应使用 checkAndMutate。【检查-Hbase checkAndPut 和 checkAndMutate 有什么区别?]
希望这可以帮助。
| 归档时间: |
|
| 查看次数: |
938 次 |
| 最近记录: |