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/08/11 19:09:02 UTC

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

     [ https://issues.apache.org/jira/browse/HBASE-8458?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Toshihiro Suzuki updated HBASE-8458:
------------------------------------
    Release Note: 
HBASE-8458 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>
 * Use the builder class to instantiate a CheckAndMutate object.
 * This builder class is fluent style APIs, the code are 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 = CheckAndMutate.newBuilder(row)
 *   .ifEquals(family, qualifier, value)
 *   .build(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 = CheckAndMutate.newBuilder(row)
 *   .ifNotExists(family, qualifier)
 *   .build(put);
 *
 * // A CheckAndMutate operation where do the specified action if the row matches the filter
 * CheckAndMutate checkAndMutate = CheckAndMutate.newBuilder(row)
 *   .ifMatches(filter)
 *   .build(delete);
 * </code>
 * </pre>
{code}

And it added new checkAndMutate APIs to the Table and AsyncTable interfaces, and deprecated the old checkAndMutate APIs.
The new 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 new 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}

This has Protocol Buffers level changes. Old clients without this patch will work against new servers with this patch. However, new clients will break against old servers without this patch for checkAndMutate with RM and mutateRow. So, for rolling upgrade, we will need to upgrade servers first, and then roll out the new clients.


  was:
HBASE-8458 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}

And it added new checkAndMutate APIs to the Table and AsyncTable interfaces, and deprecated the old checkAndMutate APIs.
The new 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 new 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}

This has Protocol Buffers level changes. Old clients without this patch will work against new servers with this patch. However, new clients will break against old servers without this patch for checkAndMutate with RM and mutateRow. So, for rolling upgrade, we will need to upgrade servers first, and then roll out the new clients.



> 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)