You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@hbase.apache.org by "Toshihiro Suzuki (Jira)" <ji...@apache.org> on 2020/05/04 22:57:00 UTC

[jira] [Commented] (HBASE-8458) Support for batch version of checkAndMutate()

    [ https://issues.apache.org/jira/browse/HBASE-8458?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17099405#comment-17099405 ] 

Toshihiro Suzuki commented on HBASE-8458:
-----------------------------------------

Could someone please review the following PR? Actually this feature is important for our usecase.
https://github.com/apache/hbase/pull/1648

The highlights of the changes are as follows:

- Introduced CheckAndMutate class that's used to perform CheckAndMutate operations. The following is the JavaDoc for this class:
{code}
* Used to perform CheckAndMutate operations. Currently {@link Put}, {@link Delete}
* and {@link RowMutations} are supported.
* <p>
* This has a fluent style API to instantiate it, the code is like:
* <pre>
* <code>
* // A CheckAndMutate operation where do the specified action if the column (specified by the
* // family and the qualifier) of the row equals to the specified value
* CheckAndMutate checkAndMutate = new CheckAndMutate(row)
*   .ifEquals(family, qualifier, value)
*   .action(put);
*
* // A CheckAndMutate operation where do the specified action if the column (specified by the
* // family and the qualifier) of the row doesn't exist
* CheckAndMutate checkAndMutate = new CheckAndMutate(row)
*   .ifNotExists(family, qualifier)
*   .action(put);
*
* // A CheckAndMutate operation where do the specified action if the row matches the filter
* CheckAndMutate checkAndMutate = new CheckAndMutate(row)
*   .ifMatches(filter)
*   .action(delete);
* </code>
* </pre>
{code}

- Added new checkAndMutate APIs to the Table and AsyncTable interfaces.
-- The APIs for the Table interface:
{code}
/**
  * checkAndMutate that atomically checks if a row matches the specified condition. If it does,
  * it performs the specified action.
  *
  * @param checkAndMutate The CheckAndMutate object.
  * @return boolean that represents the result for the CheckAndMutate.
  * @throws IOException if a remote or network exception occurs.
  */
 default boolean checkAndMutate(CheckAndMutate checkAndMutate) throws IOException {
   return checkAndMutate(Collections.singletonList(checkAndMutate))[0];
 }

 /**
  * Batch version of checkAndMutate.
  *
  * @param checkAndMutates The list of CheckAndMutate.
  * @return A array of boolean that represents the result for each CheckAndMutate.
  * @throws IOException if a remote or network exception occurs.
  */
 default boolean[] checkAndMutate(List<CheckAndMutate> checkAndMutates) throws IOException {
   throw new NotImplementedException("Add an implementation!");
 }
{code}
-- The APIs for the AsyncTable interface:
{code}
/**
 * checkAndMutate that atomically checks if a row matches the specified condition. If it does,
 * it performs the specified action.
 *
 * @param checkAndMutate The CheckAndMutate object.
 * @return A {@link CompletableFuture}s that represent the result for the CheckAndMutate.
 */
CompletableFuture<Boolean> checkAndMutate(CheckAndMutate checkAndMutate);

/**
 * Batch version of checkAndMutate.
 *
 * @param checkAndMutates The list of CheckAndMutate.
 * @return A list of {@link CompletableFuture}s that represent the result for each
 *   CheckAndMutate.
 */
List<CompletableFuture<Boolean>> checkAndMutate(List<CheckAndMutate> checkAndMutates);

/**
 * A simple version of batch checkAndMutate. It will fail if there are any failures.
 *
 * @param checkAndMutates The list of rows to apply.
 * @return A {@link CompletableFuture} that wrapper the result boolean list.
 */
default CompletableFuture<List<Boolean>> checkAndMutateAll(
  List<CheckAndMutate> checkAndMutates) {
  return allOf(checkAndMutate(checkAndMutates));
}
{code}

- Deprecated the old checkAndMutate APIs of the Table and AsyncTable interfaces.

- This has Protocol Buffers level changes. I moved MultiRequest#condition to RegionAction and MultiResponse#processed to RegionActionResult. This is already disscussed in the Jira:
https://issues.apache.org/jira/browse/HBASE-8458?focusedCommentId=17064155&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-17064155

Thanks.

> Support for batch version of checkAndMutate()
> ---------------------------------------------
>
>                 Key: HBASE-8458
>                 URL: https://issues.apache.org/jira/browse/HBASE-8458
>             Project: HBase
>          Issue Type: New Feature
>          Components: Client, regionserver
>            Reporter: Hari Mankude
>            Assignee: Toshihiro Suzuki
>            Priority: Major
>             Fix For: 3.0.0-alpha-1, 2.4.0
>
>
> The use case is that the user has multiple threads loading hundreds of keys into a hbase table. Occasionally there are collisions in the keys being uploaded by different threads. So for correctness, it is required to do checkAndMutate() instead of a put(). However, doing a checkAndMutate() rpc for every key update is non optimal. It would be good to have a batch version of checkAndMutate() similar to batch put(). The client can partition the keys on region boundaries.
> The jira is NOT looking for any type of cross-row locking or multi-row atomicity with checkAndMutate().



--
This message was sent by Atlassian Jira
(v8.3.4#803005)