Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

HBASE-24996 Support CheckAndMutate in Region.batchMutate() #2498

Closed
wants to merge 1 commit into from

Conversation

brfrn169
Copy link
Member

@brfrn169 brfrn169 commented Oct 4, 2020

  • After this change, Region.batchMutate() will support CheckAndMutate operations and we will be able to perform Put/Delete/Increment/Append/CheckAndMutate operations atomically.
  • When CheckAndMutate operations are executed, the following coprocessor methods of RegionObserver will be no longer called. However, postIncrementBeforeWAL/postAppendBeforeWAL will be still called.
    • prePut
    • postPut
    • preDelete
    • postDelete
    • preIncrement
    • preIncrementAfterRowLock
    • postIncrement
    • preAppend
    • preAppendAfterRowLock
    • postAppend
  • Also, the following coprocessor methods of RegionObserver will be called when CheckAndMutate operations are performed:
    • preBatchMutate()
    • postBatchMutate()
    • postBatchMutateIndispensably()

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

Copy link
Contributor

@saintstack saintstack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hard to review (complicated) but it looks great. In each place I dug in it seemed good. Few qs.

@@ -139,7 +139,8 @@ public Configuration getConfiguration() {
*/
@Override
protected KeyValueScanner createScanner(Scan scan, ScanInfo scanInfo,
NavigableSet<byte[]> targetCols, long readPt) throws IOException {
NavigableSet<byte[]> targetCols, long readPt,List<KeyValueScanner> additionalScanners)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Has to be a KVScanner? Can't be a CellScanner? (Took a look... seems like the latter is something else...)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It Has to be a KVScanner. I will explain the reason in the following comment:
#2498 (comment)

@@ -3069,27 +3073,33 @@ private RegionScannerImpl getScanner(Scan scan, List<KeyValueScanner> additional
checkFamily(family);
}
}
return instantiateRegionScanner(scan, additionalScanners, nonceGroup, nonce);
return instantiateRegionScanner(scan, additionalScanners, additionalScannersForStores,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whats the diff between the two additional Scanner?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me explain this.

There was one requirement where the additional cells of a mutation need to be visible for followed mutations. For example, when we have a Put operation and a CheckAndMutate operation in a single mutation batch, the additional cells of the Put operation should be visible for the followed CheckAndMutate operation.

The following code keeps additional cells of mutations:
https://github.com/brfrn169/hbase/blob/HBASE-24996/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java#L3833-L3835

To achieve this, I first tried to use the existing additionalScanners of RegionScannerImpl:
https://github.com/brfrn169/hbase/blob/HBASE-24996/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java#L3061

However, I found it's much easier to add a new additionalScanners to StoreScanner and use it than to use the existing additionalScanners of RegionScannerImpl.

So, I decided to add additionalScanners to StoreScanner and was able to make the additional cell visible for the followed mutations.
https://github.com/brfrn169/hbase/blob/HBASE-24996/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/StoreScanner.java#L251-L253

By the way, the test code of this is as as follows:
https://github.com/brfrn169/hbase/blob/HBASE-24996/hbase-server/src/test/java/org/apache/hadoop/hbase/regionserver/TestHRegion.java#L7101-L7174

Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do process increment and append in the past? What if we have a put and then an increment on the same row before this PR?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't handle this situation in the past. So if we have a put and then an increment on the same row, it acts like the put is ignored.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So let's not mix things up in a single PR? Open another PR to discuss this first? I do not think this is the only way to do this. For HBase, it is not like the traditional RDBMS, where we issue a start transaction command to the server first, and then apply several SQL statements, and last issue a commit transaction command. Here we know all the action before actually executing them, so if there are multiple actions operation on the same row, we could merge them first. For example, if there are two increment on the same row, we could just add the values to merge them into one increment. And if there is a CAS and then a Put, we could just remove the CAS as the internal value is not visible right? And if there is a Put and then a CAS, it is easy to know whether the CAS can be performed, and can even convert it to a Put.

Or maybe even make a simple statement that, please do not operate on the same row in a batch, we will not consider the previous operation in the same batch when performing the operations in the batch.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here we know all the action before actually executing them, so if there are multiple actions operation on the same row, we could merge them first.

I thought the same thing first, but it is not such a simple thing because we can specify timestamp to mutations. So we can't always know the latest column value without merging the existing values (in memstore and hfiles). For example, if we have one existing Put with timestamp 2, and if we perform Put with timestamp 1 and CAS for the same column in a batch, we can't know the latest column value without merging the existing values. That's why I needed to add the new additional Scanner. However, I know it will make things complicated.

Or maybe even make a simple statement that, please do not operate on the same row in a batch, we will not consider the previous operation in the same batch when performing the operations in the batch.

Sounds this is a good idea. I will modify the patch this way. Thank you for discussing this.

// Sort the cells so that they match the order that they appear in the Get results.
// Otherwise, we won't be able to find the existing values if the cells are not specified
// in order by the client since cells are in an array list.
// TODO: I don't get why we are sorting. St.Ack 20150107
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anything on this sort issue?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need the sorting actually, otherwise it will return a wrong result to the client. I keep this sorting here: https://github.com/brfrn169/hbase/blob/HBASE-24996/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/HRegion.java#L4072-L4075

* <p>
* Note this supports only Put, Delete, Increment and Append mutations and will ignore other
* types passed.
*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice. One way in only.

@brfrn169
Copy link
Member Author

@saintstack Thank you very much for reviewing this! I'm working on fixing the test failure in the last QA. Once it's done, will work on your review. Thanks.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@brfrn169
Copy link
Member Author

I don't think the test failure in the last QA is related to this change. I will re-trigger the QA.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@brfrn169
Copy link
Member Author

@saintstack @Apache9 @joshelser Could you please review this when you have time? I wrote down the summary of this change in the following comment:
#2498 (comment)

Thank you in advance.

@brfrn169
Copy link
Member Author

@saintstack @Apache9 @joshelser Could you please review this? I want to include this to hbase-2.4 if possible. Thanks.

@Apache9
Copy link
Contributor

Apache9 commented Oct 20, 2020

Sorry for the late reply...

This is a big change, need to find a suitable large block of time to review it...

Will do this soon this week.

@brfrn169
Copy link
Member Author

Thank you very much! @Apache9

Copy link
Contributor

@Apache9 Apache9 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm a bit confused that why we need to touch so many existing code? I suppose what we need to do is to just add a new instanceof branch in the batchMutate method?

}

