Skip to content

HBASE-29668 Add row cache framework#7398

Merged
wchevreuil merged 9 commits intoapache:HBASE-29585from
EungsopYoo:HBASE-29668
Feb 23, 2026
Merged

HBASE-29668 Add row cache framework#7398
wchevreuil merged 9 commits intoapache:HBASE-29585from
EungsopYoo:HBASE-29668

Conversation

@EungsopYoo
Copy link
Contributor

No description provided.

@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.

@wchevreuil
Copy link
Contributor

I see this PR got an unrelated commit. Do you want me to rebase this branch on top of master, @EungsopYoo? You can then just force push your initial commit to your remote branch.

@EungsopYoo
Copy link
Contributor Author

@wchevreuil
I’ve rebased it myself. Do you mean like this?

@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.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@EungsopYoo
Copy link
Contributor Author

@wchevreuil
Could you continue reviewing this PR?

Copy link
Contributor

@wchevreuil wchevreuil left a comment

Choose a reason for hiding this comment

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

Thanks for submitting this PR @EungsopYoo and sorry for the long delayed response. Let's resume the discussions on this. Please refer to my comments below:

I think we should avoid putting row cache related logic on RSRpcServices, as RSRpcServices is mainly a proxy between RS/Region logic and the RPC layer.

The row cache would be a core component of RegionServer, so in that sense, it should be created and kept at HRegionServer, just like we do for BlockCache.

Since row cache would be used on region related operations, all access logic to it should be implemented at HRegion class. HRegionServer should expose its row cache to HRegion instances via the RegionServerServices (as it does with BlockCache, for instance).

package org.apache.hadoop.hbase.regionserver;

