HBASE-30021 Introduce cache access service API#8231
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new CacheAccessService abstraction as an HBase-facing API for block-cache access, with adapters for existing BlockCache implementations, a disabled-cache no-op implementation, and a topology-backed implementation that integrates with CacheTopology, CacheEngine, and CachePlacementAdmissionPolicy.
Changes:
- Adds the
CacheAccessServiceinterface plus a smallCacheAccessServiceshelper for constructing implementations. - Introduces
BlockCacheBackedCacheAccessService(compat adapter),NoOpCacheAccessService(disabled wiring), andTopologyBackedCacheAccessService(topology/policy/engine wiring). - Adds unit tests for the block-cache-backed and topology-backed service behavior.
Reviewed changes
Copilot reviewed 8 out of 8 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/cache/CacheAccessService.java | Defines the new HBase-facing cache access abstraction and compatibility default methods. |
| hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/cache/CacheAccessServices.java | Provides centralized helper construction for the new service implementations. |
| hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/cache/BlockCacheBackedCacheAccessService.java | Compatibility adapter delegating service operations to an existing BlockCache. |
| hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/cache/TopologyBackedCacheAccessService.java | Topology/policy-driven implementation that routes operations to participating engines and performs promotion. |
| hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/cache/NoOpCacheAccessService.java | Disabled-cache implementation that returns misses and reports zero sizing/capacity. |
| hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/cache/CacheRequestContext.java | Updates block type access to return Optional<BlockType>. |
| hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/cache/TestBlockCacheBackedCacheAccessService.java | Adds unit tests for the block-cache-backed adapter and no-op behavior. |
| hbase-server/src/test/java/org/apache/hadoop/hbase/io/hfile/cache/TestTopologyBackedCacheAccessService.java | Adds unit tests for topology-backed lookup, insertion, promotion, eviction, sizing, and factory construction. |
Comments suppressed due to low confidence (1)
hbase-server/src/main/java/org/apache/hadoop/hbase/io/hfile/cache/TopologyBackedCacheAccessService.java:239
- Test coverage: TopologyBackedCacheAccessService implements evictBlocksByRegionName(...), but there is no unit test confirming delegation/aggregation across participating engines. A simple test similar to the HFile eviction tests would close this gap.
@Override
public int evictBlocksByRegionName(String regionName) {
Objects.requireNonNull(regionName, "regionName must not be null");
int evicted = 0;
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| * </p> | ||
| */ | ||
| @InterfaceAudience.Private | ||
| public final class NoOpCacheAccessService implements CacheAccessService { |
There was a problem hiding this comment.
nit: is this class used for testing purpose?
There was a problem hiding this comment.
The intent is to have a null-object implementation for the disabled-cache case.
Once read/write path callers start depending on CacheAccessService, having a disabled implementation lets the runtime wire a non-null service even when block cache is disabled or unavailable. That keeps future call sites simpler because they can call the service uniformly instead of carrying repeated null checks around BlockCache.
So instead of patterns like:
if (blockCache != null) { blockCache.getBlock(...); } the wiring can select either:
CacheAccessServices.fromBlockCache(blockCache) or:
CacheAccessServices.disabled() and callers can use CacheAccessService consistently.
It is not strictly required for the first adapter PR. If you think it adds unnecessary surface area before we wire CacheAccessService into runtime code, I can remove NoOpCacheAccessService and the disabled() helper from this PR and add it later when the first disabled-cache wiring needs it.
| when(policy.selectRepresentation(key, block, context, topologyView)) | ||
| .thenReturn(RepresentationDecision.CURRENT_HBASE_DEFAULT); |
There was a problem hiding this comment.
nit: I assumed this is just a mock call and the representation isn't used at the moment, will we have another alternative TopologyBackedCacheAccessService for other implementation?
also, can you briefly explain how TopologyBackedCacheAccessService or BlockCacheBackedCacheAccessService could be configured in future ?
There was a problem hiding this comment.
Good question. No, I do not expect multiple TopologyBackedCacheAccessService implementations per cache engine.
The intended model is:
CacheAccessService
-> CacheTopology
-> CacheEngine(s)
-> CachePlacementAdmissionPolicy
So TopologyBackedCacheAccessService would be the common topology-based service. Different implementations plug in below it as different CacheEngine implementations, and different behavior plugs in as different CachePlacementAdmissionPolicy implementations.
For example, future wiring could choose either:
BlockCacheBackedCacheAccessService -> existing BlockCache
for compatibility mode, or:
TopologyBackedCacheAccessService
-> TieredExclusiveTopology
-> LruCacheEngine + BucketCacheEngine
-> Default policy
and later swap only the engine/policy, for example:
LruCacheEngine + CarrotCacheEngine Carrot-aware policy
This PR does not wire runtime configuration yet, but future configuration would likely happen in BlockCacheFactory, using settings such as service type, topology type, L1/L2 engines, and policy.
Example:
hbase.blockcache.access.service = topology
hbase.blockcache.topology = tiered-exclusive
hbase.blockcache.l1.engine = lru
hbase.blockcache.l2.engine = bucket
hbase.blockcache.policy = default0846377 to
eae86a6
Compare
|
|
||
| when(topology.getView()).thenReturn(topologyView); | ||
| when(topology.getEngines()).thenReturn(List.of(l1, l2)); | ||
| when(l1.evictBlocksRangeByHfileName("file", 10L, 100L)).thenReturn(2); |
There was a problem hiding this comment.
nit: for "file" I forgot to mention this test class also need to replace this inline plaintext with parameters.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
eae86a6 to
cafed87
Compare
Summary
This PR introduces
CacheAccessService, an HBase-facing cache access abstraction for block cache read/write path callers.The new service layer preserves the core operational shape of the existing
BlockCacheAPI while moving callers toward context-based cache access usingCacheRequestContextandCacheWriteContext.Changes
CacheAccessServiceBlockCacheBackedCacheAccessServiceas a compatibility adapter over existingBlockCacheNoOpCacheAccessServicefor disabled-cache wiringCacheAccessServiceshelper factory methodsTopologyBackedCacheAccessServiceto connect the service layer toCacheTopology,CacheEngine, andCachePlacementAdmissionPolicyNotes
This PR does not migrate
HFileReaderImpl,BlockCacheFactory, or write-path callers yet. It only introduces the service abstraction and compatibility adapter so later PRs can migrate call sites incrementally.No behavior change is intended for existing cache implementations.