Skip to content

[#12019] feat(core): make caffeine entity cache multi-node correct via change-log invalidation#12111

Draft
yuqi1129 wants to merge 6 commits into
apache:mainfrom
yuqi1129:issue-12019-caffeine-multinode
Draft

[#12019] feat(core): make caffeine entity cache multi-node correct via change-log invalidation#12111
yuqi1129 wants to merge 6 commits into
apache:mainfrom
yuqi1129:issue-12019-caffeine-multinode

Conversation

@yuqi1129

Copy link
Copy Markdown
Contributor

Stacked on #12042 (issue-12018-cache-type-allowlist). Please merge after #12042; until then this PR's diff also contains #12042's commits.

What changes were proposed in this pull request?

Make the default caffeine entity store cache correct in multi-node deployments by reusing the existing entity_change_log + EntityChangeLogPoller, per the #11923 design (Phase 1 of #11737).

  • Coherence marker: add EntityCache.coherence()LOCAL_PER_NODE | SHARED (cache/Coherence.java); BaseEntityCache defaults to LOCAL_PER_NODE, so caffeine is per-node. A future Redis cache reports SHARED.
  • Reader side: new EntityCacheChangeLogListener replays each ALTER/DROP row as invalidate(ident, type); a container drop cascades to cached children via the existing forward cacheIndex prefix scan. Registered as a third poller consumer (next to the catalog and jcasbin id-mapping caches) only when coherence() == LOCAL_PER_NODE — the coherence gate.
  • Writer side: add in-transaction change-log emit points for the cached types that had none — TagMetaService (update/delete), PolicyMetaService (update/delete), JobMetaService (overwrite/delete). Structural rows already exist.

Why are the changes needed?

Today only the writing node invalidates its cache, so other nodes serve stale data until TTL expiry — forcing gravitino.cache.enabled=false in HA deployments. This reuses infrastructure already present (no schema change, no new dependency), so cache.enabled=true becomes safe across nodes with the default cache.

Fix: #12019

Does this PR introduce any user-facing change?

No. Internal caching behavior only; uncached types and single-node behavior are unchanged.

How was this patch tested?

  • TestEntityCacheChangeLogListener — dispatch/cascade/sibling-preservation, per-type invalidation, malformed-row skipping, fault isolation, coherence values.
  • TestEntityChangeLogService — the new tag/policy/job ALTER & DROP rows are emitted (a plain create emits none).
  • TestEntityCacheCrossNodeInvalidation — end-to-end: a node A write emits a change-log row and node B's poller invalidates its own cache (table ALTER and schema-drop child cascade).
  • Regression: org.apache.gravitino.cache.*, TestEntityChangeLogPoller, TestTagMetaService, TestPolicyMetaService, TestJobMetaService, TestRelationalEntityStore all pass; spotlessCheck and javadoc are clean.

yuqi1129 added 6 commits July 13, 2026 19:20
…ties only

Relation lists, the reverse index and its rules are no longer maintained.
A radix prefix index still provides hierarchical cascade invalidation.
USER/GROUP/ROLE entities are excluded from caching because their
materialized form embeds relation-derived data that can no longer be
invalidated when referenced entities change.
…ect via change-log invalidation

Add an EntityCache.coherence() marker (LOCAL_PER_NODE | SHARED) and an entity
store EntityCacheChangeLogListener that replays each entity_change_log ALTER/DROP
row as invalidate(ident, type); a container drop cascades to cached children
through the existing forward prefix scan. The listener is registered as a third
consumer of the existing poller, next to the catalog and jcasbin caches, only for
a LOCAL_PER_NODE cache (the coherence gate).

Add in-transaction change-log emit points for tag, policy and job (updateTag /
deleteTag, updatePolicy / deletePolicy, insertJob overwrite / deleteJob), the
cached types that emitted no row before. Structural rows already exist.
@github-actions

Copy link
Copy Markdown

Code Coverage Report

Overall Project 67.69% +0.1% 🟢
Files changed 83.36% 🟢

Module Coverage
aliyun 1.72% 🔴
api 47.82% 🟢
authorization-common 85.96% 🟢
aws 42.04% 🟢
azure 2.47% 🔴
catalog-common 9.92% 🔴
catalog-fileset 79.77% 🟢
catalog-glue 66.91% 🟢
catalog-hive 79.42% 🟢
catalog-jdbc-common 44.81% 🟢
catalog-jdbc-doris 81.6% 🟢
catalog-jdbc-mysql 79.23% 🟢
catalog-jdbc-postgresql 82.29% 🟢
catalog-jdbc-starrocks 78.51% 🟢
catalog-kafka 77.01% 🟢
catalog-lakehouse-generic 59.18% 🟢
catalog-lakehouse-hudi 79.1% 🟢
catalog-lakehouse-iceberg 85.87% 🟢
catalog-lakehouse-paimon 84.25% 🟢
catalog-model 77.72% 🟢
cli 44.5% 🟢
client-java 78.27% 🟢
common 51.95% 🟢
core 82.59% +0.02% 🟢
filesystem-hadoop3 77.28% 🟢
flink 0.0% 🔴
flink-common 47.09% 🟢
flink-runtime 0.0% 🔴
gcp 14.12% 🔴
hadoop-auth 68.0% 🟢
hadoop-common 12.7% 🔴
hive-metastore-common 53.4% 🟢
iceberg-common 63.77% 🟢
iceberg-rest-server 74.9% 🟢
idp-basic 86.02% 🟢
integration-test-common 0.0% 🔴
jobs 66.17% 🟢
lance-common 20.67% 🔴
lance-rest-server 64.84% 🟢
lineage 53.02% 🟢
optimizer 83.17% 🟢
optimizer-api 21.95% 🔴
server 86.05% 🟢
server-common 76.12% 🟢
spark 28.57% 🔴
spark-common 46.01% 🟢
tencent 69.84% 🟢
trino-connector 40.29% 🟢
Files
Module File Coverage
core Coherence.java 100.0% 🟢
EntityCacheWeigher.java 100.0% 🟢
EntityCacheChangeLogListener.java 100.0% 🟢
TagMetaService.java 98.86% 🟢
JobMetaService.java 95.45% 🟢
PolicyMetaService.java 93.46% 🟢
BaseEntityCache.java 87.5% 🟢
RelationalEntityStore.java 71.88% 🟢
CaffeineEntityCache.java 68.87% 🟢
NoOpsCache.java 26.67% 🔴
EntityCache.java 0.0% 🔴

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.

[Subtask] Make the caffeine entity cache multi-node correct via cross-node change-log invalidation

1 participant