@Override
public String getId() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we have so many unsupported methods, is it still a good idea to make CheckAndMutate extend Mutation?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to keep CheckAndMutate extend Mutation because I want to treat CheckAndMutate as same as other mutations (Put/Delete/Increment/Append) to perform CheckAndMutate and other mutations atomically.

For example, after this change, we will be able to perform Put and Increment and CheckAndMutate atomically in a single row (or region).

However, I'm thinking that we need to rearrange/redesign the mutation structure in the future.

@@ -3069,27 +3073,33 @@ private RegionScannerImpl getScanner(Scan scan, List<KeyValueScanner> additional
checkFamily(family);
}
}
return instantiateRegionScanner(scan, additionalScanners, nonceGroup, nonce);
return instantiateRegionScanner(scan, additionalScanners, additionalScannersForStores,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do process increment and append in the past? What if we have a put and then an increment on the same row before this PR?

Copy link
Member Author

@brfrn169 brfrn169 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Apache9 Thank you for taking a look at this!

I'm a bit confused that why we need to touch so many existing code? I suppose what we need to do is to just add a new instanceof branch in the batchMutate method?

Sorry for the confusion. I did multiple things in this commit actually. One of the biggest changes is things related to the additional Scanner. As I mentioned in the other comment, there was the following requirement so I needed to add the new additional Scanner:

There was one requirement where the additional cells of a mutation need to be visible for followed mutations. For example, when we have a Put operation and a CheckAndMutate operation in a single mutation batch, the additional cells of the Put operation should be visible for the followed CheckAndMutate operation.

Another big change is the following as mentioned in #2498 (comment) :

When CheckAndMutate operations are executed, the following coprocessor methods of RegionObserver will be no longer called. However, postIncrementBeforeWAL/postAppendBeforeWAL will be still called.
prePut
postPut
preDelete
postDelete
preIncrement
preIncrementAfterRowLock
postIncrement
preAppend
preAppendAfterRowLock
postAppend

This is a side-effect of this change and I also needed to change AccessController and VisibilityController due to it.

Thanks.

}