@org.apache.yetus.audience.InterfaceAudience.Private
public class RowCacheImpl implements RowCache {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: since we are not really doing anything here, can we remove this impl from this PR and focus only on the framework itself?

Copy link
Contributor Author

@EungsopYoo EungsopYoo Feb 10, 2026

Choose a reason for hiding this comment

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

@EungsopYoo
Copy link
Contributor Author

@wchevreuil
Understood. I’m currently on vacation, so I’ll review your comments next week.

@wchevreuil
Copy link
Contributor

@wchevreuil Understood. I’m currently on vacation, so I’ll review your comments next week.

No problem. Enjoy your time off!

@EungsopYoo
Copy link
Contributor Author

I have a lot of backlog, so I think I’ll be able to resume in about one to two weeks.

@Apache-HBase

This comment has been minimized.

@Apache-HBase

This comment has been minimized.

@EungsopYoo
Copy link
Contributor Author

@wchevreuil
The apache:HBASE-29585 branch was created a few months ago. So wouldn’t it be better to sync it with the latest changes before we start modifying it? What’s the best way to proceed?

Should I open a separate PR for the update, or could you take care of it directly?

@Apache-HBase
Copy link

🎊 +1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 12s Docker mode activated.
_ Prechecks _
+1 💚 dupname 0m 0s No case conflicting files found.
+0 🆗 codespell 0m 0s codespell was not available.
+0 🆗 detsecrets 0m 0s detect-secrets was not available.
+1 💚 @author 0m 0s The patch does not contain any @author tags.
+1 💚 hbaseanti 0m 0s Patch does not have any anti-patterns.
_ HBASE-29585 Compile Tests _
+0 🆗 mvndep 0m 10s Maven dependency ordering for branch
+1 💚 mvninstall 2m 40s HBASE-29585 passed
+1 💚 compile 4m 4s HBASE-29585 passed
+1 💚 checkstyle 0m 55s HBASE-29585 passed
+1 💚 spotbugs 2m 15s HBASE-29585 passed
+1 💚 spotless 0m 41s branch has no errors when running spotless:check.
_ Patch Compile Tests _
+0 🆗 mvndep 0m 11s Maven dependency ordering for patch
+1 💚 mvninstall 2m 19s the patch passed
+1 💚 compile 4m 0s the patch passed
+1 💚 javac 4m 0s the patch passed
+1 💚 blanks 0m 0s The patch has no blanks issues.
-0 ⚠️ checkstyle 0m 8s /buildtool-patch-checkstyle-hbase-server.txt The patch fails to run checkstyle in hbase-server
-0 ⚠️ rubocop 0m 4s /results-rubocop.txt The patch generated 2 new + 411 unchanged - 0 fixed = 413 total (was 411)
+1 💚 spotbugs 2m 27s the patch passed
+1 💚 hadoopcheck 8m 48s Patch does not cause any errors with Hadoop 3.3.6 3.4.1.
+1 💚 spotless 0m 34s patch has no errors when running spotless:check.
_ Other Tests _
+1 💚 asflicense 0m 30s The patch does not generate ASF License warnings.
36m 41s
Subsystem Report/Notes
Docker ClientAPI=1.53 ServerAPI=1.53 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7398/14/artifact/yetus-general-check/output/Dockerfile
GITHUB PR #7398
Optional Tests dupname asflicense javac spotbugs checkstyle codespell detsecrets compile hadoopcheck hbaseanti spotless rubocop
uname Linux bacbee5c8d09 6.14.0-1018-aws #18~24.04.1-Ubuntu SMP Mon Nov 24 19:46:27 UTC 2025 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/hbase-personality.sh
git revision HBASE-29585 / 927b2e6
Default Java Eclipse Adoptium-17.0.11+9
Max. process+thread count 85 (vs. ulimit of 30000)
modules C: hbase-common hbase-client hbase-server hbase-shell U: .
Console output https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7398/14/console
versions git=2.34.1 maven=3.9.8 spotbugs=4.7.3 rubocop=1.37.1
Powered by Apache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@Apache-HBase
Copy link

🎊 +1 overall

Vote Subsystem Runtime Logfile Comment
+0 🆗 reexec 0m 36s Docker mode activated.
-0 ⚠️ yetus 0m 5s Unprocessed flag(s): --brief-report-file --spotbugs-strict-precheck --author-ignore-list --blanks-eol-ignore-file --blanks-tabs-ignore-file --quick-hadoopcheck
_ Prechecks _
_ HBASE-29585 Compile Tests _
+0 🆗 mvndep 0m 21s Maven dependency ordering for branch
+1 💚 mvninstall 4m 27s HBASE-29585 passed
+1 💚 compile 1m 54s HBASE-29585 passed
+1 💚 javadoc 1m 12s HBASE-29585 passed
+1 💚 shadedjars 6m 7s branch has no errors when building our shaded downstream artifacts.
_ Patch Compile Tests _
+0 🆗 mvndep 0m 14s Maven dependency ordering for patch
+1 💚 mvninstall 2m 58s the patch passed
+1 💚 compile 1m 55s the patch passed
+1 💚 javac 1m 55s the patch passed
+1 💚 javadoc 1m 11s the patch passed
+1 💚 shadedjars 6m 1s patch has no errors when building our shaded downstream artifacts.
_ Other Tests _
+1 💚 unit 2m 25s hbase-common in the patch passed.
+1 💚 unit 1m 31s hbase-client in the patch passed.
+1 💚 unit 230m 24s hbase-server in the patch passed.
+1 💚 unit 7m 25s hbase-shell in the patch passed.
275m 3s
Subsystem Report/Notes
Docker ClientAPI=1.43 ServerAPI=1.43 base: https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7398/14/artifact/yetus-jdk17-hadoop3-check/output/Dockerfile
GITHUB PR #7398
Optional Tests javac javadoc unit compile shadedjars
uname Linux 51b405efab84 5.4.0-1103-aws #111~18.04.1-Ubuntu SMP Tue May 23 20:04:10 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
Build tool maven
Personality dev-support/hbase-personality.sh
git revision HBASE-29585 / 927b2e6
Default Java Eclipse Adoptium-17.0.11+9
Test Results https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7398/14/testReport/
Max. process+thread count 4435 (vs. ulimit of 30000)
modules C: hbase-common hbase-client hbase-server hbase-shell U: .
Console output https://ci-hbase.apache.org/job/HBase-PreCommit-GitHub-PR/job/PR-7398/14/console
versions git=2.34.1 maven=3.9.8
Powered by Apache Yetus 0.15.0 https://yetus.apache.org

This message was automatically generated.

@EungsopYoo EungsopYoo marked this pull request as draft February 9, 2026 06:05
@EungsopYoo
Copy link
Contributor Author

EungsopYoo commented Feb 9, 2026

Thanks for submitting this PR @EungsopYoo and sorry for the long delayed response. Let's resume the discussions on this. Please refer to my comments below:

I think we should avoid putting row cache related logic on RSRpcServices, as RSRpcServices is mainly a proxy between RS/Region logic and the RPC layer.

The row cache would be a core component of RegionServer, so in that sense, it should be created and kept at HRegionServer, just like we do for BlockCache.

Since row cache would be used on region related operations, all access logic to it should be implemented at HRegion class. HRegionServer should expose its row cache to HRegion instances via the RegionServerServices (as it does with BlockCache, for instance).

4707c74

@EungsopYoo EungsopYoo marked this pull request as ready for review February 9, 2026 08:02

RegionScannerImpl getScannerWithResults(Get get, Scan scan, List<Cell> results)
throws IOException {
return getRowCacheService().getScanner(this, get, scan, results);
Copy link
Contributor

Choose a reason for hiding this comment

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

We'll always go for the row cache? What if it's disabled?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is determined in RowCacheService.getScanner(). If the row cache is disabled, the system falls back to the traditional read path.

Comment on lines +90 to +107
RegionScannerImpl getScanner(HRegion region, Get get, Scan scan, List<Cell> results)
throws IOException {
if (!canCacheRow(get, region)) {
return getScannerInternal(region, scan, results);
}

RowCacheKey key = new RowCacheKey(region, get.getRow());

// Try get from row cache
if (tryGetFromCache(region, key, get, results)) {
// Cache is hit, and then no scanner is created
return null;
}

RegionScannerImpl scanner = getScannerInternal(region, scan, results);
populateCache(region, results, key);
return scanner;
}
Copy link
Contributor

Choose a reason for hiding this comment

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

I think RowCacheService shouldn't bother about RegionScannerImpl, but rather only the cache itself, so it should only check for the rowkey in the cache and populate the results accordingly. It's then up for the HRegion to create the scanner when no results are found in the row cache. So we could make this method void, or return List with the found results, and get rid of the scanner creation logic. These would be done in HRegion.getScannerResults.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Comment on lines +132 to +134
RegionScannerImpl scanner = region.getScanner(scan);
scanner.next(results);
return scanner;
Copy link
Contributor

Choose a reason for hiding this comment

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

Should move to HRegion (see my previous comment above).

return getScannerInternal(region, scan, results);
}

RowCacheKey key = new RowCacheKey(region, get.getRow());
Copy link
Contributor

Choose a reason for hiding this comment

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

Could we use "namespace + tableame + rowkey" as the UID of a row in the row cache? We could then only pass the TableDescriptor, rather than the HRegion as this method parameter.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

If we want to support evicting the row cache when a region is closed, similar to how block cache eviction works, we need to include the region ID as part of the UID. Otherwise, it is impossible to determine which row cache entries are associated with the region being closed.

Copy link
Contributor

Choose a reason for hiding this comment

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

That's a good point. Let's keep it as it is now (region name + row key).

Copy link
Contributor

@wchevreuil wchevreuil left a comment

Choose a reason for hiding this comment

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

LGTM, +1, just had some final nit comments.

this.isRowCacheEnabled = determineRowCacheEnabled();
}

boolean determineRowCacheEnabled() {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: call it "checkRowCacheConfig()" and make it private.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

return false;
}

boolean tryGetFromCache(HRegion region, RowCacheKey key, Get get, List<Cell> results) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: no need for the region param anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

return true;
}

void populateCache(HRegion region, List<Cell> results, RowCacheKey key) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: no need for the region param anymore.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@wchevreuil wchevreuil merged commit 7c5fa67 into apache:HBASE-29585 Feb 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants