[server] Manage historical lookup local cache capacity - #3864
Conversation
Allow active historical lookup generations to finish after replacement, refresh lookupers when lake configuration changes, and use table-scoped local cache directories. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 173/173 AI-Contributed/UT: 7/7
Add server and table cache capacity settings, validate table limits, reserve configured capacity atomically, and evict lookupers in best-effort LRU order. Expose cached table and eviction metrics and pass per-table limits to Paimon. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 638/638 AI-Contributed/UT: 396/396
Allow ALTER TABLE to update the effective historical lookup cache size. Propagate the latest table configuration to TabletServer replicas and recreate cached lookupers only when the effective size changes. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 74/74 AI-Contributed/UT: 106/106
Allow the global historical lookup cache capacity to be updated through cluster configuration and apply reductions lazily during admission. Keep coordinator table validation synchronized through a dedicated config updater. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 151/151 AI-Contributed/UT: 123/123
Expose request, table, in-flight, and Paimon materialization metrics for historical lookups.\n\nInvalidate cached lookupers when lake configuration changes and initialize Paimon lookup state only from active data files.\n\nCo-Authored-By: Codex <noreply@openai.com>\nAI-Model: gpt-5\nAI-Contributed/Feature: 444/444\nAI-Contributed/UT: 58/58 AI-Contributed/Feature: 444/444 AI-Contributed/UT: 58/58
There was a problem hiding this comment.
Pull request overview
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
This PR introduces configurable, capacity-bounded local caching for historical partition lake lookups on TabletServers, including dynamic resizing, cache invalidation on relevant config changes, and new operational/latency metrics.
Changes:
- Add server-wide and per-table cache size configs and validate table cache size against the server limit.
- Implement a reservation-based global cache budget with LRU eviction and lazy handling of dynamic capacity reductions.
- Add metrics for cache utilization/eviction, in-flight requests, and lake lookup latency/materialization; update related RPC request metrics routing.
Reviewed changes
Copilot reviewed 31 out of 31 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| fluss-server/src/test/java/org/apache/fluss/server/utils/HistoricalPartitionTableValidationTest.java | Updates validation tests for new cache-size constraints and new validator signature. |
| fluss-server/src/test/java/org/apache/fluss/server/replica/HistoricalLookupCacheBudgetManagerTest.java | Adds tests for reservation, replacement, and dynamic limit behavior of the cache budget manager. |
| fluss-server/src/test/java/org/apache/fluss/server/replica/HistoricalLakeLookupManagerTest.java | Expands tests for capacity eviction, lazy reconfigure, lookuper invalidation triggers, and concurrency edge cases. |
| fluss-server/src/main/java/org/apache/fluss/server/utils/TableDescriptorValidation.java | Extends table validation to enforce per-table cache size > 0 and <= server cache limit. |
| fluss-server/src/main/java/org/apache/fluss/server/tablet/TabletService.java | Uses a shared RPC utility to detect historical lookup batches (removes local helper). |
| fluss-server/src/main/java/org/apache/fluss/server/replica/ReplicaManager.java | Wires historical lookup manager reconfiguration and registers new cache/inflight/eviction metrics; records table-level historical lookup metrics. |
| fluss-server/src/main/java/org/apache/fluss/server/replica/Replica.java | Makes TableConfig snapshot updatable (volatile) and exposes update/get methods used during metadata refresh. |
| fluss-server/src/main/java/org/apache/fluss/server/replica/HistoricalLookupCacheBudgetManager.java | Adds reservation accounting for configured cache capacity with atomic reserve/replace/release operations. |
| fluss-server/src/main/java/org/apache/fluss/server/replica/HistoricalLakeLookupManager.java | Implements budget-based cache admission with LRU eviction, stable per-table cache directories, dynamic reconfigure, and metric recording hook. |
| fluss-server/src/main/java/org/apache/fluss/server/metrics/group/TabletServerMetricGroup.java | Adds a metric group to expose in-flight historical partition operation gauges. |
| fluss-server/src/main/java/org/apache/fluss/server/metrics/group/TableMetricGroup.java | Adds per-table historical lookup counters and lake lookup latency/materialization metrics. |
| fluss-server/src/main/java/org/apache/fluss/server/coordinator/MetadataManager.java | Tracks server cache limit for validation and updates validation API to include TablePath and global limit. |
| fluss-server/src/main/java/org/apache/fluss/server/coordinator/HistoricalLookupCacheConfigUpdater.java | Adds dynamic-config handler to validate/apply server cache limit changes to MetadataManager. |
| fluss-server/src/main/java/org/apache/fluss/server/coordinator/CoordinatorService.java | Updates table creation path to pass TablePath into validation. |
| fluss-server/src/main/java/org/apache/fluss/server/coordinator/CoordinatorServer.java | Registers the new dynamic-config updater for historical lookup cache limit changes. |
| fluss-server/src/main/java/org/apache/fluss/server/DynamicServerConfig.java | Marks the new server cache size option as dynamically reconfigurable. |
| fluss-rpc/src/main/java/org/apache/fluss/rpc/util/CommonRpcMessageUtils.java | Adds shared helper to detect historical lookup content in a LookupRequest. |
| fluss-rpc/src/main/java/org/apache/fluss/rpc/netty/server/RequestsMetrics.java | Splits LOOKUP request metrics into normal vs historical lookups. |
| fluss-rpc/src/main/java/org/apache/fluss/rpc/netty/server/NettyServerHandler.java | Routes LOOKUP request metrics based on whether the request contains historical lookup data. |
| fluss-lake/fluss-lake-paimon/src/test/java/org/apache/fluss/lake/paimon/lookup/PaimonLakeTableLookuperTest.java | Adds assertions/coverage for lookup file materialization metric recording. |
| fluss-lake/fluss-lake-paimon/src/main/java/org/apache/fluss/lake/paimon/lookup/PaimonLakeTableLookuper.java | Uses per-table configured cache size for Paimon lookup cache and records lookup latency/materialization via a metric recorder. |
| fluss-flink/fluss-flink-common/src/test/java/org/apache/fluss/flink/procedure/FlinkProcedureITCase.java | Extends set/get/reset cluster config procedure IT to include the new server cache size option. |
| fluss-flink/fluss-flink-common/src/main/java/org/apache/fluss/flink/procedure/SetClusterConfigsProcedure.java | Documents setting the new server cache size option via the procedure. |
| fluss-common/src/test/java/org/apache/fluss/config/TableConfigTest.java | Adds unit test for the new per-table cache size accessor. |
| fluss-common/src/test/java/org/apache/fluss/config/FlussConfigUtilsTest.java | Adds validation tests for server cache limit and expiration duration constraints. |
| fluss-common/src/main/java/org/apache/fluss/utils/FlussPaths.java | Adds per-table stable directory path construction for historical lookup caches. |
| fluss-common/src/main/java/org/apache/fluss/metrics/MetricNames.java | Adds metric name constants for inflight historical requests and lake lookup metrics. |
| fluss-common/src/main/java/org/apache/fluss/lake/lakestorage/LakeTableLookuper.java | Extends lookup context with a metric recorder callback used by implementations. |
| fluss-common/src/main/java/org/apache/fluss/config/TableConfig.java | Adds accessor for per-table historical lookup cache max disk size. |
| fluss-common/src/main/java/org/apache/fluss/config/FlussConfigUtils.java | Adds validation for the new server cache limit and cache expiration duration; marks the table option alterable. |
| fluss-common/src/main/java/org/apache/fluss/config/ConfigOptions.java | Adds new server/table config options for cache limit and idle expiration. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Make idle expiration dynamically reconfigurable and use Caffeine access order for capacity eviction. Preserve existing lookup metric labels by exposing historical request rates separately, and validate table cache sizes only when historical lookup is enabled. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 197/197 AI-Contributed/UT: 73/73
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 31 out of 31 changed files in this pull request and generated no new comments.
Suppressed comments (4)
fluss-lake/fluss-lake-paimon/src/main/java/org/apache/fluss/lake/paimon/lookup/PaimonLakeTableLookuper.java:104
lookupFileMaterializationCountis mutated and read without synchronization/atomicity, but the lookuper can be used concurrently by multiple lookup requests. This introduces a data race (and potentially tornlongreads/writes on some platforms) and can also misclassifylookupFileMaterializationin the metric recorder. Use anAtomicLong/LongAdder(and read viaget()/sum()) or otherwise synchronize accesses around increment and snapshot/compare.
private long lookupFileMaterializationCount;
fluss-lake/fluss-lake-paimon/src/main/java/org/apache/fluss/lake/paimon/lookup/PaimonLakeTableLookuper.java:456
lookupFileMaterializationCountis mutated and read without synchronization/atomicity, but the lookuper can be used concurrently by multiple lookup requests. This introduces a data race (and potentially tornlongreads/writes on some platforms) and can also misclassifylookupFileMaterializationin the metric recorder. Use anAtomicLong/LongAdder(and read viaget()/sum()) or otherwise synchronize accesses around increment and snapshot/compare.
lookupFileMaterializationCount++;
fluss-server/src/main/java/org/apache/fluss/server/utils/TableDescriptorValidation.java:251
- This validation rejects only exactly-0 values but would allow negative sizes if they can be parsed/provided (e.g., via table properties), which could later break budget reservation (
bytes > 0) or produce misleading behavior. Reject non-positive values by checking<= 0and keep the error message consistent with that constraint.
if (tableCacheSize.getBytes() == 0) {
throw new InvalidConfigException(
String.format(
"'%s' for table '%s' must be greater than 0 bytes.",
ConfigOptions
.TABLE_DATALAKE_HISTORICAL_PARTITION_LOOKUP_CACHE_MAX_DISK_SIZE
.key(),
tablePath));
}
fluss-server/src/main/java/org/apache/fluss/server/coordinator/HistoricalLookupCacheConfigUpdater.java:58
- Grammar: the message is missing 'to' (i.e., 'greater than or equal to 1 ms'). Updating it improves clarity for operators.
"Invalid configuration for %s, it must be greater than or equal 1 ms.",
Clean cache files left by a previous TabletServer process during startup while keeping directory creation lazy. Tighten historical lookup cache configuration validation and isolate temporary directories in replica tests. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 86/86 AI-Contributed/UT: 44/44
Derive global and per-table cache capacities from the total size of the first available data volume. Store lookup files under that data directory, keep the cache root out of tablet recovery, and propagate resolved byte limits to Paimon. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 256/256 AI-Contributed/UT: 286/286
Exclude the delegating TrackingIOManager inner class from the per-class JaCoCo threshold. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 3/3 AI-Contributed/UT: 0/0
|
@platinumhamburg Thanks for review. Comments has been addressed. |
Clarify cache metric naming, lookup lifecycle comments, and data-directory parameters. Document the historical lookup metrics exposed to operators. Co-Authored-By: Codex <noreply@openai.com> AI-Model: gpt-5 AI-Contributed/Feature: 81/81 AI-Contributed/UT: 0/0
Purpose
Linked issue: closes #3862
Historical partition lookups materialize local Paimon lookup files on TabletServers. This change bounds their configured disk capacity across tables and keeps cached lookupers consistent when table or lake configuration changes.
Brief change log
Tests
API and Format
Adds server and table configuration options and extends the evolving lake lookup context with a metric recorder. No RPC wire-format or storage-format changes.
Documentation
Configuration descriptions are included. Cache lifecycle and capacity semantics are covered by the historical lookup local cache management design document.
Generative AI disclosure