@Override
public String getId() {
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to keep CheckAndMutate extend Mutation because I want to treat CheckAndMutate as same as other mutations (Put/Delete/Increment/Append) to perform CheckAndMutate and other mutations atomically.

For example, after this change, we will be able to perform Put and Increment and CheckAndMutate atomically in a single row (or region).

However, I'm thinking that we need to rearrange/redesign the mutation structure in the future.

@@ -3069,27 +3073,33 @@ private RegionScannerImpl getScanner(Scan scan, List<KeyValueScanner> additional
checkFamily(family);
}
}
return instantiateRegionScanner(scan, additionalScanners, nonceGroup, nonce);
return instantiateRegionScanner(scan, additionalScanners, additionalScannersForStores,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We didn't handle this situation in the past. So if we have a put and then an increment on the same row, it acts like the put is ignored.

@Apache-HBase
Copy link

🎊 +1 overall

Vote Subsystem Runtime Comment
+0 🆗 reexec 0m 31s Docker mode activated.
_ Prechecks _
+1 💚 dupname 0m 0s No case conflicting files found.
+1 💚 hbaseanti 0m 0s Patch does not have any anti-patterns.
+1 💚 @author 0m 0s The patch does not contain any @author tags.
_ master Compile Tests _
+0 🆗 mvndep 0m 28s Maven dependency ordering for branch
+1 💚 mvninstall 3m 56s master passed
+1 💚 checkstyle 2m 10s master passed
+1 💚 spotbugs 4m 16s master passed
_ Patch Compile Tests _
+0 🆗 mvndep 0m 14s Maven dependency ordering for patch
+1 💚 mvninstall 3m 39s the patch passed
+1 💚 checkstyle 0m 22s The patch passed checkstyle in hbase-common
+1 💚 checkstyle 0m 27s The patch passed checkstyle in hbase-client
+1 💚 checkstyle 1m 11s hbase-server: The patch generated 0 new + 356 unchanged - 1 fixed = 356 total (was 357)
+1 💚 whitespace 0m 0s The patch has no whitespace issues.
+1 💚 hadoopcheck 17m 16s Patch does not cause any errors with Hadoop 3.1.2 3.2.1 3.3.0.
+1 💚 spotbugs 4m 4s the patch passed
_ Other Tests _
+1 💚 asflicense 0m 37s The patch does not generate ASF License warnings.
47m 14s
Subsystem Report/Notes
Docker Client=19.03.13 Server=19.03.13 base: https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/artifact/yetus-general-check/output/Dockerfile
GITHUB PR #2498
Optional Tests dupname asflicense spotbugs hadoopcheck hbaseanti checkstyle
uname Linux 6ebfec7ae2d9 4.15.0-58-generic #64-Ubuntu SMP Tue Aug 6 11:12:41 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/hbase-personality.sh
git revision master / 17f9ade
Max. process+thread count 94 (vs. ulimit of 30000)
modules C: hbase-common hbase-client hbase-server U: .
Console output https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/console
versions git=2.17.1 maven=(cecedd343002696d0abb50b32b541b8a6ba2883f) spotbugs=3.1.12
Powered by Apache Yetus 0.11.1 https://yetus.apache.org

This message was automatically generated.

@Apache-HBase
Copy link

🎊 +1 overall

Vote Subsystem Runtime Comment
+0 🆗 reexec 0m 27s Docker mode activated.
-0 ⚠️ yetus 0m 4s Unprocessed flag(s): --brief-report-file --spotbugs-strict-precheck --whitespace-eol-ignore-list --whitespace-tabs-ignore-list --quick-hadoopcheck
_ Prechecks _
_ master Compile Tests _
+0 🆗 mvndep 0m 21s Maven dependency ordering for branch
+1 💚 mvninstall 3m 39s master passed
+1 💚 compile 1m 42s master passed
+1 💚 shadedjars 6m 33s branch has no errors when building our shaded downstream artifacts.
+1 💚 javadoc 1m 22s master passed
_ Patch Compile Tests _
+0 🆗 mvndep 0m 16s Maven dependency ordering for patch
+1 💚 mvninstall 3m 27s the patch passed
+1 💚 compile 1m 44s the patch passed
+1 💚 javac 1m 44s the patch passed
+1 💚 shadedjars 6m 30s patch has no errors when building our shaded downstream artifacts.
+1 💚 javadoc 1m 20s the patch passed
_ Other Tests _
+1 💚 unit 1m 30s hbase-common in the patch passed.
+1 💚 unit 1m 4s hbase-client in the patch passed.
+1 💚 unit 139m 12s hbase-server in the patch passed.
171m 58s
Subsystem Report/Notes
Docker Client=19.03.13 Server=19.03.13 base: https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/artifact/yetus-jdk8-hadoop3-check/output/Dockerfile
GITHUB PR #2498
Optional Tests javac javadoc unit shadedjars compile
uname Linux d31898f79a92 4.15.0-58-generic #64-Ubuntu SMP Tue Aug 6 11:12:41 UTC 2019 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/hbase-personality.sh
git revision master / 17f9ade
Default Java 1.8.0_232
Test Results https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/testReport/
Max. process+thread count 4432 (vs. ulimit of 30000)
modules C: hbase-common hbase-client hbase-server U: .
Console output https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/console
versions git=2.17.1 maven=(cecedd343002696d0abb50b32b541b8a6ba2883f)
Powered by Apache Yetus 0.11.1 https://yetus.apache.org

This message was automatically generated.

@Apache-HBase
Copy link

💔 -1 overall

Vote Subsystem Runtime Comment
+0 🆗 reexec 1m 37s Docker mode activated.
-0 ⚠️ yetus 0m 3s Unprocessed flag(s): --brief-report-file --spotbugs-strict-precheck --whitespace-eol-ignore-list --whitespace-tabs-ignore-list --quick-hadoopcheck
_ Prechecks _
_ master Compile Tests _
+0 🆗 mvndep 0m 30s Maven dependency ordering for branch
+1 💚 mvninstall 5m 19s master passed
+1 💚 compile 2m 20s master passed
+1 💚 shadedjars 8m 19s branch has no errors when building our shaded downstream artifacts.
+1 💚 javadoc 1m 34s master passed
_ Patch Compile Tests _
+0 🆗 mvndep 0m 16s Maven dependency ordering for patch
+1 💚 mvninstall 4m 6s the patch passed
+1 💚 compile 1m 59s the patch passed
+1 💚 javac 1m 59s the patch passed
+1 💚 shadedjars 6m 37s patch has no errors when building our shaded downstream artifacts.
+1 💚 javadoc 1m 31s the patch passed
_ Other Tests _
+1 💚 unit 1m 32s hbase-common in the patch passed.
+1 💚 unit 1m 4s hbase-client in the patch passed.
-1 ❌ unit 138m 27s hbase-server in the patch failed.
178m 8s
Subsystem Report/Notes
Docker Client=19.03.13 Server=19.03.13 base: https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/artifact/yetus-jdk11-hadoop3-check/output/Dockerfile
GITHUB PR #2498
Optional Tests javac javadoc unit shadedjars compile
uname Linux 1a2f8adde280 4.15.0-112-generic #113-Ubuntu SMP Thu Jul 9 23:41:39 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/hbase-personality.sh
git revision master / 17f9ade
Default Java 2020-01-14
unit https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/artifact/yetus-jdk11-hadoop3-check/output/patch-unit-hbase-server.txt
Test Results https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/testReport/
Max. process+thread count 4078 (vs. ulimit of 30000)
modules C: hbase-common hbase-client hbase-server U: .
Console output https://ci-hadoop.apache.org/job/HBase/job/HBase-PreCommit-GitHub-PR/job/PR-2498/8/console
versions git=2.17.1 maven=(cecedd343002696d0abb50b32b541b8a6ba2883f)
Powered by Apache Yetus 0.11.1 https://yetus.apache.org

This message was automatically generated.

@brfrn169
Copy link
Member Author

brfrn169 commented Oct 29, 2020

The failed UT is not related to the patch. It was successful locally.

I removed the new additional Scanner things from the patch and added the following document to the Region.batchMutate method:

   * Please do not operate on a same column of a single row in a batch, we will not consider the
   * previous operation in the same batch when performing the operations in the batch.

Can you please review this? @Apache9

@brfrn169
Copy link
Member Author

brfrn169 commented Nov 4, 2020

It looks like this change will make things too complicated and it has big side effects and incompatible changes. So I will give it up. Closing it.

@brfrn169 brfrn169 closed this Nov 4, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants