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

Reply via email to